hmi.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "main.h"
  2. #include "cvt.h"
  3. #define _MThd 'dhTM'
  4. #define _MTrk 'krTM'
  5. #define tempo 0x188000
  6. #define Q_MAX 128
  7. struct HMI_cvt
  8. {
  9. public:
  10. struct
  11. {
  12. DWORD tm;
  13. BYTE ch,n;
  14. } q_rel[Q_MAX];
  15. void inline q_add(BYTE ch,BYTE nt,DWORD t)
  16. {
  17. UINT n=0;
  18. while(q_rel[n].tm!=-1) n++;
  19. q_rel[n].tm=t;
  20. q_rel[n].ch=ch;
  21. q_rel[n].n=nt;
  22. }
  23. grow_buf buf;
  24. UINT DoTrack(const BYTE* t,UINT *_bw);
  25. void DoQueue(DWORD ct,DWORD& tw,BYTE& _run);
  26. bool run(MIDI_file * mf,const BYTE* _buf,DWORD sz);
  27. };
  28. #define FixHeader(H) {(H).fmt=rev16((H).fmt);(H).trax=rev16((H).trax);(H).dtx=rev16((H).dtx);}
  29. void HMI_cvt::DoQueue(DWORD ct,DWORD& tw,BYTE& _run)
  30. {
  31. UINT n,mt,_n;
  32. _t:
  33. mt=-1;
  34. for(n=0;n<Q_MAX;n++)
  35. {
  36. if (q_rel[n].tm<mt) {_n=n;mt=q_rel[n].tm;}
  37. }
  38. if (mt>ct) return;
  39. gb_write_delta(buf,mt-tw);
  40. tw=mt;
  41. BYTE _e=q_rel[_n].ch|0x90;
  42. if (_e!=_run) buf.write_byte(_run=_e);
  43. buf.write_byte(q_rel[_n].n);
  44. buf.write_byte(0);
  45. q_rel[_n].tm=-1;
  46. goto _t;
  47. }
  48. extern BYTE ff7loopstart[12];
  49. UINT HMI_cvt::DoTrack(const BYTE* t,UINT *_bw)
  50. {
  51. {
  52. UINT n;
  53. for(n=0;n<Q_MAX;n++) q_rel[n].tm=-1;
  54. }
  55. DWORD pt=0;
  56. DWORD ct=0,tw=0;
  57. BYTE run=0;
  58. BYTE _run=0;
  59. DWORD bw_s=buf.get_size();
  60. while(1)
  61. {
  62. {
  63. unsigned int _d;
  64. pt+=DecodeDelta(t+pt,&_d);
  65. ct+=_d;
  66. }
  67. DoQueue(ct,tw,_run);
  68. BYTE c=t[pt];
  69. if (c==0xFF)
  70. {
  71. DoQueue(-2,tw,_run);
  72. if (t[pt+1]==0x2f)
  73. {
  74. pt+=3;
  75. buf.write_dword(0x002FFF00);
  76. break;
  77. }
  78. return -1;
  79. }
  80. else if (c==0xF0)
  81. {
  82. gb_write_delta(buf,ct-tw);
  83. tw=ct;
  84. UINT _p=pt;
  85. while(t[pt]!=0xF7) pt++;
  86. pt++;
  87. buf.write(t+_p,pt-_p);
  88. }
  89. else if (c==0xFE)
  90. {
  91. c=t[pt+1];
  92. if (c==0x10)
  93. {
  94. pt+=t[pt+4]+9;
  95. }
  96. else if (c==0x14)
  97. {
  98. pt+=4;
  99. gb_write_delta(buf,ct-tw);
  100. tw=ct;
  101. buf.write(ff7loopstart,12);
  102. }
  103. else if (c==0x15) pt+=8;
  104. else return -1;
  105. }
  106. else
  107. {
  108. gb_write_delta(buf,ct-tw);
  109. tw=ct;
  110. if (c&0x80) {pt++;run=c;}
  111. else c=run;
  112. if (c!=_run) buf.write_byte(_run=c);
  113. buf.write_byte(t[pt++]);
  114. BYTE c1=c&0xF0;
  115. if (c1!=0xC0 && c1!=0xD0) buf.write_byte(t[pt++]);
  116. if (c1==0x90)
  117. {
  118. BYTE b=t[pt-2];
  119. unsigned int _t;
  120. pt+=DecodeDelta(t+pt,&_t);
  121. q_add(c&0xF,b,_t+ct);
  122. }
  123. }
  124. }
  125. (*_bw)+=buf.get_size()-bw_s;
  126. return pt;
  127. }
  128. extern BYTE hmp_track0[19]; //hmp.cpp
  129. bool HMI_cvt::run(MIDI_file* mf,const BYTE* _buf,DWORD sz)
  130. {
  131. const BYTE *ptr=_buf;
  132. while(*(DWORD*)ptr!='CART')
  133. {
  134. ptr++;
  135. if (ptr==_buf+sz) {return 0;}
  136. }
  137. buf.write(0,14);
  138. ptr-=8;
  139. UINT ntrax=1;
  140. UINT nft=*(DWORD*)(_buf+0xE4);
  141. buf.write(hmp_track0,sizeof(hmp_track0));
  142. UINT n;
  143. for(n=0;n<nft;n++)
  144. {
  145. if (ptr>_buf+sz) return 0;
  146. UINT _b=0;
  147. ntrax++;
  148. buf.write_dword(_rv('MTrk'));
  149. DWORD _s=buf.get_size();
  150. buf.write(0,4);
  151. {
  152. const BYTE* p1=ptr+ptr[0x4B];
  153. const BYTE* _p=p1+p1[1];
  154. p1+=2;
  155. while(_p[-1]==' ') _p--;
  156. _b=(_p-p1)+4;
  157. BYTE tmp[3]={0,0xFF,1};
  158. buf.write(tmp,3);
  159. gb_write_delta(buf,_p-p1);
  160. buf.write(p1,_p-p1);
  161. p1=_p;
  162. }
  163. ptr+=ptr[0x57];
  164. {
  165. DWORD d=DoTrack(ptr,&_b);
  166. if (d==-1) return 0;
  167. ptr+=d;
  168. }
  169. buf.write_dword_ptr(rev32(_b),_s);
  170. }
  171. buf.write_dword_ptr(_rv('MThd'),0);
  172. buf.write_dword_ptr(_rv(6),4);
  173. MIDIHEADER mhd={0x0100,rev16(ntrax),0xC000};
  174. buf.write_ptr(&mhd,sizeof(mhd),8);
  175. mf->size = buf.get_size();
  176. mf->data = (BYTE*)buf.finish();
  177. return !!mf->data;
  178. }
  179. bool load_hmi(MIDI_file* mf,const BYTE* _buf,size_t sz)
  180. {
  181. HMI_cvt c;
  182. return c.run(mf,_buf,sz);
  183. }