123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- #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;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.cpp
- bool 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);
- }
|