/*	
 *	clipvgm.h
 *
 *	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
 *	- 作成開始。
 *	* Wed Nov 18 21:37:53 JST 2015 Naoyuki Sawa
 *	- 'extern "C" {'〜'}'で囲みました。.cppを含むWin32プロジェクトからもインクルード出来るようにするためです。
 */
#ifndef __CLIP_VGM_H__
#define __CLIP_VGM_H__

#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus

/****************************************************************************
 *	VGMファイル仕様
 ****************************************************************************/

/*
 *	VGMファイルヘッダ
 */
typedef struct _VGMHEADER {
	char signature[4];	/* +0x00,0x04: "Vgm "固定 */
	int eof_offset;		/* +0x04,0x04: (ファイルサイズ-0x04)と書いてあるが、実際にはサイズぴったり? ※仕様不明 */
	int version;		/* +0x08,0x04: 0x00000101固定 */
	int psg_clock;		/* +0x0c,0x04: PSG音源入力クロック(例:3579545[Hz])。PSG音源無しの場合は0 */
	int fm_clock;		/* +0x10,0x04: FM 音源入力クロック(例:3579545[Hz])。FM 音源無しの場合は0 */
	int gd3_offset;		/* +0x14,0x04: GD3タグ位置への相対オフセット(==絶対位置-0x14)。GD3タグ無しの場合は0 */
	int total_samples;	/* +0x18,0x04: 全体の出力サンプル数 */
	int loop_offset;	/* +0x1c,0x04: ループ開始位置への相対オフセット(==絶対位置-0x1c)。ループ無しの場合は0 */
	int loop_samples;	/* +0x20,0x04: ループ部分の出力サンプル数 */
	int rate_recording;	/* +0x24,0x04: 録音環境(50:PALorSECAM/60:NTSC/0:不明?)。(通常の再生には不要な情報です) */
	int padding[6];		/* +0x28,0x18: (予約) */
} VGMHEADER;			/* =0x40     : この後にシーケンスコマンドが続きます。 */

/*
 *	シーケンスコマンド
 */
/***** 音源チップ制御コマンド *****/
#define VGM_GGPSG_dd		0x4f	/* Game Gear PSG stereo, write dd to port 0x06 */
#define VGM_SN76489_dd		0x50	/* PSG (SN76496) write value dd */
#define VGM_YM2413_aa_dd	0x51	/* YM2413, write value dd to register aa */
#define VGM_YM2612P0_aa_dd	0x52	/* YM2612 port 0, write value dd to register aa */
#define VGM_YM2612P1_aa_dd	0x53	/* YM2612 port 1, write value dd to register aa */
#define VGM_YM2151_aa_dd	0x54	/* YM2151, write value dd to register aa */
//#define VGM_RESERVED_aa_dd	0x5?	/* reserved for other chips/future, ignore */
/***** シーケンサ制御コマンド (WAIT単位は1/44100[秒]です) *****/
#define VGM_WAIT_nn_nn		0x61	/* wait n samples, n can range from 0 to 65535 (approx 1.49 seconds) */
					/* Longer pauses than this are represented by multiple wait commands. */
#define VGM_WAIT_735		0x62	/* wait 735 samples (60th of a second), a shortcut for 0x61 0xdf 0x02 */
#define VGM_WAIT_882		0x63	/* wait 882 samples (50th of a second), a shortcut for 0x61 0x72 0x03 */
#define VGM_END			0x66	/* end of sound data */

/****************************************************************************
 *	VGMドライバ
 ****************************************************************************/

#define VGMBUFLEN 320 /* =16000/50 … 1[tick](=1/50[sec])当たりのサンプル数 */

#define VGMSAMPLERATE	44100	/* VGMファイルのサンプルレート(44.1KHz固定) */

/*
 *	VGMドライバ
 */
typedef struct _VGMDRIVER {
	gzFile file;		/* gzioストリーム (VGZ形式の場合) */
				/* 非圧縮VGM形式の場合はgzio関数群が透過してくれるので、区別不要です。 */
	VGMHEADER header;	/* VGMファイルヘッダ */
	//
	SN76489 sn76489;	/* SN76489 Chip */
	//
	int progress;		/* 進行カウンタ */
	int stop;		/* 0:演奏中/1:演奏終了 */
} VGMDRIVER;

/*
 *	VGMドライバ内部関数
 */
int vgm_init(VGMDRIVER* vgm, const char* fname);
void vgm_free(VGMDRIVER* vgm);
int vgm_mix(VGMDRIVER* vgm, short wbuff[/*VGMBUFLEN*/]);
int vgm_stream_callback(short* wbuff, int param);

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

/* VGM/VGZファイルの再生を開始します。
 * [in]
 *	fname		VGM/VGZファイル名。
 * [out]
 *	戻り値		再生開始に成功したら、 0を返します。
 *			再生開始できなければ、-1を返します。
 * [note]
 *	* この関数は内部でstream_play()を呼び出しています。
 *	* stream_play()を呼ぶと、サウンド割り込みベクタがフックされます。
 *	  プログラム終了前に必ずvgm_stop()を呼んで、ベクタを復元してください。
 */
int vgm_play(const char* fname);

/* VGMファイルの再生を停止します。
 * [note]
 *	* 再生中でなければ、この関数は何もしません。
 */
void vgm_stop();

#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus

#endif /*__CLIP_VGM_H__*/
