]> 4ch.mooo.com Git - 16.git/blob - 16/adplug/adplug-2.2.1/src/mid.cpp
Please enter the commit message for your changes. Lines starting
[16.git] / 16 / adplug / adplug-2.2.1 / src / mid.cpp
1 /*
2  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
3  * Copyright (C) 1999 - 2008 Simon Peter, <dn.tlp@gmx.net>, et al.
4  * 
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  * 
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  * 
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  *
20  * MIDI & MIDI-like file player - Last Update: 10/15/2005
21  *                  by Phil Hassey - www.imitationpickles.org
22  *                                   philhassey@hotmail.com
23  *
24  * Can play the following
25  *      .LAA - a raw save of a Lucas Arts Adlib music
26  *             or
27  *             a raw save of a LucasFilm Adlib music
28  *      .MID - a "midi" save of a Lucas Arts Adlib music
29  *           - or general MIDI files
30  *      .CMF - Creative Music Format
31  *      .SCI - the sierra "midi" format.
32  *             Files must be in the form
33  *             xxxNAME.sci
34  *             So that the loader can load the right patch file:
35  *             xxxPATCH.003  (patch.003 must be saved from the
36  *                            sierra resource from each game.)
37  *
38  * 6/2/2000:  v1.0 relased by phil hassey
39  *      Status:  LAA is almost perfect
40  *                      - some volumes are a bit off (intrument too quiet)
41  *               MID is fine (who wants to listen to MIDI vid adlib anyway)
42  *               CMF is okay (still needs the adlib rythm mode implemented
43  *                            for real)
44  * 6/6/2000:
45  *      Status:  SCI:  there are two SCI formats, orginal and advanced.
46  *                    original:  (Found in SCI/EGA Sierra Adventures)
47  *                               played almost perfectly, I believe
48  *                               there is one mistake in the instrument
49  *                               loader that causes some sounds to
50  *                               not be quite right.  Most sounds are fine.
51  *                    advanced:  (Found in SCI/VGA Sierra Adventures)
52  *                               These are multi-track files.  (Thus the
53  *                               player had to be modified to work with
54  *                               them.)  This works fine.
55  *                               There are also multiple tunes in each file.
56  *                               I think some of them are supposed to be
57  *                               played at the same time, but I'm not sure
58  *                               when.
59  * 8/16/2000:
60  *      Status:  LAA: now EGA and VGA lucas games work pretty well
61  *
62  * 10/15/2005: Changes by Simon Peter
63  *      Added rhythm mode support for CMF format.
64  *
65  * 09/13/2008: Changes by Adam Nielsen (malvineous@shikadi.net)
66  *      Fixed a couple of CMF rhythm mode bugs
67  *      Disabled note velocity for CMF files
68  *      Added support for nonstandard CMF AM+VIB controller (for VGFM CMFs)
69  *
70  * Other acknowledgements:
71  *  Allegro - for the midi instruments and the midi volume table
72  *  SCUMM Revisited - for getting the .LAA / .MIDs out of those
73  *                    LucasArts files.
74  *  FreeSCI - for some information on the sci music files
75  *  SD - the SCI Decoder (to get all .sci out of the Sierra files)
76  */
77
78 #include <stdlib.h>
79 #include <stdio.h>
80 #include <math.h>
81 #include <string.h>
82 #include "mid.h"
83 #include "mididata.h"
84
85 /*#define TESTING*/
86 #ifdef TESTING
87 #define midiprintf printf
88 #else
89 void CmidPlayer::midiprintf(const char *format, ...)
90     {
91     }
92 #endif
93
94 #define LUCAS_STYLE   1
95 #define CMF_STYLE     2
96 #define MIDI_STYLE    4
97 #define SIERRA_STYLE  8
98
99 // AdLib melodic and rhythm mode defines
100 #define ADLIB_MELODIC   0
101 #define ADLIB_RYTHM     1
102
103 // File types
104 #define FILE_LUCAS      1
105 #define FILE_MIDI       2
106 #define FILE_CMF        3
107 #define FILE_SIERRA     4
108 #define FILE_ADVSIERRA  5
109 #define FILE_OLDLUCAS   6
110
111 // AdLib standard operator table
112 const unsigned char CmidPlayer::adlib_opadd[] = {0x00  ,0x01 ,0x02  ,0x08  ,0x09  ,0x0A  ,0x10 ,0x11  ,0x12};
113
114 // map CMF drum channels 12 - 15 to corresponding AdLib drum operators
115 // bass drum (channel 11) not mapped, cause it's handled like a normal instrument
116 const int CmidPlayer::map_chan[] = { 0x14, 0x12, 0x15, 0x11 };
117
118 // Standard AdLib frequency table
119 const int CmidPlayer::fnums[] = { 0x16b,0x181,0x198,0x1b0,0x1ca,0x1e5,0x202,0x220,0x241,0x263,0x287,0x2ae };
120
121 // Map CMF drum channels 11 - 15 to corresponding AdLib drum channels
122 const int CmidPlayer::percussion_map[] = { 6, 7, 8, 8, 7 };
123
124 CPlayer *CmidPlayer::factory(Copl *newopl)
125 {
126   return new CmidPlayer(newopl);
127 }
128
129 CmidPlayer::CmidPlayer(Copl *newopl)
130   : CPlayer(newopl), author(&emptystr), title(&emptystr), remarks(&emptystr),
131     emptystr('\0'), flen(0), data(0)
132 {
133 }
134
135 unsigned char CmidPlayer::datalook(long pos)
136 {
137     if (pos<0 || pos >= flen) return(0);
138     return(data[pos]);
139 }
140
141 unsigned long CmidPlayer::getnexti(unsigned long num)
142 {
143         unsigned long v=0;
144         unsigned long i;
145
146     for (i=0; i<num; i++)
147         {
148         v+=(datalook(pos)<<(8*i)); pos++;
149         }
150     return(v);
151 }
152
153 unsigned long CmidPlayer::getnext(unsigned long num)
154 {
155         unsigned long v=0;
156         unsigned long i;
157
158     for (i=0; i<num; i++)
159         {
160         v<<=8;
161         v+=datalook(pos); pos++;
162         }
163     return(v);
164 }
165
166 unsigned long CmidPlayer::getval()
167 {
168     int v=0;
169         unsigned char b;
170
171     b=(unsigned char)getnext(1);
172         v=b&0x7f;
173         while ((b&0x80) !=0)
174                 {
175         b=(unsigned char)getnext(1);
176         v = (v << 7) + (b & 0x7F);
177                 }
178         return(v);
179 }
180
181 bool CmidPlayer::load_sierra_ins(const std::string &fname, const CFileProvider &fp)
182 {
183     long i,j,k,l;
184     unsigned char ins[28];
185     char *pfilename;
186     binistream *f;
187
188     pfilename = (char *)malloc(fname.length()+9);
189     strcpy(pfilename,fname.c_str());
190     j=0;
191     for(i=strlen(pfilename)-1; i >= 0; i--)
192       if(pfilename[i] == '/' || pfilename[i] == '\\') {
193         j = i+1;
194         break;
195       }
196     sprintf(pfilename+j+3,"patch.003");
197
198     f = fp.open(pfilename);
199     free(pfilename);
200     if(!f) return false;
201
202     f->ignore(2);
203     stins = 0;
204     for (i=0; i<2; i++)
205         {
206         for (k=0; k<48; k++)
207             {
208             l=i*48+k;
209             midiprintf ("\n%2d: ",l);
210             for (j=0; j<28; j++)
211                 ins[j] = f->readInt(1);
212
213             myinsbank[l][0]=
214                 (ins[9]*0x80) + (ins[10]*0x40) +
215                 (ins[5]*0x20) + (ins[11]*0x10) +
216                 ins[1];   //1=ins5
217             myinsbank[l][1]=
218                 (ins[22]*0x80) + (ins[23]*0x40) +
219                 (ins[18]*0x20) + (ins[24]*0x10) +
220                 ins[14];  //1=ins18
221
222             myinsbank[l][2]=(ins[0]<<6)+ins[8];
223             myinsbank[l][3]=(ins[13]<<6)+ins[21];
224
225             myinsbank[l][4]=(ins[3]<<4)+ins[6];
226             myinsbank[l][5]=(ins[16]<<4)+ins[19];
227             myinsbank[l][6]=(ins[4]<<4)+ins[7];
228             myinsbank[l][7]=(ins[17]<<4)+ins[20];
229
230             myinsbank[l][8]=ins[26];
231             myinsbank[l][9]=ins[27];
232
233             myinsbank[l][10]=((ins[2]<<1))+(1-(ins[12]&1));
234             //(ins[12] ? 0:1)+((ins[2]<<1));
235
236             for (j=0; j<11; j++)
237                 midiprintf ("%02X ",myinsbank[l][j]);
238                         stins++;
239             }
240                 f->ignore(2);
241         }
242
243     fp.close(f);
244     memcpy(smyinsbank, myinsbank, 128 * 16);
245     return true;
246 }
247
248 void CmidPlayer::sierra_next_section()
249 {
250     int i,j;
251
252     for (i=0; i<16; i++)
253         track[i].on=0;
254
255     midiprintf("\n\nnext adv sierra section:\n");
256
257     pos=sierra_pos;
258     i=0;j=0;
259     while (i!=0xff)
260        {
261        getnext(1);
262        curtrack=j; j++;
263        track[curtrack].on=1;
264            track[curtrack].spos = getnext(1);
265            track[curtrack].spos += (getnext(1) << 8) + 4;       //4 best usually +3? not 0,1,2 or 5
266 //       track[curtrack].spos=getnext(1)+(getnext(1)<<8)+4;             // dynamite!: doesn't optimize correctly!!
267        track[curtrack].tend=flen; //0xFC will kill it
268        track[curtrack].iwait=0;
269        track[curtrack].pv=0;
270        midiprintf ("track %d starts at %lx\n",curtrack,track[curtrack].spos);
271
272        getnext(2);
273        i=getnext(1);
274        }
275     getnext(2);
276     deltas=0x20;
277     sierra_pos=pos;
278     //getch();
279
280     fwait=0;
281     doing=1;
282 }
283
284 bool CmidPlayer::load(const std::string &filename, const CFileProvider &fp)
285 {
286     binistream *f = fp.open(filename); if(!f) return false;
287     int good;
288     unsigned char s[6];
289
290     f->readString((char *)s, 6);
291     good=0;
292     subsongs=0;
293     switch(s[0])
294         {
295         case 'A':
296             if (s[1]=='D' && s[2]=='L') good=FILE_LUCAS;
297             break;
298         case 'M':
299             if (s[1]=='T' && s[2]=='h' && s[3]=='d') good=FILE_MIDI;
300             break;
301         case 'C':
302             if (s[1]=='T' && s[2]=='M' && s[3]=='F') good=FILE_CMF;
303             break;
304         case 0x84:
305           if (s[1]==0x00 && load_sierra_ins(filename, fp)) {
306             if (s[2]==0xf0)
307               good=FILE_ADVSIERRA;
308             else
309               good=FILE_SIERRA;
310           }
311           break;
312         default:
313             if (s[4]=='A' && s[5]=='D') good=FILE_OLDLUCAS;
314             break;
315         }
316
317     if (good!=0)
318                 subsongs=1;
319     else {
320       fp.close(f);
321       return false;
322     }
323
324     type=good;
325     f->seek(0);
326     flen = fp.filesize(f);
327     data = new unsigned char [flen];
328     f->readString((char *)data, flen);
329
330     fp.close(f);
331     rewind(0);
332     return true;
333 }
334
335 void CmidPlayer::midi_write_adlib(unsigned int r, unsigned char v)
336 {
337   opl->write(r,v);
338   adlib_data[r]=v;
339 }
340
341 void CmidPlayer::midi_fm_instrument(int voice, unsigned char *inst)
342 {
343     if ((adlib_style&SIERRA_STYLE)!=0)
344         midi_write_adlib(0xbd,0);  //just gotta make sure this happens..
345                                       //'cause who knows when it'll be
346                                       //reset otherwise.
347
348
349     midi_write_adlib(0x20+adlib_opadd[voice],inst[0]);
350     midi_write_adlib(0x23+adlib_opadd[voice],inst[1]);
351
352     if (adlib_style & LUCAS_STYLE) {
353         midi_write_adlib(0x43+adlib_opadd[voice],0x3f);
354         if ((inst[10] & 1)==0)
355             midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
356         else
357             midi_write_adlib(0x40+adlib_opadd[voice],0x3f);
358
359     } else if ((adlib_style & SIERRA_STYLE) || (adlib_style & CMF_STYLE)) {
360         midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
361         midi_write_adlib(0x43+adlib_opadd[voice],inst[3]);
362
363     } else {
364         midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
365         if ((inst[10] & 1)==0)
366             midi_write_adlib(0x43+adlib_opadd[voice],inst[3]);
367         else
368             midi_write_adlib(0x43+adlib_opadd[voice],0);
369     }
370
371     midi_write_adlib(0x60+adlib_opadd[voice],inst[4]);
372     midi_write_adlib(0x63+adlib_opadd[voice],inst[5]);
373     midi_write_adlib(0x80+adlib_opadd[voice],inst[6]);
374     midi_write_adlib(0x83+adlib_opadd[voice],inst[7]);
375     midi_write_adlib(0xe0+adlib_opadd[voice],inst[8]);
376     midi_write_adlib(0xe3+adlib_opadd[voice],inst[9]);
377
378     midi_write_adlib(0xc0+voice,inst[10]);
379 }
380
381 void CmidPlayer::midi_fm_percussion(int ch, unsigned char *inst)
382 {
383   int   opadd = map_chan[ch - 12];
384
385   midi_write_adlib(0x20 + opadd, inst[0]);
386   midi_write_adlib(0x40 + opadd, inst[2]);
387   midi_write_adlib(0x60 + opadd, inst[4]);
388   midi_write_adlib(0x80 + opadd, inst[6]);
389   midi_write_adlib(0xe0 + opadd, inst[8]);
390   if (opadd < 0x13) // only output this for the modulator, not the carrier, as it affects the entire channel
391       midi_write_adlib(0xc0 + percussion_map[ch - 11], inst[10]);
392 }
393
394 void CmidPlayer::midi_fm_volume(int voice, int volume)
395 {
396     int vol;
397
398     if ((adlib_style&SIERRA_STYLE)==0)  //sierra likes it loud!
399     {
400     vol=volume>>2;
401
402     if ((adlib_style&LUCAS_STYLE)!=0)
403         {
404         if ((adlib_data[0xc0+voice]&1)==1)
405             midi_write_adlib(0x40+adlib_opadd[voice], (unsigned char)((63-vol) |
406             (adlib_data[0x40+adlib_opadd[voice]]&0xc0)));
407         midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) |
408             (adlib_data[0x43+adlib_opadd[voice]]&0xc0)));
409         }
410         else
411         {
412         if ((adlib_data[0xc0+voice]&1)==1)
413             midi_write_adlib(0x40+adlib_opadd[voice], (unsigned char)((63-vol) |
414             (adlib_data[0x40+adlib_opadd[voice]]&0xc0)));
415         midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) |
416            (adlib_data[0x43+adlib_opadd[voice]]&0xc0)));
417         }
418     }
419 }
420
421 void CmidPlayer::midi_fm_playnote(int voice, int note, int volume)
422 {
423     int freq=fnums[note%12];
424     int oct=note/12;
425         int c;
426
427     midi_fm_volume(voice,volume);
428     midi_write_adlib(0xa0+voice,(unsigned char)(freq&0xff));
429
430         c=((freq&0x300) >> 8)+((oct&7)<<2) + (adlib_mode == ADLIB_MELODIC || voice < 6 ? (1<<5) : 0);
431     midi_write_adlib(0xb0+voice,(unsigned char)c);
432 }
433
434 void CmidPlayer::midi_fm_endnote(int voice)
435 {
436     //midi_fm_volume(voice,0);
437     //midi_write_adlib(0xb0+voice,0);
438
439     midi_write_adlib(0xb0+voice,(unsigned char)(adlib_data[0xb0+voice]&(255-32)));
440 }
441
442 void CmidPlayer::midi_fm_reset()
443 {
444     int i;
445
446     opl->init();
447
448     for (i=0; i<256; i++)
449         midi_write_adlib(i,0);
450
451     midi_write_adlib(0x01, 0x20);
452     midi_write_adlib(0xBD,0xc0);
453 }
454
455 bool CmidPlayer::update()
456 {
457     long w,v,note,vel,ctrl,nv,x,l,lnum;
458     int i=0,j,c;
459     int on,onl,numchan;
460     int ret;
461
462     if (doing == 1)
463         {
464         // just get the first wait and ignore it :>
465         for (curtrack=0; curtrack<16; curtrack++)
466             if (track[curtrack].on)
467                 {
468                 pos=track[curtrack].pos;
469                 if (type != FILE_SIERRA && type !=FILE_ADVSIERRA)
470                     track[curtrack].iwait+=getval();
471                     else
472                     track[curtrack].iwait+=getnext(1);
473                 track[curtrack].pos=pos;
474                 }
475         doing=0;
476         }
477
478     iwait=0;
479     ret=1;
480
481     while (iwait==0 && ret==1)
482         {
483         for (curtrack=0; curtrack<16; curtrack++)
484         if (track[curtrack].on && track[curtrack].iwait==0 &&
485             track[curtrack].pos < track[curtrack].tend)
486         {
487         pos=track[curtrack].pos;
488
489                 v=getnext(1);
490
491         //  This is to do implied MIDI events.
492         if (v<0x80) {v=track[curtrack].pv; pos--;}
493         track[curtrack].pv=(unsigned char)v;
494
495                 c=v&0x0f;
496         midiprintf ("[%2X]",v);
497         switch(v&0xf0)
498             {
499                         case 0x80: /*note off*/
500                                 note=getnext(1); vel=getnext(1);
501                 for (i=0; i<9; i++)
502                     if (chp[i][0]==c && chp[i][1]==note)
503                         {
504                         midi_fm_endnote(i);
505                         chp[i][0]=-1;
506                         }
507                 break;
508             case 0x90: /*note on*/
509               //  doing=0;
510                 note=getnext(1); vel=getnext(1);
511
512                 if(adlib_mode == ADLIB_RYTHM)
513                   numchan = 6;
514                 else
515                   numchan = 9;
516
517                 if (ch[c].on!=0)
518                 {
519                   for (i=0; i<18; i++)
520                     chp[i][2]++;
521
522                   if(c < 11 || adlib_mode == ADLIB_MELODIC) {
523                     j=0;
524                     on=-1;onl=0;
525                     for (i=0; i<numchan; i++)
526                       if (chp[i][0]==-1 && chp[i][2]>onl)
527                         { onl=chp[i][2]; on=i; j=1; }
528
529                     if (on==-1)
530                       {
531                         onl=0;
532                         for (i=0; i<numchan; i++)
533                           if (chp[i][2]>onl)
534                             { onl=chp[i][2]; on=i; }
535                       }
536
537                     if (j==0)
538                       midi_fm_endnote(on);
539                   } else
540                     on = percussion_map[c - 11];
541
542                   if (vel!=0 && ch[c].inum>=0 && ch[c].inum<128) {
543                     if (adlib_mode == ADLIB_MELODIC || c < 12) // 11 == bass drum, handled like a normal instrument, on == channel 6 thanks to percussion_map[] above
544                       midi_fm_instrument(on,ch[c].ins);
545                     else
546                       midi_fm_percussion(c, ch[c].ins);
547
548                     if (adlib_style & MIDI_STYLE) {
549                         nv=((ch[c].vol*vel)/128);
550                         if ((adlib_style&LUCAS_STYLE)!=0) nv*=2;
551                         if (nv>127) nv=127;
552                         nv=my_midi_fm_vol_table[nv];
553                         if ((adlib_style&LUCAS_STYLE)!=0)
554                             nv=(int)((float)sqrt((float)nv)*11);
555                     } else if (adlib_style & CMF_STYLE) {
556                         // CMF doesn't support note velocity (even though some files have them!)
557                         nv = 127;
558                     } else {
559                         nv=vel;
560                     }
561
562                     midi_fm_playnote(on,note+ch[c].nshift,nv*2); // sets freq in rhythm mode
563                     chp[on][0]=c;
564                     chp[on][1]=note;
565                     chp[on][2]=0;
566
567                     if(adlib_mode == ADLIB_RYTHM && c >= 11) {
568                       // Still need to turn off the perc instrument before playing it again,
569                       // as not all songs send a noteoff.
570                       midi_write_adlib(0xbd, adlib_data[0xbd] & ~(0x10 >> (c - 11)));
571                       // Play the perc instrument
572                       midi_write_adlib(0xbd, adlib_data[0xbd] | (0x10 >> (c - 11)));
573                     }
574
575                   } else {
576                     if (vel==0) { //same code as end note
577                         if (adlib_mode == ADLIB_RYTHM && c >= 11) {
578                             // Turn off the percussion instrument
579                             midi_write_adlib(0xbd, adlib_data[0xbd] & ~(0x10 >> (c - 11)));
580                             //midi_fm_endnote(percussion_map[c]);
581                             chp[percussion_map[c - 11]][0]=-1;
582                         } else {
583                             for (i=0; i<9; i++) {
584                                 if (chp[i][0]==c && chp[i][1]==note) {
585                                     // midi_fm_volume(i,0);  // really end the note
586                                     midi_fm_endnote(i);
587                                     chp[i][0]=-1;
588                                 }
589                             }
590                         }
591                     } else {
592                         // i forget what this is for.
593                         chp[on][0]=-1;
594                         chp[on][2]=0;
595                     }
596                   }
597                   midiprintf(" [%d:%d:%d:%d]\n",c,ch[c].inum,note,vel);
598                 }
599                 else
600                 midiprintf ("off");
601                 break;
602             case 0xa0: /*key after touch */
603                 note=getnext(1); vel=getnext(1);
604                 /*  //this might all be good
605                 for (i=0; i<9; i++)
606                     if (chp[i][0]==c & chp[i][1]==note)
607                         
608 midi_fm_playnote(i,note+cnote[c],my_midi_fm_vol_table[(cvols[c]*vel)/128]*2);
609                 */
610                 break;
611             case 0xb0: /*control change .. pitch bend? */
612                 ctrl=getnext(1); vel=getnext(1);
613
614                 switch(ctrl)
615                     {
616                     case 0x07:
617                         midiprintf ("(pb:%d: %d %d)",c,ctrl,vel);
618                         ch[c].vol=vel;
619                         midiprintf("vol");
620                         break;
621                     case 0x63:
622                         if (adlib_style & CMF_STYLE) {
623                             // Custom extension to allow CMF files to switch the
624                             // AM+VIB depth on and off (officially this is on,
625                             // and there's no way to switch it off.)  Controller
626                             // values:
627                             //   0 == AM+VIB off
628                             //   1 == VIB on
629                             //   2 == AM on
630                             //   3 == AM+VIB on
631                             midi_write_adlib(0xbd, (adlib_data[0xbd] & ~0xC0) | (vel << 6));
632                             midiprintf(" AM+VIB depth change - AM %s, VIB %s\n",
633                                 (adlib_data[0xbd] & 0x80) ? "on" : "off",
634                                 (adlib_data[0xbd] & 0x40) ? "on" : "off"
635                             );
636                         }
637                         break;
638                     case 0x67:
639                         midiprintf("Rhythm mode: %d\n", vel);
640                         if ((adlib_style&CMF_STYLE)!=0) {
641                           adlib_mode=vel;
642                           if(adlib_mode == ADLIB_RYTHM)
643                             midi_write_adlib(0xbd, adlib_data[0xbd] | (1 << 5));
644                           else
645                             midi_write_adlib(0xbd, adlib_data[0xbd] & ~(1 << 5));
646                         }
647                         break;
648                     }
649                 break;
650             case 0xc0: /*patch change*/
651               x=getnext(1);
652               ch[c].inum=x;
653               for (j=0; j<11; j++)
654                 ch[c].ins[j]=myinsbank[ch[c].inum][j];
655               break;
656             case 0xd0: /*chanel touch*/
657                 x=getnext(1);
658                 break;
659             case 0xe0: /*pitch wheel*/
660                 x=getnext(1);
661                 x=getnext(1);
662                 break;
663             case 0xf0:
664                 switch(v)
665                     {
666                     case 0xf0:
667                     case 0xf7: /*sysex*/
668                       l=getval();
669                       if (datalook(pos+l)==0xf7)
670                         i=1;
671                       midiprintf("{%d}",l);
672                       midiprintf("\n");
673
674                         if (datalook(pos)==0x7d &&
675                             datalook(pos+1)==0x10 &&
676                             datalook(pos+2)<16)
677                                                         {
678                             adlib_style=LUCAS_STYLE|MIDI_STYLE;
679                                                         for (i=0; i<l; i++)
680                                                                 {
681                                 midiprintf ("%x ",datalook(pos+i));
682                                 if ((i-3)%10 == 0) midiprintf("\n");
683                                                                 }
684                             midiprintf ("\n");
685                             getnext(1);
686                             getnext(1);
687                                                         c=getnext(1);
688                                                         getnext(1);
689
690                           //  getnext(22); //temp
691                             ch[c].ins[0]=(unsigned char)((getnext(1)<<4)+getnext(1));
692                             ch[c].ins[2]=(unsigned char)(0xff-(((getnext(1)<<4)+getnext(1))&0x3f));
693                             ch[c].ins[4]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
694                             ch[c].ins[6]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
695                             ch[c].ins[8]=(unsigned char)((getnext(1)<<4)+getnext(1));
696
697                             ch[c].ins[1]=(unsigned char)((getnext(1)<<4)+getnext(1));
698                             ch[c].ins[3]=(unsigned char)(0xff-(((getnext(1)<<4)+getnext(1))&0x3f));
699                             ch[c].ins[5]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
700                             ch[c].ins[7]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
701                             ch[c].ins[9]=(unsigned char)((getnext(1)<<4)+getnext(1));
702
703                             i=(getnext(1)<<4)+getnext(1);
704                             ch[c].ins[10]=i;
705
706                             //if ((i&1)==1) ch[c].ins[10]=1;
707
708                             midiprintf ("\n%d: ",c);
709                                                         for (i=0; i<11; i++)
710                                 midiprintf ("%2X ",ch[c].ins[i]);
711                             getnext(l-26);
712                                                         }
713                             else
714                             {
715                             midiprintf("\n");
716                             for (j=0; j<l; j++)
717                                 midiprintf ("%2X ",getnext(1));
718                             }
719
720                         midiprintf("\n");
721                                                 if(i==1)
722                                                         getnext(1);
723                         break;
724                     case 0xf1:
725                         break;
726                     case 0xf2:
727                         getnext(2);
728                         break;
729                     case 0xf3:
730                         getnext(1);
731                         break;
732                     case 0xf4:
733                         break;
734                     case 0xf5:
735                         break;
736                     case 0xf6: /*something*/
737                     case 0xf8:
738                     case 0xfa:
739                     case 0xfb:
740                     case 0xfc:
741                         //this ends the track for sierra.
742                         if (type == FILE_SIERRA ||
743                             type == FILE_ADVSIERRA)
744                             {
745                             track[curtrack].tend=pos;
746                             midiprintf ("endmark: %ld -- %lx\n",pos,pos);
747                             }
748                         break;
749                     case 0xfe:
750                         break;
751                     case 0xfd:
752                         break;
753                     case 0xff:
754                         v=getnext(1);
755                         l=getval();
756                         midiprintf ("\n");
757                         midiprintf("{%X_%X}",v,l);
758                         if (v==0x51)
759                             {
760                             lnum=getnext(l);
761                             msqtr=lnum; /*set tempo*/
762                             midiprintf ("(qtr=%ld)",msqtr);
763                             }
764                             else
765                             {
766                             for (i=0; i<l; i++)
767                                 midiprintf ("%2X ",getnext(1));
768                             }
769                         break;
770                                         }
771                 break;
772             default: midiprintf("!",v); /* if we get down here, a error occurred */
773                         break;
774             }
775
776         if (pos < track[curtrack].tend)
777             {
778             if (type != FILE_SIERRA && type !=FILE_ADVSIERRA)
779                 w=getval();
780                 else
781                 w=getnext(1);
782             track[curtrack].iwait=w;
783             /*
784             if (w!=0)
785                 {
786                 midiprintf("\n<%d>",w);
787                 f = 
788 ((float)w/(float)deltas)*((float)msqtr/(float)1000000);
789                 if (doing==1) f=0; //not playing yet. don't wait yet
790                 }
791                 */
792             }
793             else
794             track[curtrack].iwait=0;
795
796         track[curtrack].pos=pos;
797         }
798
799
800         ret=0; //end of song.
801         iwait=0;
802         for (curtrack=0; curtrack<16; curtrack++)
803             if (track[curtrack].on == 1 &&
804                 track[curtrack].pos < track[curtrack].tend)
805                 ret=1;  //not yet..
806
807         if (ret==1)
808             {
809             iwait=0xffffff;  // bigger than any wait can be!
810             for (curtrack=0; curtrack<16; curtrack++)
811                if (track[curtrack].on == 1 &&
812                    track[curtrack].pos < track[curtrack].tend &&
813                    track[curtrack].iwait < iwait)
814                    iwait=track[curtrack].iwait;
815             }
816         }
817
818
819     if (iwait !=0 && ret==1)
820         {
821         for (curtrack=0; curtrack<16; curtrack++)
822             if (track[curtrack].on)
823                 track[curtrack].iwait-=iwait;
824
825         
826 fwait=1.0f/(((float)iwait/(float)deltas)*((float)msqtr/(float)1000000));
827         }
828         else
829         fwait=50;  // 1/50th of a second
830
831     midiprintf ("\n");
832     for (i=0; i<16; i++)
833       if (track[i].on) {
834         if (track[i].pos < track[i].tend)
835           midiprintf ("<%d>",track[i].iwait);
836         else
837           midiprintf("stop");
838       }
839
840     /*
841     if (ret==0 && type==FILE_ADVSIERRA)
842         if (datalook(sierra_pos-2)!=0xff)
843             {
844             midiprintf ("next sectoin!");
845             sierra_next_section(p);
846             fwait=50;
847             ret=1;
848             }
849     */
850
851         if(ret)
852                 return true;
853         else
854                 return false;
855 }
856
857 float CmidPlayer::getrefresh()
858 {
859     return (fwait > 0.01f ? fwait : 0.01f);
860 }
861
862 void CmidPlayer::rewind(int subsong)
863 {
864     long i,j,n,m,l;
865     long o_sierra_pos;
866     unsigned char ins[16];
867
868     pos=0; tins=0;
869     adlib_style=MIDI_STYLE|CMF_STYLE;
870     adlib_mode=ADLIB_MELODIC;
871     for (i=0; i<128; i++)
872         for (j=0; j<16; j++)
873             myinsbank[i][j]=midi_fm_instruments[i][j];
874         for (i=0; i<16; i++)
875         {
876         ch[i].inum=0;
877         for (j=0; j<11; j++)
878             ch[i].ins[j]=myinsbank[ch[i].inum][j];
879         ch[i].vol=127;
880         ch[i].nshift=-25;
881         ch[i].on=1;
882         }
883
884     /* General init */
885     for (i=0; i<9; i++)
886         {
887         chp[i][0]=-1;
888         chp[i][2]=0;
889         }
890
891     deltas=250;  // just a number,  not a standard
892     msqtr=500000;
893     fwait=123; // gotta be a small thing.. sorta like nothing
894     iwait=0;
895
896     subsongs=1;
897
898     for (i=0; i<16; i++)
899         {
900         track[i].tend=0;
901         track[i].spos=0;
902         track[i].pos=0;
903         track[i].iwait=0;
904         track[i].on=0;
905         track[i].pv=0;
906         }
907     curtrack=0;
908
909     /* specific to file-type init */
910
911         pos=0;
912         i=getnext(1);
913         switch(type)
914             {
915             case FILE_LUCAS:
916                 getnext(24);  //skip junk and get to the midi.
917                 adlib_style=LUCAS_STYLE|MIDI_STYLE;
918                 //note: no break, we go right into midi headers...
919             case FILE_MIDI:
920                 if (type != FILE_LUCAS)
921                     tins=128;
922                 getnext(11);  /*skip header*/
923                 deltas=getnext(2);
924                 midiprintf ("deltas:%ld\n",deltas);
925                 getnext(4);
926
927                 curtrack=0;
928                 track[curtrack].on=1;
929                 track[curtrack].tend=getnext(4);
930                 track[curtrack].spos=pos;
931                 midiprintf ("tracklen:%ld\n",track[curtrack].tend);
932                 break;
933             case FILE_CMF:
934                 getnext(3);  // ctmf
935                 getnexti(2); //version
936                 n=getnexti(2); // instrument offset
937                 m=getnexti(2); // music offset
938                 deltas=getnexti(2); //ticks/qtr note
939                 msqtr=1000000/getnexti(2)*deltas;
940                    //the stuff in the cmf is click ticks per second..
941
942                 i=getnexti(2);
943                                 if(i) title = (char *)data+i;
944                 i=getnexti(2);
945                                 if(i) author = (char *)data+i;
946                 i=getnexti(2);
947                                 if(i) remarks = (char *)data+i;
948
949                 getnext(16); // channel in use table ..
950                 i=getnexti(2); // num instr
951                 if (i>128) i=128; // to ward of bad numbers...
952                 getnexti(2); //basic tempo
953
954                 midiprintf("\nioff:%d\nmoff%d\ndeltas:%ld\nmsqtr:%ld\nnumi:%d\n",
955                     n,m,deltas,msqtr,i);
956                 pos=n;  // jump to instruments
957                 tins=i;
958                 for (j=0; j<i; j++)
959                     {
960                     midiprintf ("\n%d: ",j);
961                     for (l=0; l<16; l++)
962                         {
963                         myinsbank[j][l]=(unsigned char)getnext(1);
964                         midiprintf ("%2X ",myinsbank[j][l]);
965                         }
966                     }
967
968                 for (i=0; i<16; i++)
969                     ch[i].nshift=-13;
970
971                 adlib_style=CMF_STYLE;
972
973                 curtrack=0;
974                 track[curtrack].on=1;
975                 track[curtrack].tend=flen;  // music until the end of the file
976                 track[curtrack].spos=m;  //jump to midi music
977                 break;
978             case FILE_OLDLUCAS:
979                 msqtr=250000;
980                 pos=9;
981                 deltas=getnext(1);
982
983                 i=8;
984                 pos=0x19;  // jump to instruments
985                 tins=i;
986                 for (j=0; j<i; j++)
987                     {
988                     midiprintf ("\n%d: ",j);
989                     for (l=0; l<16; l++)
990                         ins[l]=(unsigned char)getnext(1);
991
992                     myinsbank[j][10]=ins[2];
993                     myinsbank[j][0]=ins[3];
994                     myinsbank[j][2]=ins[4];
995                     myinsbank[j][4]=ins[5];
996                     myinsbank[j][6]=ins[6];
997                     myinsbank[j][8]=ins[7];
998                     myinsbank[j][1]=ins[8];
999                     myinsbank[j][3]=ins[9];
1000                     myinsbank[j][5]=ins[10];
1001                     myinsbank[j][7]=ins[11];
1002                     myinsbank[j][9]=ins[12];
1003
1004                     for (l=0; l<11; l++)
1005                         midiprintf ("%2X ",myinsbank[j][l]);
1006                     }
1007
1008                 for (i=0; i<16; i++)
1009                     {
1010                     if (i<tins)
1011                         {
1012                         ch[i].inum=i;
1013                         for (j=0; j<11; j++)
1014                             ch[i].ins[j]=myinsbank[ch[i].inum][j];
1015                         }
1016                     }
1017
1018                 adlib_style=LUCAS_STYLE|MIDI_STYLE;
1019
1020                 curtrack=0;
1021                 track[curtrack].on=1;
1022                 track[curtrack].tend=flen;  // music until the end of the file
1023                 track[curtrack].spos=0x98;  //jump to midi music
1024                 break;
1025             case FILE_ADVSIERRA:
1026               memcpy(myinsbank, smyinsbank, 128 * 16);
1027               tins = stins;
1028                 deltas=0x20;
1029                 getnext(11); //worthless empty space and "stuff" :)
1030
1031                 o_sierra_pos=sierra_pos=pos;
1032                 sierra_next_section();
1033                 while (datalook(sierra_pos-2)!=0xff)
1034                     {
1035                     sierra_next_section();
1036                     subsongs++;
1037                     }
1038
1039                 if (subsong < 0 || subsong >= subsongs) subsong=0;
1040
1041                 sierra_pos=o_sierra_pos;
1042                 sierra_next_section();
1043                 i=0;
1044                 while (i != subsong)
1045                     {
1046                     sierra_next_section();
1047                     i++;
1048                     }
1049
1050                 adlib_style=SIERRA_STYLE|MIDI_STYLE;  //advanced sierra tunes use volume
1051                 break;
1052             case FILE_SIERRA:
1053               memcpy(myinsbank, smyinsbank, 128 * 16);
1054               tins = stins;
1055                 getnext(2);
1056                 deltas=0x20;
1057
1058                 curtrack=0;
1059                 track[curtrack].on=1;
1060                 track[curtrack].tend=flen;  // music until the end of the file
1061
1062                 for (i=0; i<16; i++)
1063                     {
1064                     ch[i].nshift=-13;
1065                     ch[i].on=getnext(1);
1066                     ch[i].inum=getnext(1);
1067                     for (j=0; j<11; j++)
1068                         ch[i].ins[j]=myinsbank[ch[i].inum][j];
1069                     }
1070
1071                 track[curtrack].spos=pos;
1072                 adlib_style=SIERRA_STYLE|MIDI_STYLE;
1073                 break;
1074             }
1075
1076
1077 /*        sprintf(info,"%s\r\nTicks/Quarter Note: %ld\r\n",info,deltas);
1078         sprintf(info,"%sms/Quarter Note: %ld",info,msqtr); */
1079
1080         for (i=0; i<16; i++)
1081             if (track[i].on)
1082                 {
1083                 track[i].pos=track[i].spos;
1084                 track[i].pv=0;
1085                 track[i].iwait=0;
1086                 }
1087
1088     doing=1;
1089     midi_fm_reset();
1090 }
1091
1092 std::string CmidPlayer::gettype()
1093 {
1094         switch(type) {
1095         case FILE_LUCAS:
1096                 return std::string("LucasArts AdLib MIDI");
1097         case FILE_MIDI:
1098                 return std::string("General MIDI");
1099         case FILE_CMF:
1100                 return std::string("Creative Music Format (CMF MIDI)");
1101         case FILE_OLDLUCAS:
1102                 return std::string("Lucasfilm Adlib MIDI");
1103         case FILE_ADVSIERRA:
1104                 return std::string("Sierra On-Line VGA MIDI");
1105         case FILE_SIERRA:
1106                 return std::string("Sierra On-Line EGA MIDI");
1107         default:
1108                 return std::string("MIDI unknown");
1109         }
1110 }