| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 | #include "main.h"#include "cvt.h"#define _MThd 'dhTM'#define _MTrk 'krTM'#define tempo 0x188000#define Q_MAX 128struct HMI_cvt{public:	struct	{		DWORD tm;		BYTE ch,n;	} q_rel[Q_MAX];	void inline q_add(BYTE ch,BYTE nt,DWORD t)	{		UINT n=0;		while(q_rel[n].tm!=-1) n++;		q_rel[n].tm=t;		q_rel[n].ch=ch;		q_rel[n].n=nt;	}	grow_buf buf;	UINT DoTrack(const BYTE* t,UINT *_bw);	void DoQueue(DWORD ct,DWORD& tw,BYTE& _run);	bool run(MIDI_file * mf,const BYTE* _buf,DWORD sz);};#define FixHeader(H) {(H).fmt=rev16((H).fmt);(H).trax=rev16((H).trax);(H).dtx=rev16((H).dtx);}void HMI_cvt::DoQueue(DWORD ct,DWORD& tw,BYTE& _run){	UINT n,mt,_n;_t:		mt=-1;	for(n=0;n<Q_MAX;n++)	{		if (q_rel[n].tm<mt) {_n=n;mt=q_rel[n].tm;}	}	if (mt>ct) return;	gb_write_delta(buf,mt-tw);	tw=mt;	BYTE _e=q_rel[_n].ch|0x90;	if (_e!=_run) buf.write_byte(_run=_e);	buf.write_byte(q_rel[_n].n);	buf.write_byte(0);	q_rel[_n].tm=-1;	goto _t;}extern BYTE ff7loopstart[12];UINT HMI_cvt::DoTrack(const BYTE* t,UINT *_bw){	{		UINT n;		for(n=0;n<Q_MAX;n++) q_rel[n].tm=-1;	}	DWORD pt=0;	DWORD ct=0,tw=0;	BYTE run=0;	BYTE _run=0;	DWORD bw_s=buf.get_size();	while(1)	{		{			unsigned int _d;			pt+=DecodeDelta(t+pt,&_d);			ct+=_d;		}		DoQueue(ct,tw,_run);		BYTE c=t[pt];		if (c==0xFF)		{			DoQueue(-2,tw,_run);			if (t[pt+1]==0x2f)			{				pt+=3;				buf.write_dword(0x002FFF00);				break;			}			return -1;					}		else if (c==0xF0)		{			gb_write_delta(buf,ct-tw);			tw=ct;			UINT _p=pt;			while(t[pt]!=0xF7) pt++;			pt++;			buf.write(t+_p,pt-_p);		}		else if (c==0xFE)		{			c=t[pt+1];			if (c==0x10)			{				pt+=t[pt+4]+9;			}			else if (c==0x14)			{				pt+=4;				gb_write_delta(buf,ct-tw);				tw=ct;				buf.write(ff7loopstart,12);			}			else if (c==0x15) pt+=8;			else return -1;		}		else		{			gb_write_delta(buf,ct-tw);			tw=ct;			if (c&0x80) {pt++;run=c;}			else c=run;			if (c!=_run) buf.write_byte(_run=c);			buf.write_byte(t[pt++]);			BYTE c1=c&0xF0;			if (c1!=0xC0 && c1!=0xD0) buf.write_byte(t[pt++]);			if (c1==0x90)			{				BYTE b=t[pt-2];				unsigned int _t;				pt+=DecodeDelta(t+pt,&_t);				q_add(c&0xF,b,_t+ct);			}		}	}	(*_bw)+=buf.get_size()-bw_s;	return pt;}extern BYTE hmp_track0[19];	//hmp.cppbool HMI_cvt::run(MIDI_file* mf,const BYTE* _buf,DWORD sz){	const BYTE *ptr=_buf;	while(*(DWORD*)ptr!='CART')	{		ptr++;		if (ptr==_buf+sz) {return 0;}	}		buf.write(0,14);	ptr-=8;	UINT ntrax=1;	UINT nft=*(DWORD*)(_buf+0xE4);	buf.write(hmp_track0,sizeof(hmp_track0));	UINT n;	for(n=0;n<nft;n++)	{		if (ptr>_buf+sz) return 0;		UINT _b=0;		ntrax++;		buf.write_dword(_rv('MTrk'));		DWORD _s=buf.get_size();		buf.write(0,4);		{			const BYTE* p1=ptr+ptr[0x4B];			const BYTE* _p=p1+p1[1];			p1+=2;			while(_p[-1]==' ') _p--;			_b=(_p-p1)+4;			BYTE tmp[3]={0,0xFF,1};			buf.write(tmp,3);			gb_write_delta(buf,_p-p1);			buf.write(p1,_p-p1);			p1=_p;		}		ptr+=ptr[0x57];		{			DWORD d=DoTrack(ptr,&_b);			if (d==-1) return 0;			ptr+=d;		}		buf.write_dword_ptr(rev32(_b),_s);	}	buf.write_dword_ptr(_rv('MThd'),0);	buf.write_dword_ptr(_rv(6),4);	MIDIHEADER mhd={0x0100,rev16(ntrax),0xC000};	buf.write_ptr(&mhd,sizeof(mhd),8);		mf->size = buf.get_size();	mf->data = (BYTE*)buf.finish();	return !!mf->data;}bool load_hmi(MIDI_file* mf,const BYTE* _buf,size_t sz){	HMI_cvt c;	return c.run(mf,_buf,sz);}
 |