#include "tn_adplug.h"
#include "TN_AdPlug.bin_rev.h"

#ifndef min
#define min(a,b) (((a)<(b))?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))
#endif

struct TNDecHandle *handlePtr;

const char verstag[] = VERSTAG;

int main (int argc, char **argv) {
	struct TNDecHandle *handle;
	uint32 signals;
	int rc = 20;
	int32 cnt = 0, i;

	handlePtr =
	handle = (struct TNDecHandle *)argv;

	handle->mydb = new CAdPlugDatabase();
	if (!handle->mydb) goto out;
	handle->mydb->load("PROGDIR:Plugins/data/adplug.db");
	CAdPlug::set_database(handle->mydb);

	handle->opl = new CEmuopl(44100, TRUE, TRUE);
	if (!handle->opl) goto out;

	handle->pl = CAdPlug::factory(handle->filename, handle->opl);
	if (!handle->pl) goto out;

	handle->length_ms = handle->pl->songlength();

	handle->datasig = 1 << IExec->AllocSignal(-1);
	handle->endsig = 1 << IExec->AllocSignal(-1);
	IExec->ReplyMsg(&handle->msg);

	handle->data_in_buffer = 0;
	rc = 0;
	for (;;) {
		signals = IExec->Wait(handle->datasig|handle->endsig);
		if (signals & handle->endsig) {
			break;
		}
		handle->data_in_buffer = 0;
		if (!handle->eof) {
			while (cnt < 0) {
				cnt += 44100;
				handle->eof = !handle->pl->update();
			}
			i = min(handle->pcm_size, (int32)(cnt / handle->pl->getrefresh() + 4) & ~3);
			handle->opl->update(handle->pcm, i);
			handle->data_in_buffer = i;
			cnt -= (int32)(handle->pl->getrefresh() * i);
		}
		IExec->Signal(handle->main_task, SIGF_CHILD);
	}

out:
	handle->player_task = NULL;
	delete(handle->pl);
	delete(handle->opl);
	delete(handle->mydb);
	return rc;
}
