#include "main.h" #include "cvt.h" #define _MThd 'dhTM' #define _MTrk 'krTM' #define tempo 0x188000 #define Q_MAX 128 struct 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;nct) 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_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); }