#include <clip.h>

/***************************************************************************/
/* DO change */

//#define FILENAME "c:/home/share/2ND_PM.S3M"
//#define FILENAME "c:/home/share/A_AP.S3M"
//#define FILENAME "c:/home/share/FUNPLAST.S3M"
//#define FILENAME "c:/home/share/party92.s3m"
//#define FILENAME "c:/home/share/intro93.s3m"
//#define FILENAME "c:/home/share/SPLATFST.S3M"
//#define FILENAME "c:/home/share/SKYRIDER.S3M"
#define FILENAME "c:/home/share/hopmap.S3M"
//#define FILENAME "c:/home/share/Module1.s3m"

#define BUFLEN		S3MBUFLEN
#define INIT()		s3m_init(&driver, g_data, 0)
#define stream_callback	s3m_stream_callback

/***************************************************************************/
/* do NOT change */

#define NWHDR		8	/* これ以上増やすとwaveOutWriteでエラーになるみたい */
HWAVEOUT g_wout;
WAVEFORMATEX g_fmt;
WAVEHDR g_whdr[NWHDR];
short g_wbuff[NWHDR][BUFLEN];
unsigned char g_data[16 * 1024 * 1024];
S3MDRIVER driver;

/***************************************************************************/

void CALLBACK
waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
	static int I;
	int retval;

	if(uMsg != WOM_DONE) return;

	retval = stream_callback(g_wbuff[I], (int)&driver);
	if(retval != 0) {
		memset(g_wbuff[I], 0, sizeof(short) * S3MBUFLEN);
	}
	retval = waveOutWrite(hwo, &g_whdr[I], sizeof g_whdr[I]);
	assert(retval == 0);

	I = (I + 1) % NWHDR;
}

int
main(int argc, char* argv[])
{
	int retval;
	int i;
	const char* fname;
	FILE* fp;

	if(argc >= 1 + 1) {
		fname = argv[1];
	} else {
		fname = FILENAME;
	}

	/* init driver */
	fp = fopen(fname, "rb");
	if(!fp) {
		fprintf(stderr, "fopen(%s) failed\n", fname);
		exit(1);
	}
	fread(g_data, 1, sizeof g_data, fp);
	fclose(fp);
	retval = INIT();
	if(retval != 0) {
		fprintf(stderr, "init failed (%d)\n", retval);
		exit(1);
	}

	/* init stream */
	memset(&g_fmt, 0, sizeof g_fmt);
	g_fmt.wFormatTag = WAVE_FORMAT_PCM;
	g_fmt.nChannels = 1;
	g_fmt.nSamplesPerSec = 16000;
	g_fmt.nAvgBytesPerSec = 16000 * 2;
	g_fmt.nBlockAlign = 2;
	g_fmt.wBitsPerSample = 16;
	retval = waveOutOpen(&g_wout, WAVE_MAPPER, &g_fmt, (DWORD)waveOutProc, 0, CALLBACK_FUNCTION);
	assert(retval == 0);
	for(i = 0; i < NWHDR; i++) {
		memset(&g_whdr[i], 0, sizeof g_whdr[i]);
		g_whdr[i].lpData = (char*)g_wbuff[i];
		g_whdr[i].dwBufferLength = sizeof g_wbuff[i];
		retval = waveOutPrepareHeader(g_wout, &g_whdr[i], sizeof g_whdr[i]);
		assert(retval == 0);
	}

	/* start playing */
	for(i = 0; i < NWHDR; i++) {
		retval = waveOutWrite(g_wout, &g_whdr[i], sizeof g_whdr[i]);
		assert(retval == 0);
	}
	Sleep(INFINITE);

	return 0;
}

