/*

  in_cube Gamecube Stream Player for Winamp
  by hcs

  includes work by Destop and bero

*/

// RSF (Retro's dirty little addition to Metroid Prime)

#include "../xmms_cube/windows.h"
#include "wamain.h"
#include "cube.h"

// inputfile == NULL means file is already opened, just reload
// return 1 if valid RSF not detected, 0 on success
int InitRSFFILE(char * inputfile, CUBEFILE * rsf) {
	int l;
	char buf[1];
	if (inputfile) {
		rsf->ch[0].infile=rsf->ch[1].infile=INVALID_HANDLE_VALUE;

		if (strcmpi(inputfile+strlen(inputfile)-4,".rsf")) return 1;

#ifndef __amigaos4__
		rsf->ch[0].infile = rsf->ch[1].infile = CreateFile(inputfile,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
			OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
#else
		rsf->ch[0].infile = rsf->ch[1].infile = IDOS->Open(inputfile, MODE_OLDFILE);
#endif

		if (rsf->ch[0].infile == INVALID_HANDLE_VALUE) // error opening file
			return 1;

	} else if (rsf->ch[0].type!=type_rsf) return 1; // we don't have the file name to recheck

	rsf->ch[0].type=type_rsf;
	rsf->ch[1].type=type_rsf;

	
	rsf->NCH = 2;
	rsf->ch[0].sample_rate = 32000;
#ifndef __amigaos4__
	rsf->ch[0].num_samples = GetFileSize(rsf->ch[0].infile,NULL);
#else
	rsf->ch[0].num_samples = IDOS->GetFileSize(rsf->ch[0].infile);
#endif

#ifndef __amigaos4__
	SetFilePointer(rsf->ch[0].infile,GetFileSize(rsf->ch[0].infile,NULL)/2,0,FILE_BEGIN);
	ReadFile(rsf->ch[0].infile, buf, 1, &l, NULL);
#else
	IDOS->ChangeFilePosition(rsf->ch[0].infile, IDOS->GetFileSize(rsf->ch[0].infile)/2, OFFSET_BEGINNING);
	IDOS->FRead(rsf->ch[0].infile, buf, 1, 1);
#endif
	
	//if (buf[0]&0x0f && buf[0]&0xf0) {
	//	rsf->ch[0].loop_flag=rsf->ch[1].loop_flag=1;
	//	rsf->ch[0].sa=rsf->ch[1].sa=0;
	//	rsf->ch[0].ea=rsf->ch[1].ea=GetFileSize(rsf->ch[0].infile,NULL);
	//} else {
		rsf->ch[0].loop_flag=rsf->ch[1].loop_flag=0;
	//}

	rsf->ch[0].chanstart=0;
#ifndef __amigaos4__
	rsf->ch[1].chanstart=GetFileSize(rsf->ch[1].infile,NULL)/2;
	rsf->file_length=GetFileSize(rsf->ch[0].infile,NULL);
#else
	rsf->ch[1].chanstart=IDOS->GetFileSize(rsf->ch[1].infile)/2;
	rsf->file_length=IDOS->GetFileSize(rsf->ch[0].infile);
#endif

	rsf->ch[0].hist1 = 0;
    rsf->ch[0].hist2 = 0;
    rsf->ch[1].hist1 = 0;
    rsf->ch[1].hist2 = 0;

	rsf->ch[0].offs = rsf->ch[0].chanstart;
	rsf->ch[1].offs = rsf->ch[1].chanstart;

	if (!rsf->ch[0].loop_flag) rsf->nrsamples = rsf->ch[0].num_samples;
	else rsf->nrsamples=rsf->ch[0].sa+looptimes*(rsf->ch[0].ea-rsf->ch[0].sa)+(fadelength+fadedelay)*rsf->ch[0].sample_rate;
	
	rsf->ch[0].readloc=rsf->ch[1].readloc=rsf->ch[0].writeloc=rsf->ch[1].writeloc=0;
		
	return 0;
}

void fillbufferRSF(CUBESTREAM * stream) {
	int i,l;
	short decodebuf[2];
	unsigned char ADPCMbuf[16];

	do {
		if (stream->loop_flag && stream->offs+16 > stream->chanstart+stream->ea/2) {
			stream->offs=stream->chanstart+stream->sa/2;
		}
		
#ifndef __amigaos4__
		SetFilePointer(stream->infile,stream->offs,0,FILE_BEGIN);
		ReadFile(stream->infile, ADPCMbuf, 16, &l, NULL);
#else
		IDOS->ChangeFilePosition(stream->infile, stream->offs, OFFSET_BEGINNING);
		l = IDOS->FRead(stream->infile, ADPCMbuf, 1, 16);
#endif
		if (l<=0) return;
		stream->offs+=l;
		
		for (i=0;l>0;i++,l--) {
			RSFdecodebuffer(ADPCMbuf[i],decodebuf,&stream->hist1,&stream->hist2);
			//DisplayError("read %02x\nout: %04x %04x",ADPCMbuf[0],decodebuf[0],decodebuf[1]);
		
			stream->chanbuf[stream->writeloc++]=decodebuf[0];
			stream->chanbuf[stream->writeloc++]=decodebuf[1];
			if (stream->writeloc>=HEX_8000_DIV_EIGHT_MUL_FOURTEEN) stream->writeloc=0;
		}
	} while (stream->writeloc != stream->readloc);
}
