/* =======================
     z2m MDDデータを扱う
   ======================= */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "VarLen.h"
#include "etc.h"
/* #include "z.h" */

/* ryk ==> */
#ifdef ZTOM_STATIC_LIB	/* Static lib */
	#include "setjmp.h"
	#include "etc.h"
	extern jmp_buf g_ztommark;
#endif
/* <== ryk */

#include "config.h"
DWORD bulkdump(UBYTE *MTrk,UBYTE *MTrk_st,DWORD *MDDdelay,char *filename,DWORD *bufs);

#ifdef __GCC__
	#include <unistd.h>
#endif

DWORD bulkdump(UBYTE *MTrk,UBYTE *MTrk_st,DWORD *MDDdelay,char *filename,DWORD *bufs)
{
	DWORD i,k = 0,len,ptr = 0,ptr2 = 0;
	FILE *fp;
	char file[64];
	UBYTE *buf;

	strcpy(file,filename);
	for (i = strlen(file); i > 0; i--) {
		if (file[i]=='.') break;
	}
	if (i < 0) {
		i = strlen(file);
	}
	strcpy(&filename[i],".MDD");

	fp = fopen(file,"rb");
	if (fp == (FILE *)NULL) {
#ifndef ENGLISH
		ZTOMFormatMessage(stderr,"%s:ファイルが存在しません。\n",file);
#else
		ZTOMFormatMessage(stderr,"%s: file does not exist.\n",file);
#endif
	terminateProgram(1);
/* ryk ==> */
#ifdef ZTOM_STATIC_LIB	/* Static lib */
		longjmp(g_ztommark, 1);
#endif
/* <== ryk */
	}

#ifndef ENGLISH
	ZTOMFormatMessage(stderr," MDDファイル[%s]を読み込みます。\n",file);
#else
	ZTOMFormatMessage(stderr," reading %s...\n",file);
#endif
	/* len = filelen(fp); */
	/* len = filelength(fileno(fp)); */
	fseek(fp,0,SEEK_END);
	len = ftell(fp);
	rewind(fp);


	buf = emalloc(len, "buf");
	if ( (fread(buf,sizeof(UBYTE),len,fp)) != (size_t)len ) {
#ifndef ENGLISH
		ZTOMFormatMessage(stderr,"%s:ファイルが読めません。\n",file);
#else
		ZTOMFormatMessage(stderr,"%s: can't read.\n",file);
#endif
	terminateProgram(1);
/* ryk ==> */
#ifdef ZTOM_STATIC_LIB	/* Static lib */
		longjmp(g_ztommark, 1);
#endif
/* <== ryk */
	}
	fclose(fp);

	i = -1;
	while (ptr < len) {
		if ( ('0' <= buf[ptr] )&&(buf[ptr] <= '9') ) {
			if (i < 0) i = 0;
			i <<= 4;
			i  += buf[ptr++]-'0';
		} else if ( ('A' <= buf[ptr] )&&(buf[ptr] <= 'F') ) {
			if (i<0) i=0;
			i <<= 4;
			i  += buf[ptr++]-'A'+10;
		} else {
			switch ( buf[ptr++] ) {
				case ' ':
				case 0x0D:
					if (i>=0) {
						buf[ptr2++] = i;
						i = -1;
					}
					if ( (ptr2>0) && (buf[ptr2-1] == 0xF7) ) {	/* exclusive end */
						DWORD j;
						MTrk += PutVarLen(MTrk,*MDDdelay);	/* delta time */
						k += *MDDdelay;
						*MTrk++ = buf[0];
						if ( ( buf[0]!=0xF0 )&&( buf[0]!=0xF7 ) ) {
							fatal(1,"MDD file: not exclusive mes.\n");
						}
						MTrk += PutVarLen(MTrk,ptr2-1);
						for (j=1; j<=ptr2-1; j++) {
							*MTrk++ = buf[j];
						}
						ptr2 = 0;
					}
					break;
				case 0x0A:
					break;
				default:
					while ( buf[ptr++] != 0x0D )
						;
			}
			if (MTrk - MTrk_st> (*bufs<<10)-512) {		/* 512でいいよね */
				DWORD j = MTrk - MTrk_st;
				*bufs += 16;
				MTrk_st = (UBYTE *)erealloc((void *)MTrk_st,*bufs*1024, "MTrk_st");
				MTrk = MTrk_st + j;
			}
		}
	}

	efree(buf, "buf");
	*MDDdelay = k;
	return MTrk_st - MTrk;
}
