Mercurial > audlegacy-plugins
diff src/adplug/core/mid.cxx @ 955:4709ce4e209e trunk
[svn] Run indent -ts4 -nut -bli0 -cdw on this messy lot. Upstream is not consistent with whitespace anyway, no loss there.
| author | chainsaw |
|---|---|
| date | Sat, 14 Apr 2007 15:23:50 -0700 |
| parents | cae46214b8bf |
| children | b1128efde471 |
line wrap: on
line diff
--- a/src/adplug/core/mid.cxx Sat Apr 14 08:48:41 2007 -0700 +++ b/src/adplug/core/mid.cxx Sat Apr 14 15:23:50 2007 -0700 @@ -82,9 +82,10 @@ #ifdef TESTING #define midiprintf printf #else -void CmidPlayer::midiprintf(char *format, ...) - { - } +void +CmidPlayer::midiprintf (char *format, ...) +{ +} #endif #define LUCAS_STYLE 1 @@ -105,987 +106,1082 @@ #define FILE_OLDLUCAS 6 // AdLib standard operator table -const unsigned char CmidPlayer::adlib_opadd[] = {0x00 ,0x01 ,0x02 ,0x08 ,0x09 ,0x0A ,0x10 ,0x11 ,0x12}; +const unsigned char +CmidPlayer::adlib_opadd[] = + { 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12 }; // dunno -const int CmidPlayer::ops[] = {0x20,0x20,0x40,0x40,0x60,0x60,0x80,0x80,0xe0,0xe0,0xc0}; +const int +CmidPlayer::ops[] = + { 0x20, 0x20, 0x40, 0x40, 0x60, 0x60, 0x80, 0x80, 0xe0, 0xe0, 0xc0 }; // map CMF drum channels 12 - 15 to corresponding AdLib drum operators // bass drum (channel 11) not mapped, cause it's handled like a normal instrument -const int CmidPlayer::map_chan[] = { 0x14, 0x12, 0x15, 0x11 }; +const int +CmidPlayer::map_chan[] = { 0x14, 0x12, 0x15, 0x11 }; // Standard AdLib frequency table -const int CmidPlayer::fnums[] = { 0x16b,0x181,0x198,0x1b0,0x1ca,0x1e5,0x202,0x220,0x241,0x263,0x287,0x2ae }; +const int +CmidPlayer::fnums[] = + { 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x241, 0x263, +0x287, 0x2ae }; // Map CMF drum channels 11 - 15 to corresponding AdLib drum channels -const int CmidPlayer::percussion_map[] = { 6, 7, 8, 8, 7 }; +const int +CmidPlayer::percussion_map[] = { 6, 7, 8, 8, 7 }; -CPlayer *CmidPlayer::factory(Copl *newopl) +CPlayer * +CmidPlayer::factory (Copl * newopl) { - return new CmidPlayer(newopl); + return new CmidPlayer (newopl); } -CmidPlayer::CmidPlayer(Copl *newopl) - : CPlayer(newopl), author(&emptystr), title(&emptystr), remarks(&emptystr), - emptystr('\0'), flen(0), data(0) +CmidPlayer::CmidPlayer (Copl * newopl):CPlayer (newopl), author (&emptystr), title (&emptystr), remarks (&emptystr), +emptystr ('\0'), flen (0), data (0) { } -unsigned char CmidPlayer::datalook(long pos) +unsigned char +CmidPlayer::datalook (long pos) { - if (pos<0 || pos >= flen) return(0); - return(data[pos]); + if (pos < 0 || pos >= flen) + return (0); + return (data[pos]); } -unsigned long CmidPlayer::getnexti(unsigned long num) +unsigned long +CmidPlayer::getnexti (unsigned long num) { - unsigned long v=0; - unsigned long i; + unsigned long v = 0; + unsigned long i; - for (i=0; i<num; i++) - { - v+=(datalook(pos)<<(8*i)); pos++; - } - return(v); + for (i = 0; i < num; i++) + { + v += (datalook (pos) << (8 * i)); + pos++; + } + return (v); } -unsigned long CmidPlayer::getnext(unsigned long num) +unsigned long +CmidPlayer::getnext (unsigned long num) { - unsigned long v=0; - unsigned long i; + unsigned long v = 0; + unsigned long i; - for (i=0; i<num; i++) - { - v<<=8; - v+=datalook(pos); pos++; - } - return(v); + for (i = 0; i < num; i++) + { + v <<= 8; + v += datalook (pos); + pos++; + } + return (v); } -unsigned long CmidPlayer::getval() +unsigned long +CmidPlayer::getval () { - int v=0; - unsigned char b; + int v = 0; + unsigned char b; - b=(unsigned char)getnext(1); - v=b&0x7f; - while ((b&0x80) !=0) - { - b=(unsigned char)getnext(1); - v = (v << 7) + (b & 0x7F); - } - return(v); + b = (unsigned char) getnext (1); + v = b & 0x7f; + while ((b & 0x80) != 0) + { + b = (unsigned char) getnext (1); + v = (v << 7) + (b & 0x7F); + } + return (v); } -bool CmidPlayer::load_sierra_ins(const std::string &fname, const CFileProvider &fp) +bool +CmidPlayer::load_sierra_ins (const std::string & fname, + const CFileProvider & fp) { - long i,j,k,l; - unsigned char ins[28]; - char *pfilename; - binistream *f; + long i, j, k, l; + unsigned char ins[28]; + char *pfilename; + binistream *f; + + pfilename = (char *) malloc (fname.length () + 9); + strcpy (pfilename, fname.c_str ()); + j = 0; + for (i = strlen (pfilename) - 1; i >= 0; i--) + if (pfilename[i] == '/' || pfilename[i] == '\\') + { + j = i + 1; + break; + } + sprintf (pfilename + j + 3, "patch.003"); + + VFSFile *instfd = vfs_fopen (pfilename, "rb"); + f = fp.open (instfd); + free (pfilename); + if (!f) + { + vfs_fclose (instfd); + return false; + } + + f->ignore (2); + stins = 0; + for (i = 0; i < 2; i++) + { + for (k = 0; k < 48; k++) + { + l = i * 48 + k; + midiprintf ("\n%2d: ", l); + for (j = 0; j < 28; j++) + ins[j] = f->readInt (1); - pfilename = (char *)malloc(fname.length()+9); - strcpy(pfilename,fname.c_str()); - j=0; - for(i=strlen(pfilename)-1; i >= 0; i--) - if(pfilename[i] == '/' || pfilename[i] == '\\') { - j = i+1; - break; - } - sprintf(pfilename+j+3,"patch.003"); + myinsbank[l][0] = (ins[9] * 0x80) + (ins[10] * 0x40) + (ins[5] * 0x20) + (ins[11] * 0x10) + ins[1]; //1=ins5 + myinsbank[l][1] = (ins[22] * 0x80) + (ins[23] * 0x40) + (ins[18] * 0x20) + (ins[24] * 0x10) + ins[14]; //1=ins18 + + myinsbank[l][2] = (ins[0] << 6) + ins[8]; + myinsbank[l][3] = (ins[13] << 6) + ins[21]; + + myinsbank[l][4] = (ins[3] << 4) + ins[6]; + myinsbank[l][5] = (ins[16] << 4) + ins[19]; + myinsbank[l][6] = (ins[4] << 4) + ins[7]; + myinsbank[l][7] = (ins[17] << 4) + ins[20]; + + myinsbank[l][8] = ins[26]; + myinsbank[l][9] = ins[27]; + + myinsbank[l][10] = ((ins[2] << 1)) + (1 - (ins[12] & 1)); + //(ins[12] ? 0:1)+((ins[2]<<1)); - VFSFile *instfd = vfs_fopen(pfilename, "rb"); - f = fp.open(instfd); - free(pfilename); - if(!f) { vfs_fclose(instfd); return false; } + for (j = 0; j < 11; j++) + midiprintf ("%02X ", myinsbank[l][j]); + stins++; + } + f->ignore (2); + } - f->ignore(2); - stins = 0; - for (i=0; i<2; i++) - { - for (k=0; k<48; k++) - { - l=i*48+k; - midiprintf ("\n%2d: ",l); - for (j=0; j<28; j++) - ins[j] = f->readInt(1); + fp.close (f); + vfs_fclose (instfd); + memcpy (smyinsbank, myinsbank, 128 * 16); + return true; +} + +void +CmidPlayer::sierra_next_section () +{ + int i, j; + + for (i = 0; i < 16; i++) + track[i].on = 0; + + midiprintf ("\n\nnext adv sierra section:\n"); - myinsbank[l][0]= - (ins[9]*0x80) + (ins[10]*0x40) + - (ins[5]*0x20) + (ins[11]*0x10) + - ins[1]; //1=ins5 - myinsbank[l][1]= - (ins[22]*0x80) + (ins[23]*0x40) + - (ins[18]*0x20) + (ins[24]*0x10) + - ins[14]; //1=ins18 + pos = sierra_pos; + i = 0; + j = 0; + while (i != 0xff) + { + getnext (1); + curtrack = j; + j++; + track[curtrack].on = 1; + track[curtrack].spos = getnext (1); + track[curtrack].spos += (getnext (1) << 8) + 4; //4 best usually +3? not 0,1,2 or 5 +// track[curtrack].spos=getnext(1)+(getnext(1)<<8)+4; // dynamite!: doesn't optimize correctly!! + track[curtrack].tend = flen; //0xFC will kill it + track[curtrack].iwait = 0; + track[curtrack].pv = 0; + midiprintf ("track %d starts at %lx\n", curtrack, track[curtrack].spos); - myinsbank[l][2]=(ins[0]<<6)+ins[8]; - myinsbank[l][3]=(ins[13]<<6)+ins[21]; + getnext (2); + i = getnext (1); + } + getnext (2); + deltas = 0x20; + sierra_pos = pos; + //getch(); - myinsbank[l][4]=(ins[3]<<4)+ins[6]; - myinsbank[l][5]=(ins[16]<<4)+ins[19]; - myinsbank[l][6]=(ins[4]<<4)+ins[7]; - myinsbank[l][7]=(ins[17]<<4)+ins[20]; + fwait = 0; + doing = 1; +} + +bool +CmidPlayer::load (VFSFile * fd, const CFileProvider & fp) +{ + binistream *f = fp.open (fd); + if (!f) + return false; + int good; + unsigned char s[6]; + std::string filename (fd->uri); - myinsbank[l][8]=ins[26]; - myinsbank[l][9]=ins[27]; - - myinsbank[l][10]=((ins[2]<<1))+(1-(ins[12]&1)); - //(ins[12] ? 0:1)+((ins[2]<<1)); + f->readString ((char *) s, 6); + good = 0; + subsongs = 0; + switch (s[0]) + { + case 'A': + if (s[1] == 'D' && s[2] == 'L') + good = FILE_LUCAS; + break; + case 'C': + if (s[1] == 'T' && s[2] == 'M' && s[3] == 'F') + good = FILE_CMF; + break; + case 0x84: + if (s[1] == 0x00 && load_sierra_ins (filename, fp)) + if (s[2] == 0xf0) + good = FILE_ADVSIERRA; + else + good = FILE_SIERRA; + break; + default: + if (s[4] == 'A' && s[5] == 'D') + good = FILE_OLDLUCAS; + break; + } - for (j=0; j<11; j++) - midiprintf ("%02X ",myinsbank[l][j]); - stins++; - } - f->ignore(2); - } + if (good != 0) + subsongs = 1; + else + { + fp.close (f); + return false; + } - fp.close(f); - vfs_fclose(instfd); - memcpy(smyinsbank, myinsbank, 128 * 16); - return true; + type = good; + f->seek (0); + flen = fp.filesize (f); + data = new unsigned char[flen]; + f->readString ((char *) data, flen); + + fp.close (f); + rewind (0); + return true; +} + +void +CmidPlayer::midi_write_adlib (unsigned int r, unsigned char v) +{ + opl->write (r, v); + adlib_data[r] = v; } -void CmidPlayer::sierra_next_section() +void +CmidPlayer::midi_fm_instrument (int voice, unsigned char *inst) { - int i,j; + if ((adlib_style & SIERRA_STYLE) != 0) + midi_write_adlib (0xbd, 0); //just gotta make sure this happens.. + //'cause who knows when it'll be + //reset otherwise. + + + midi_write_adlib (0x20 + adlib_opadd[voice], inst[0]); + midi_write_adlib (0x23 + adlib_opadd[voice], inst[1]); - for (i=0; i<16; i++) - track[i].on=0; + if ((adlib_style & LUCAS_STYLE) != 0) + { + midi_write_adlib (0x43 + adlib_opadd[voice], 0x3f); + if ((inst[10] & 1) == 0) + midi_write_adlib (0x40 + adlib_opadd[voice], inst[2]); + else + midi_write_adlib (0x40 + adlib_opadd[voice], 0x3f); + } + else + { + if ((adlib_style & SIERRA_STYLE) != 0) + { + midi_write_adlib (0x40 + adlib_opadd[voice], inst[2]); + midi_write_adlib (0x43 + adlib_opadd[voice], inst[3]); + } + else + { + midi_write_adlib (0x40 + adlib_opadd[voice], inst[2]); + if ((inst[10] & 1) == 0) + midi_write_adlib (0x43 + adlib_opadd[voice], inst[3]); + else + midi_write_adlib (0x43 + adlib_opadd[voice], 0); + } + } - midiprintf("\n\nnext adv sierra section:\n"); + midi_write_adlib (0x60 + adlib_opadd[voice], inst[4]); + midi_write_adlib (0x63 + adlib_opadd[voice], inst[5]); + midi_write_adlib (0x80 + adlib_opadd[voice], inst[6]); + midi_write_adlib (0x83 + adlib_opadd[voice], inst[7]); + midi_write_adlib (0xe0 + adlib_opadd[voice], inst[8]); + midi_write_adlib (0xe3 + adlib_opadd[voice], inst[9]); + + midi_write_adlib (0xc0 + voice, inst[10]); +} + +void +CmidPlayer::midi_fm_percussion (int ch, unsigned char *inst) +{ + int opadd = map_chan[ch - 12]; + + midi_write_adlib (0x20 + opadd, inst[0]); + midi_write_adlib (0x40 + opadd, inst[2]); + midi_write_adlib (0x60 + opadd, inst[4]); + midi_write_adlib (0x80 + opadd, inst[6]); + midi_write_adlib (0xe0 + opadd, inst[8]); + midi_write_adlib (0xc0 + opadd, inst[10]); +} + +void +CmidPlayer::midi_fm_volume (int voice, int volume) +{ + int vol; + + if ((adlib_style & SIERRA_STYLE) == 0) //sierra likes it loud! + { + vol = volume >> 2; - pos=sierra_pos; - i=0;j=0; - while (i!=0xff) - { - getnext(1); - curtrack=j; j++; - track[curtrack].on=1; - track[curtrack].spos = getnext(1); - track[curtrack].spos += (getnext(1) << 8) + 4; //4 best usually +3? not 0,1,2 or 5 -// track[curtrack].spos=getnext(1)+(getnext(1)<<8)+4; // dynamite!: doesn't optimize correctly!! - track[curtrack].tend=flen; //0xFC will kill it - track[curtrack].iwait=0; - track[curtrack].pv=0; - midiprintf ("track %d starts at %lx\n",curtrack,track[curtrack].spos); + if ((adlib_style & LUCAS_STYLE) != 0) + { + if ((adlib_data[0xc0 + voice] & 1) == 1) + midi_write_adlib (0x40 + adlib_opadd[voice], + (unsigned char) ((63 - vol) | + (adlib_data + [0x40 + + adlib_opadd[voice]] & 0xc0))); + midi_write_adlib (0x43 + adlib_opadd[voice], + (unsigned char) ((63 - vol) | + (adlib_data + [0x43 + + adlib_opadd[voice]] & 0xc0))); + } + else + { + if ((adlib_data[0xc0 + voice] & 1) == 1) + midi_write_adlib (0x40 + adlib_opadd[voice], + (unsigned char) ((63 - vol) | + (adlib_data + [0x40 + + adlib_opadd[voice]] & 0xc0))); + midi_write_adlib (0x43 + adlib_opadd[voice], + (unsigned char) ((63 - vol) | + (adlib_data + [0x43 + + adlib_opadd[voice]] & 0xc0))); + } + } +} - getnext(2); - i=getnext(1); - } - getnext(2); - deltas=0x20; - sierra_pos=pos; - //getch(); +void +CmidPlayer::midi_fm_playnote (int voice, int note, int volume) +{ + int freq = fnums[note % 12]; + int oct = note / 12; + int c; + + midi_fm_volume (voice, volume); + midi_write_adlib (0xa0 + voice, (unsigned char) (freq & 0xff)); + + c = ((freq & 0x300) >> 8) + (oct << 2) + (adlib_mode == ADLIB_MELODIC + || voice < 6 ? (1 << 5) : 0); + midi_write_adlib (0xb0 + voice, (unsigned char) c); +} - fwait=0; - doing=1; +void +CmidPlayer::midi_fm_endnote (int voice) +{ + //midi_fm_volume(voice,0); + //midi_write_adlib(0xb0+voice,0); + + midi_write_adlib (0xb0 + voice, + (unsigned char) (adlib_data[0xb0 + voice] & (255 - 32))); +} + +void +CmidPlayer::midi_fm_reset () +{ + int i; + + opl->init (); + + for (i = 0; i < 256; i++) + midi_write_adlib (i, 0); + + midi_write_adlib (0x01, 0x20); + midi_write_adlib (0xBD, 0xc0); } -bool CmidPlayer::load(VFSFile *fd, const CFileProvider &fp) +bool +CmidPlayer::update () { - binistream *f = fp.open(fd); if(!f) return false; - int good; - unsigned char s[6]; - std::string filename(fd->uri); + long w, v, note, vel, ctrl, nv, x, l, lnum; + int i = 0, j, c; + int on, onl, numchan; + int ret; - f->readString((char *)s, 6); - good=0; - subsongs=0; - switch(s[0]) + if (doing == 1) + { + // just get the first wait and ignore it :> + for (curtrack = 0; curtrack < 16; curtrack++) + if (track[curtrack].on) + { + pos = track[curtrack].pos; + if (type != FILE_SIERRA && type != FILE_ADVSIERRA) + track[curtrack].iwait += getval (); + else + track[curtrack].iwait += getnext (1); + track[curtrack].pos = pos; + } + doing = 0; + } + + iwait = 0; + ret = 1; + + while (iwait == 0 && ret == 1) + { + for (curtrack = 0; curtrack < 16; curtrack++) + if (track[curtrack].on && track[curtrack].iwait == 0 && + track[curtrack].pos < track[curtrack].tend) + { + pos = track[curtrack].pos; + + v = getnext (1); + + // This is to do implied MIDI events. + if (v < 0x80) { - case 'A': - if (s[1]=='D' && s[2]=='L') good=FILE_LUCAS; - break; - case 'C': - if (s[1]=='T' && s[2]=='M' && s[3]=='F') good=FILE_CMF; - break; - case 0x84: - if (s[1]==0x00 && load_sierra_ins(filename, fp)) - if (s[2]==0xf0) - good=FILE_ADVSIERRA; - else - good=FILE_SIERRA; - break; - default: - if (s[4]=='A' && s[5]=='D') good=FILE_OLDLUCAS; - break; + v = track[curtrack].pv; + pos--; } + track[curtrack].pv = (unsigned char) v; - if (good!=0) - subsongs=1; - else { - fp.close(f); - return false; - } + c = v & 0x0f; + midiprintf ("[%2X]", v); + switch (v & 0xf0) + { + case 0x80: /*note off */ + note = getnext (1); + vel = getnext (1); + for (i = 0; i < 9; i++) + if (chp[i][0] == c && chp[i][1] == note) + { + midi_fm_endnote (i); + chp[i][0] = -1; + } + break; + case 0x90: /*note on */ + // doing=0; + note = getnext (1); + vel = getnext (1); + + if (adlib_mode == ADLIB_RYTHM) + numchan = 6; + else + numchan = 9; - type=good; - f->seek(0); - flen = fp.filesize(f); - data = new unsigned char [flen]; - f->readString((char *)data, flen); + if (ch[c].on != 0) + { + for (i = 0; i < 18; i++) + chp[i][2]++; - fp.close(f); - rewind(0); - return true; -} + if (c < 11 || adlib_mode == ADLIB_MELODIC) + { + j = 0; + on = -1; + onl = 0; + for (i = 0; i < numchan; i++) + if (chp[i][0] == -1 && chp[i][2] > onl) + { + onl = chp[i][2]; + on = i; + j = 1; + } -void CmidPlayer::midi_write_adlib(unsigned int r, unsigned char v) -{ - opl->write(r,v); - adlib_data[r]=v; -} + if (on == -1) + { + onl = 0; + for (i = 0; i < numchan; i++) + if (chp[i][2] > onl) + { + onl = chp[i][2]; + on = i; + } + } + + if (j == 0) + midi_fm_endnote (on); + } + else + on = percussion_map[c - 11]; -void CmidPlayer::midi_fm_instrument(int voice, unsigned char *inst) -{ - if ((adlib_style&SIERRA_STYLE)!=0) - midi_write_adlib(0xbd,0); //just gotta make sure this happens.. - //'cause who knows when it'll be - //reset otherwise. - - - midi_write_adlib(0x20+adlib_opadd[voice],inst[0]); - midi_write_adlib(0x23+adlib_opadd[voice],inst[1]); + if (vel != 0 && ch[c].inum >= 0 && ch[c].inum < 128) + { + if (adlib_mode == ADLIB_MELODIC || c < 12) + midi_fm_instrument (on, ch[c].ins); + else + midi_fm_percussion (c, ch[c].ins); - if ((adlib_style&LUCAS_STYLE)!=0) - { - midi_write_adlib(0x43+adlib_opadd[voice],0x3f); - if ((inst[10] & 1)==0) - midi_write_adlib(0x40+adlib_opadd[voice],inst[2]); - else - midi_write_adlib(0x40+adlib_opadd[voice],0x3f); - } - else - { - if ((adlib_style&SIERRA_STYLE)!=0) - { - midi_write_adlib(0x40+adlib_opadd[voice],inst[2]); - midi_write_adlib(0x43+adlib_opadd[voice],inst[3]); + if ((adlib_style & MIDI_STYLE) != 0) + { + nv = ((ch[c].vol * vel) / 128); + if ((adlib_style & LUCAS_STYLE) != 0) + nv *= 2; + if (nv > 127) + nv = 127; + nv = my_midi_fm_vol_table[nv]; + if ((adlib_style & LUCAS_STYLE) != 0) + nv = (int) ((float) sqrt ((float) nv) * 11); + } + else + { + nv = vel; + } + + midi_fm_playnote (on, note + ch[c].nshift, nv * 2); + chp[on][0] = c; + chp[on][1] = note; + chp[on][2] = 0; + + if (adlib_mode == ADLIB_RYTHM && c >= 11) + { + midi_write_adlib (0xbd, + adlib_data[0xbd] & ~(0x10 >> (c - 11))); + midi_write_adlib (0xbd, + adlib_data[0xbd] | (0x10 >> (c - 11))); + } + } else { - midi_write_adlib(0x40+adlib_opadd[voice],inst[2]); - if ((inst[10] & 1)==0) - midi_write_adlib(0x43+adlib_opadd[voice],inst[3]); - else - midi_write_adlib(0x43+adlib_opadd[voice],0); + if (vel == 0) //same code as end note + { + for (i = 0; i < 9; i++) + if (chp[i][0] == c && chp[i][1] == note) + { + // midi_fm_volume(i,0); // really end the note + midi_fm_endnote (i); + chp[i][0] = -1; + } + } + else + { // i forget what this is for. + chp[on][0] = -1; + chp[on][2] = 0; + } } - } + midiprintf (" [%d:%d:%d:%d]\n", c, ch[c].inum, note, vel); + } + else + midiprintf ("off"); + break; + case 0xa0: /*key after touch */ + note = getnext (1); + vel = getnext (1); + /* //this might all be good + for (i=0; i<9; i++) + if (chp[i][0]==c & chp[i][1]==note) - midi_write_adlib(0x60+adlib_opadd[voice],inst[4]); - midi_write_adlib(0x63+adlib_opadd[voice],inst[5]); - midi_write_adlib(0x80+adlib_opadd[voice],inst[6]); - midi_write_adlib(0x83+adlib_opadd[voice],inst[7]); - midi_write_adlib(0xe0+adlib_opadd[voice],inst[8]); - midi_write_adlib(0xe3+adlib_opadd[voice],inst[9]); - - midi_write_adlib(0xc0+voice,inst[10]); -} + midi_fm_playnote(i,note+cnote[c],my_midi_fm_vol_table[(cvols[c]*vel)/128]*2); + */ + break; + case 0xb0: /*control change .. pitch bend? */ + ctrl = getnext (1); + vel = getnext (1); -void CmidPlayer::midi_fm_percussion(int ch, unsigned char *inst) -{ - int opadd = map_chan[ch - 12]; + switch (ctrl) + { + case 0x07: + midiprintf ("(pb:%d: %d %d)", c, ctrl, vel); + ch[c].vol = vel; + midiprintf ("vol"); + break; + case 0x67: + midiprintf ("\n\nhere:%d\n\n", vel); + if ((adlib_style & CMF_STYLE) != 0) + { + adlib_mode = vel; + if (adlib_mode == ADLIB_RYTHM) + midi_write_adlib (0xbd, adlib_data[0xbd] | (1 << 5)); + else + midi_write_adlib (0xbd, adlib_data[0xbd] & ~(1 << 5)); + } + break; + } + break; + case 0xc0: /*patch change */ + x = getnext (1); + ch[c].inum = x; + for (j = 0; j < 11; j++) + ch[c].ins[j] = myinsbank[ch[c].inum][j]; + break; + case 0xd0: /*chanel touch */ + x = getnext (1); + break; + case 0xe0: /*pitch wheel */ + x = getnext (1); + x = getnext (1); + break; + case 0xf0: + switch (v) + { + case 0xf0: + case 0xf7: /*sysex */ + l = getval (); + if (datalook (pos + l) == 0xf7) + i = 1; + midiprintf ("{%d}", l); + midiprintf ("\n"); - midi_write_adlib(0x20 + opadd, inst[0]); - midi_write_adlib(0x40 + opadd, inst[2]); - midi_write_adlib(0x60 + opadd, inst[4]); - midi_write_adlib(0x80 + opadd, inst[6]); - midi_write_adlib(0xe0 + opadd, inst[8]); - midi_write_adlib(0xc0 + opadd, inst[10]); -} - -void CmidPlayer::midi_fm_volume(int voice, int volume) -{ - int vol; - - if ((adlib_style&SIERRA_STYLE)==0) //sierra likes it loud! - { - vol=volume>>2; + if (datalook (pos) == 0x7d && + datalook (pos + 1) == 0x10 && datalook (pos + 2) < 16) + { + adlib_style = LUCAS_STYLE | MIDI_STYLE; + for (i = 0; i < l; i++) + { + midiprintf ("%x ", datalook (pos + i)); + if ((i - 3) % 10 == 0) + midiprintf ("\n"); + } + midiprintf ("\n"); + getnext (1); + getnext (1); + c = getnext (1); + getnext (1); - if ((adlib_style&LUCAS_STYLE)!=0) - { - if ((adlib_data[0xc0+voice]&1)==1) - midi_write_adlib(0x40+adlib_opadd[voice], (unsigned char)((63-vol) | - (adlib_data[0x40+adlib_opadd[voice]]&0xc0))); - midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) | - (adlib_data[0x43+adlib_opadd[voice]]&0xc0))); - } - else - { - if ((adlib_data[0xc0+voice]&1)==1) - midi_write_adlib(0x40+adlib_opadd[voice], (unsigned char)((63-vol) | - (adlib_data[0x40+adlib_opadd[voice]]&0xc0))); - midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) | - (adlib_data[0x43+adlib_opadd[voice]]&0xc0))); - } - } -} + // getnext(22); //temp + ch[c].ins[0] = + (unsigned char) ((getnext (1) << 4) + getnext (1)); + ch[c].ins[2] = + (unsigned char) (0xff - + (((getnext (1) << 4) + getnext (1)) & 0x3f)); + ch[c].ins[4] = + (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1))); + ch[c].ins[6] = + (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1))); + ch[c].ins[8] = + (unsigned char) ((getnext (1) << 4) + getnext (1)); -void CmidPlayer::midi_fm_playnote(int voice, int note, int volume) -{ - int freq=fnums[note%12]; - int oct=note/12; - int c; - - midi_fm_volume(voice,volume); - midi_write_adlib(0xa0+voice,(unsigned char)(freq&0xff)); + ch[c].ins[1] = + (unsigned char) ((getnext (1) << 4) + getnext (1)); + ch[c].ins[3] = + (unsigned char) (0xff - + (((getnext (1) << 4) + getnext (1)) & 0x3f)); + ch[c].ins[5] = + (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1))); + ch[c].ins[7] = + (unsigned char) (0xff - ((getnext (1) << 4) + getnext (1))); + ch[c].ins[9] = + (unsigned char) ((getnext (1) << 4) + getnext (1)); - c=((freq&0x300) >> 8)+(oct<<2) + (adlib_mode == ADLIB_MELODIC || voice < 6 ? (1<<5) : 0); - midi_write_adlib(0xb0+voice,(unsigned char)c); -} + i = (getnext (1) << 4) + getnext (1); + ch[c].ins[10] = i; + + //if ((i&1)==1) ch[c].ins[10]=1; -void CmidPlayer::midi_fm_endnote(int voice) -{ - //midi_fm_volume(voice,0); - //midi_write_adlib(0xb0+voice,0); + midiprintf ("\n%d: ", c); + for (i = 0; i < 11; i++) + midiprintf ("%2X ", ch[c].ins[i]); + getnext (l - 26); + } + else + { + midiprintf ("\n"); + for (j = 0; j < l; j++) + midiprintf ("%2X ", getnext (1)); + } - midi_write_adlib(0xb0+voice,(unsigned char)(adlib_data[0xb0+voice]&(255-32))); -} - -void CmidPlayer::midi_fm_reset() -{ - int i; - - opl->init(); - - for (i=0; i<256; i++) - midi_write_adlib(i,0); - - midi_write_adlib(0x01, 0x20); - midi_write_adlib(0xBD,0xc0); -} - -bool CmidPlayer::update() -{ - long w,v,note,vel,ctrl,nv,x,l,lnum; - int i=0,j,c; - int on,onl,numchan; - int ret; - - if (doing == 1) - { - // just get the first wait and ignore it :> - for (curtrack=0; curtrack<16; curtrack++) - if (track[curtrack].on) - { - pos=track[curtrack].pos; - if (type != FILE_SIERRA && type !=FILE_ADVSIERRA) - track[curtrack].iwait+=getval(); - else - track[curtrack].iwait+=getnext(1); - track[curtrack].pos=pos; - } - doing=0; + midiprintf ("\n"); + if (i == 1) + getnext (1); + break; + case 0xf1: + break; + case 0xf2: + getnext (2); + break; + case 0xf3: + getnext (1); + break; + case 0xf4: + break; + case 0xf5: + break; + case 0xf6: /*something */ + case 0xf8: + case 0xfa: + case 0xfb: + case 0xfc: + //this ends the track for sierra. + if (type == FILE_SIERRA || type == FILE_ADVSIERRA) + { + track[curtrack].tend = pos; + midiprintf ("endmark: %ld -- %lx\n", pos, pos); + } + break; + case 0xfe: + break; + case 0xfd: + break; + case 0xff: + v = getnext (1); + l = getval (); + midiprintf ("\n"); + midiprintf ("{%X_%X}", v, l); + if (v == 0x51) + { + lnum = getnext (l); + msqtr = lnum; /*set tempo */ + midiprintf ("(qtr=%ld)", msqtr); + } + else + { + for (i = 0; i < l; i++) + midiprintf ("%2X ", getnext (1)); + } + break; + } + break; + default: + midiprintf ("!", v); /* if we get down here, a error occurred */ + break; } - iwait=0; - ret=1; - - while (iwait==0 && ret==1) - { - for (curtrack=0; curtrack<16; curtrack++) - if (track[curtrack].on && track[curtrack].iwait==0 && - track[curtrack].pos < track[curtrack].tend) + if (pos < track[curtrack].tend) { - pos=track[curtrack].pos; - - v=getnext(1); - - // This is to do implied MIDI events. - if (v<0x80) {v=track[curtrack].pv; pos--;} - track[curtrack].pv=(unsigned char)v; - - c=v&0x0f; - midiprintf ("[%2X]",v); - switch(v&0xf0) - { - case 0x80: /*note off*/ - note=getnext(1); vel=getnext(1); - for (i=0; i<9; i++) - if (chp[i][0]==c && chp[i][1]==note) - { - midi_fm_endnote(i); - chp[i][0]=-1; - } - break; - case 0x90: /*note on*/ - // doing=0; - note=getnext(1); vel=getnext(1); - - if(adlib_mode == ADLIB_RYTHM) - numchan = 6; - else - numchan = 9; - - if (ch[c].on!=0) - { - for (i=0; i<18; i++) - chp[i][2]++; - - if(c < 11 || adlib_mode == ADLIB_MELODIC) { - j=0; - on=-1;onl=0; - for (i=0; i<numchan; i++) - if (chp[i][0]==-1 && chp[i][2]>onl) - { onl=chp[i][2]; on=i; j=1; } - - if (on==-1) - { - onl=0; - for (i=0; i<numchan; i++) - if (chp[i][2]>onl) - { onl=chp[i][2]; on=i; } - } - - if (j==0) - midi_fm_endnote(on); - } else - on = percussion_map[c - 11]; + if (type != FILE_SIERRA && type != FILE_ADVSIERRA) + w = getval (); + else + w = getnext (1); + track[curtrack].iwait = w; + /* + if (w!=0) + { + midiprintf("\n<%d>",w); + f = + ((float)w/(float)deltas)*((float)msqtr/(float)1000000); + if (doing==1) f=0; //not playing yet. don't wait yet + } + */ + } + else + track[curtrack].iwait = 0; - if (vel!=0 && ch[c].inum>=0 && ch[c].inum<128) - { - if (adlib_mode == ADLIB_MELODIC || c < 12) - midi_fm_instrument(on,ch[c].ins); - else - midi_fm_percussion(c, ch[c].ins); - - if ((adlib_style&MIDI_STYLE)!=0) - { - nv=((ch[c].vol*vel)/128); - if ((adlib_style&LUCAS_STYLE)!=0) - nv*=2; - if (nv>127) nv=127; - nv=my_midi_fm_vol_table[nv]; - if ((adlib_style&LUCAS_STYLE)!=0) - nv=(int)((float)sqrt((float)nv)*11); - } - else - { - nv=vel; - } - - midi_fm_playnote(on,note+ch[c].nshift,nv*2); - chp[on][0]=c; - chp[on][1]=note; - chp[on][2]=0; - - if(adlib_mode == ADLIB_RYTHM && c >= 11) { - midi_write_adlib(0xbd, adlib_data[0xbd] & ~(0x10 >> (c - 11))); - midi_write_adlib(0xbd, adlib_data[0xbd] | (0x10 >> (c - 11))); - } + track[curtrack].pos = pos; + } - } - else - { - if (vel==0) //same code as end note - { - for (i=0; i<9; i++) - if (chp[i][0]==c && chp[i][1]==note) - { - // midi_fm_volume(i,0); // really end the note - midi_fm_endnote(i); - chp[i][0]=-1; - } - } - else - { // i forget what this is for. - chp[on][0]=-1; - chp[on][2]=0; - } - } - midiprintf(" [%d:%d:%d:%d]\n",c,ch[c].inum,note,vel); - } - else - midiprintf ("off"); - break; - case 0xa0: /*key after touch */ - note=getnext(1); vel=getnext(1); - /* //this might all be good - for (i=0; i<9; i++) - if (chp[i][0]==c & chp[i][1]==note) - -midi_fm_playnote(i,note+cnote[c],my_midi_fm_vol_table[(cvols[c]*vel)/128]*2); - */ - break; - case 0xb0: /*control change .. pitch bend? */ - ctrl=getnext(1); vel=getnext(1); - switch(ctrl) - { - case 0x07: - midiprintf ("(pb:%d: %d %d)",c,ctrl,vel); - ch[c].vol=vel; - midiprintf("vol"); - break; - case 0x67: - midiprintf ("\n\nhere:%d\n\n",vel); - if ((adlib_style&CMF_STYLE)!=0) { - adlib_mode=vel; - if(adlib_mode == ADLIB_RYTHM) - midi_write_adlib(0xbd, adlib_data[0xbd] | (1 << 5)); - else - midi_write_adlib(0xbd, adlib_data[0xbd] & ~(1 << 5)); - } - break; - } - break; - case 0xc0: /*patch change*/ - x=getnext(1); - ch[c].inum=x; - for (j=0; j<11; j++) - ch[c].ins[j]=myinsbank[ch[c].inum][j]; - break; - case 0xd0: /*chanel touch*/ - x=getnext(1); - break; - case 0xe0: /*pitch wheel*/ - x=getnext(1); - x=getnext(1); - break; - case 0xf0: - switch(v) - { - case 0xf0: - case 0xf7: /*sysex*/ - l=getval(); - if (datalook(pos+l)==0xf7) - i=1; - midiprintf("{%d}",l); - midiprintf("\n"); - - if (datalook(pos)==0x7d && - datalook(pos+1)==0x10 && - datalook(pos+2)<16) - { - adlib_style=LUCAS_STYLE|MIDI_STYLE; - for (i=0; i<l; i++) - { - midiprintf ("%x ",datalook(pos+i)); - if ((i-3)%10 == 0) midiprintf("\n"); - } - midiprintf ("\n"); - getnext(1); - getnext(1); - c=getnext(1); - getnext(1); - - // getnext(22); //temp - ch[c].ins[0]=(unsigned char)((getnext(1)<<4)+getnext(1)); - ch[c].ins[2]=(unsigned char)(0xff-(((getnext(1)<<4)+getnext(1))&0x3f)); - ch[c].ins[4]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1))); - ch[c].ins[6]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1))); - ch[c].ins[8]=(unsigned char)((getnext(1)<<4)+getnext(1)); - - ch[c].ins[1]=(unsigned char)((getnext(1)<<4)+getnext(1)); - ch[c].ins[3]=(unsigned char)(0xff-(((getnext(1)<<4)+getnext(1))&0x3f)); - ch[c].ins[5]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1))); - ch[c].ins[7]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1))); - ch[c].ins[9]=(unsigned char)((getnext(1)<<4)+getnext(1)); - - i=(getnext(1)<<4)+getnext(1); - ch[c].ins[10]=i; - - //if ((i&1)==1) ch[c].ins[10]=1; + ret = 0; //end of song. + iwait = 0; + for (curtrack = 0; curtrack < 16; curtrack++) + if (track[curtrack].on == 1 && + track[curtrack].pos < track[curtrack].tend) + ret = 1; //not yet.. - midiprintf ("\n%d: ",c); - for (i=0; i<11; i++) - midiprintf ("%2X ",ch[c].ins[i]); - getnext(l-26); - } - else - { - midiprintf("\n"); - for (j=0; j<l; j++) - midiprintf ("%2X ",getnext(1)); - } + if (ret == 1) + { + iwait = 0xffffff; // bigger than any wait can be! + for (curtrack = 0; curtrack < 16; curtrack++) + if (track[curtrack].on == 1 && + track[curtrack].pos < track[curtrack].tend && + track[curtrack].iwait < iwait) + iwait = track[curtrack].iwait; + } + } - midiprintf("\n"); - if(i==1) - getnext(1); - break; - case 0xf1: - break; - case 0xf2: - getnext(2); - break; - case 0xf3: - getnext(1); - break; - case 0xf4: - break; - case 0xf5: - break; - case 0xf6: /*something*/ - case 0xf8: - case 0xfa: - case 0xfb: - case 0xfc: - //this ends the track for sierra. - if (type == FILE_SIERRA || - type == FILE_ADVSIERRA) - { - track[curtrack].tend=pos; - midiprintf ("endmark: %ld -- %lx\n",pos,pos); - } - break; - case 0xfe: - break; - case 0xfd: - break; - case 0xff: - v=getnext(1); - l=getval(); - midiprintf ("\n"); - midiprintf("{%X_%X}",v,l); - if (v==0x51) - { - lnum=getnext(l); - msqtr=lnum; /*set tempo*/ - midiprintf ("(qtr=%ld)",msqtr); - } - else - { - for (i=0; i<l; i++) - midiprintf ("%2X ",getnext(1)); - } - break; - } - break; - default: midiprintf("!",v); /* if we get down here, a error occurred */ - break; - } - if (pos < track[curtrack].tend) - { - if (type != FILE_SIERRA && type !=FILE_ADVSIERRA) - w=getval(); - else - w=getnext(1); - track[curtrack].iwait=w; - /* - if (w!=0) - { - midiprintf("\n<%d>",w); - f = -((float)w/(float)deltas)*((float)msqtr/(float)1000000); - if (doing==1) f=0; //not playing yet. don't wait yet - } - */ - } - else - track[curtrack].iwait=0; - - track[curtrack].pos=pos; - } + if (iwait != 0 && ret == 1) + { + for (curtrack = 0; curtrack < 16; curtrack++) + if (track[curtrack].on) + track[curtrack].iwait -= iwait; - ret=0; //end of song. - iwait=0; - for (curtrack=0; curtrack<16; curtrack++) - if (track[curtrack].on == 1 && - track[curtrack].pos < track[curtrack].tend) - ret=1; //not yet.. + fwait = + 1.0f / (((float) iwait / (float) deltas) * + ((float) msqtr / (float) 1000000)); + } + else + fwait = 50; // 1/50th of a second - if (ret==1) - { - iwait=0xffffff; // bigger than any wait can be! - for (curtrack=0; curtrack<16; curtrack++) - if (track[curtrack].on == 1 && - track[curtrack].pos < track[curtrack].tend && - track[curtrack].iwait < iwait) - iwait=track[curtrack].iwait; - } - } - - - if (iwait !=0 && ret==1) - { - for (curtrack=0; curtrack<16; curtrack++) - if (track[curtrack].on) - track[curtrack].iwait-=iwait; + midiprintf ("\n"); + for (i = 0; i < 16; i++) + if (track[i].on) + if (track[i].pos < track[i].tend) + midiprintf ("<%d>", track[i].iwait); + else + midiprintf ("stop"); - -fwait=1.0f/(((float)iwait/(float)deltas)*((float)msqtr/(float)1000000)); - } - else - fwait=50; // 1/50th of a second - - midiprintf ("\n"); - for (i=0; i<16; i++) - if (track[i].on) - if (track[i].pos < track[i].tend) - midiprintf ("<%d>",track[i].iwait); - else - midiprintf("stop"); + /* + if (ret==0 && type==FILE_ADVSIERRA) + if (datalook(sierra_pos-2)!=0xff) + { + midiprintf ("next sectoin!"); + sierra_next_section(p); + fwait=50; + ret=1; + } + */ - /* - if (ret==0 && type==FILE_ADVSIERRA) - if (datalook(sierra_pos-2)!=0xff) - { - midiprintf ("next sectoin!"); - sierra_next_section(p); - fwait=50; - ret=1; - } - */ - - if(ret) - return true; - else - return false; + if (ret) + return true; + else + return false; } -float CmidPlayer::getrefresh() +float +CmidPlayer::getrefresh () { - return (fwait > 0.01f ? fwait : 0.01f); + return (fwait > 0.01f ? fwait : 0.01f); } -void CmidPlayer::rewind(int subsong) +void +CmidPlayer::rewind (int subsong) { - long i,j,n,m,l; - long o_sierra_pos; - unsigned char ins[16]; + long i, j, n, m, l; + long o_sierra_pos; + unsigned char ins[16]; - pos=0; tins=0; - adlib_style=MIDI_STYLE|CMF_STYLE; - adlib_mode=ADLIB_MELODIC; - for (i=0; i<128; i++) - for (j=0; j<16; j++) - myinsbank[i][j]=midi_fm_instruments[i][j]; - for (i=0; i<16; i++) - { - ch[i].inum=0; - for (j=0; j<11; j++) - ch[i].ins[j]=myinsbank[ch[i].inum][j]; - ch[i].vol=127; - ch[i].nshift=-25; - ch[i].on=1; - } + pos = 0; + tins = 0; + adlib_style = MIDI_STYLE | CMF_STYLE; + adlib_mode = ADLIB_MELODIC; + for (i = 0; i < 128; i++) + for (j = 0; j < 16; j++) + myinsbank[i][j] = midi_fm_instruments[i][j]; + for (i = 0; i < 16; i++) + { + ch[i].inum = 0; + for (j = 0; j < 11; j++) + ch[i].ins[j] = myinsbank[ch[i].inum][j]; + ch[i].vol = 127; + ch[i].nshift = -25; + ch[i].on = 1; + } - /* General init */ - for (i=0; i<9; i++) - { - chp[i][0]=-1; - chp[i][2]=0; - } + /* General init */ + for (i = 0; i < 9; i++) + { + chp[i][0] = -1; + chp[i][2] = 0; + } - deltas=250; // just a number, not a standard - msqtr=500000; - fwait=123; // gotta be a small thing.. sorta like nothing - iwait=0; + deltas = 250; // just a number, not a standard + msqtr = 500000; + fwait = 123; // gotta be a small thing.. sorta like nothing + iwait = 0; - subsongs=1; + subsongs = 1; - for (i=0; i<16; i++) - { - track[i].tend=0; - track[i].spos=0; - track[i].pos=0; - track[i].iwait=0; - track[i].on=0; - track[i].pv=0; - } - curtrack=0; - - /* specific to file-type init */ + for (i = 0; i < 16; i++) + { + track[i].tend = 0; + track[i].spos = 0; + track[i].pos = 0; + track[i].iwait = 0; + track[i].on = 0; + track[i].pv = 0; + } + curtrack = 0; - pos=0; - i=getnext(1); - switch(type) - { - case FILE_LUCAS: - getnext(24); //skip junk and get to the midi. - adlib_style=LUCAS_STYLE|MIDI_STYLE; - //note: no break, we go right into midi headers... - case FILE_MIDI: - if (type != FILE_LUCAS) - tins=128; - getnext(11); /*skip header*/ - deltas=getnext(2); - midiprintf ("deltas:%ld\n",deltas); - getnext(4); + /* specific to file-type init */ + + pos = 0; + i = getnext (1); + switch (type) + { + case FILE_LUCAS: + getnext (24); //skip junk and get to the midi. + adlib_style = LUCAS_STYLE | MIDI_STYLE; + //note: no break, we go right into midi headers... + case FILE_MIDI: + if (type != FILE_LUCAS) + tins = 128; + getnext (11); /*skip header */ + deltas = getnext (2); + midiprintf ("deltas:%ld\n", deltas); + getnext (4); - curtrack=0; - track[curtrack].on=1; - track[curtrack].tend=getnext(4); - track[curtrack].spos=pos; - midiprintf ("tracklen:%ld\n",track[curtrack].tend); - break; - case FILE_CMF: - getnext(3); // ctmf - getnexti(2); //version - n=getnexti(2); // instrument offset - m=getnexti(2); // music offset - deltas=getnexti(2); //ticks/qtr note - msqtr=1000000/getnexti(2)*deltas; - //the stuff in the cmf is click ticks per second.. + curtrack = 0; + track[curtrack].on = 1; + track[curtrack].tend = getnext (4); + track[curtrack].spos = pos; + midiprintf ("tracklen:%ld\n", track[curtrack].tend); + break; + case FILE_CMF: + getnext (3); // ctmf + getnexti (2); //version + n = getnexti (2); // instrument offset + m = getnexti (2); // music offset + deltas = getnexti (2); //ticks/qtr note + msqtr = 1000000 / getnexti (2) * deltas; + //the stuff in the cmf is click ticks per second.. - i=getnexti(2); - if(i) title = (char *)data+i; - i=getnexti(2); - if(i) author = (char *)data+i; - i=getnexti(2); - if(i) remarks = (char *)data+i; - - getnext(16); // channel in use table .. - i=getnexti(2); // num instr - if (i>128) i=128; // to ward of bad numbers... - getnexti(2); //basic tempo + i = getnexti (2); + if (i) + title = (char *) data + i; + i = getnexti (2); + if (i) + author = (char *) data + i; + i = getnexti (2); + if (i) + remarks = (char *) data + i; - midiprintf("\nioff:%d\nmoff%d\ndeltas:%ld\nmsqtr:%ld\nnumi:%d\n", - n,m,deltas,msqtr,i); - pos=n; // jump to instruments - tins=i; - for (j=0; j<i; j++) - { - midiprintf ("\n%d: ",j); - for (l=0; l<16; l++) - { - myinsbank[j][l]=(unsigned char)getnext(1); - midiprintf ("%2X ",myinsbank[j][l]); - } - } + getnext (16); // channel in use table .. + i = getnexti (2); // num instr + if (i > 128) + i = 128; // to ward of bad numbers... + getnexti (2); //basic tempo - for (i=0; i<16; i++) - ch[i].nshift=-13; - - adlib_style=CMF_STYLE; + midiprintf ("\nioff:%d\nmoff%d\ndeltas:%ld\nmsqtr:%ld\nnumi:%d\n", + n, m, deltas, msqtr, i); + pos = n; // jump to instruments + tins = i; + for (j = 0; j < i; j++) + { + midiprintf ("\n%d: ", j); + for (l = 0; l < 16; l++) + { + myinsbank[j][l] = (unsigned char) getnext (1); + midiprintf ("%2X ", myinsbank[j][l]); + } + } - curtrack=0; - track[curtrack].on=1; - track[curtrack].tend=flen; // music until the end of the file - track[curtrack].spos=m; //jump to midi music - break; - case FILE_OLDLUCAS: - msqtr=250000; - pos=9; - deltas=getnext(1); + for (i = 0; i < 16; i++) + ch[i].nshift = -13; - i=8; - pos=0x19; // jump to instruments - tins=i; - for (j=0; j<i; j++) - { - midiprintf ("\n%d: ",j); - for (l=0; l<16; l++) - ins[l]=(unsigned char)getnext(1); + adlib_style = CMF_STYLE; - myinsbank[j][10]=ins[2]; - myinsbank[j][0]=ins[3]; - myinsbank[j][2]=ins[4]; - myinsbank[j][4]=ins[5]; - myinsbank[j][6]=ins[6]; - myinsbank[j][8]=ins[7]; - myinsbank[j][1]=ins[8]; - myinsbank[j][3]=ins[9]; - myinsbank[j][5]=ins[10]; - myinsbank[j][7]=ins[11]; - myinsbank[j][9]=ins[12]; + curtrack = 0; + track[curtrack].on = 1; + track[curtrack].tend = flen; // music until the end of the file + track[curtrack].spos = m; //jump to midi music + break; + case FILE_OLDLUCAS: + msqtr = 250000; + pos = 9; + deltas = getnext (1); - for (l=0; l<11; l++) - midiprintf ("%2X ",myinsbank[j][l]); - } + i = 8; + pos = 0x19; // jump to instruments + tins = i; + for (j = 0; j < i; j++) + { + midiprintf ("\n%d: ", j); + for (l = 0; l < 16; l++) + ins[l] = (unsigned char) getnext (1); - for (i=0; i<16; i++) - { - if (i<tins) - { - ch[i].inum=i; - for (j=0; j<11; j++) - ch[i].ins[j]=myinsbank[ch[i].inum][j]; - } - } + myinsbank[j][10] = ins[2]; + myinsbank[j][0] = ins[3]; + myinsbank[j][2] = ins[4]; + myinsbank[j][4] = ins[5]; + myinsbank[j][6] = ins[6]; + myinsbank[j][8] = ins[7]; + myinsbank[j][1] = ins[8]; + myinsbank[j][3] = ins[9]; + myinsbank[j][5] = ins[10]; + myinsbank[j][7] = ins[11]; + myinsbank[j][9] = ins[12]; - adlib_style=LUCAS_STYLE|MIDI_STYLE; + for (l = 0; l < 11; l++) + midiprintf ("%2X ", myinsbank[j][l]); + } - curtrack=0; - track[curtrack].on=1; - track[curtrack].tend=flen; // music until the end of the file - track[curtrack].spos=0x98; //jump to midi music - break; - case FILE_ADVSIERRA: - memcpy(myinsbank, smyinsbank, 128 * 16); - tins = stins; - deltas=0x20; - getnext(11); //worthless empty space and "stuff" :) + for (i = 0; i < 16; i++) + { + if (i < tins) + { + ch[i].inum = i; + for (j = 0; j < 11; j++) + ch[i].ins[j] = myinsbank[ch[i].inum][j]; + } + } + + adlib_style = LUCAS_STYLE | MIDI_STYLE; - o_sierra_pos=sierra_pos=pos; - sierra_next_section(); - while (datalook(sierra_pos-2)!=0xff) - { - sierra_next_section(); - subsongs++; - } + curtrack = 0; + track[curtrack].on = 1; + track[curtrack].tend = flen; // music until the end of the file + track[curtrack].spos = 0x98; //jump to midi music + break; + case FILE_ADVSIERRA: + memcpy (myinsbank, smyinsbank, 128 * 16); + tins = stins; + deltas = 0x20; + getnext (11); //worthless empty space and "stuff" :) - if (subsong < 0 || subsong >= subsongs) subsong=0; + o_sierra_pos = sierra_pos = pos; + sierra_next_section (); + while (datalook (sierra_pos - 2) != 0xff) + { + sierra_next_section (); + subsongs++; + } + + if (subsong < 0 || subsong >= subsongs) + subsong = 0; - sierra_pos=o_sierra_pos; - sierra_next_section(); - i=0; - while (i != subsong) - { - sierra_next_section(); - i++; - } + sierra_pos = o_sierra_pos; + sierra_next_section (); + i = 0; + while (i != subsong) + { + sierra_next_section (); + i++; + } - adlib_style=SIERRA_STYLE|MIDI_STYLE; //advanced sierra tunes use volume - break; - case FILE_SIERRA: - memcpy(myinsbank, smyinsbank, 128 * 16); - tins = stins; - getnext(2); - deltas=0x20; + adlib_style = SIERRA_STYLE | MIDI_STYLE; //advanced sierra tunes use volume + break; + case FILE_SIERRA: + memcpy (myinsbank, smyinsbank, 128 * 16); + tins = stins; + getnext (2); + deltas = 0x20; - curtrack=0; - track[curtrack].on=1; - track[curtrack].tend=flen; // music until the end of the file + curtrack = 0; + track[curtrack].on = 1; + track[curtrack].tend = flen; // music until the end of the file - for (i=0; i<16; i++) - { - ch[i].nshift=-13; - ch[i].on=getnext(1); - ch[i].inum=getnext(1); - for (j=0; j<11; j++) - ch[i].ins[j]=myinsbank[ch[i].inum][j]; - } + for (i = 0; i < 16; i++) + { + ch[i].nshift = -13; + ch[i].on = getnext (1); + ch[i].inum = getnext (1); + for (j = 0; j < 11; j++) + ch[i].ins[j] = myinsbank[ch[i].inum][j]; + } - track[curtrack].spos=pos; - adlib_style=SIERRA_STYLE|MIDI_STYLE; - break; - } + track[curtrack].spos = pos; + adlib_style = SIERRA_STYLE | MIDI_STYLE; + break; + } /* sprintf(info,"%s\r\nTicks/Quarter Note: %ld\r\n",info,deltas); sprintf(info,"%sms/Quarter Note: %ld",info,msqtr); */ - for (i=0; i<16; i++) - if (track[i].on) - { - track[i].pos=track[i].spos; - track[i].pv=0; - track[i].iwait=0; - } + for (i = 0; i < 16; i++) + if (track[i].on) + { + track[i].pos = track[i].spos; + track[i].pv = 0; + track[i].iwait = 0; + } - doing=1; - midi_fm_reset(); + doing = 1; + midi_fm_reset (); } -std::string CmidPlayer::gettype() +std::string CmidPlayer::gettype () { - switch(type) { - case FILE_LUCAS: - return std::string("LucasArts AdLib MIDI"); - case FILE_MIDI: - return std::string("General MIDI"); - case FILE_CMF: - return std::string("Creative Music Format (CMF MIDI)"); - case FILE_OLDLUCAS: - return std::string("Lucasfilm Adlib MIDI"); - case FILE_ADVSIERRA: - return std::string("Sierra On-Line VGA MIDI"); - case FILE_SIERRA: - return std::string("Sierra On-Line EGA MIDI"); - default: - return std::string("MIDI unknown"); - } + switch (type) + { + case FILE_LUCAS: + return std::string ("LucasArts AdLib MIDI"); + case FILE_MIDI: + return std::string ("General MIDI"); + case FILE_CMF: + return std::string ("Creative Music Format (CMF MIDI)"); + case FILE_OLDLUCAS: + return std::string ("Lucasfilm Adlib MIDI"); + case FILE_ADVSIERRA: + return std::string ("Sierra On-Line VGA MIDI"); + case FILE_SIERRA: + return std::string ("Sierra On-Line EGA MIDI"); + default: + return std::string ("MIDI unknown"); + } }
