2 * Adplug - Replayer for many OPL2/OPL3 audio file formats.
3 * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp@gmx.net>, et al.
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.
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.
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
19 * mkj.cpp - MKJamz Player, by Simon Peter <dn.tlp@gmx.net>
28 CPlayer *CmkjPlayer::factory(Copl *newopl)
30 return new CmkjPlayer(newopl);
33 bool CmkjPlayer::load(const std::string &filename, const CFileProvider &fp)
35 binistream *f = fp.open(filename); if(!f) return false;
43 if(strncmp(id,"MKJamz",6)) { fp.close(f); return false; }
44 ver = f->readFloat(binio::Single);
45 if(ver > 1.12) { fp.close(f); return false; }
48 maxchannel = f->readInt(2);
49 opl->init(); opl->write(1, 32);
50 for(i = 0; i < maxchannel; i++) {
51 for(j = 0; j < 8; j++) inst[j] = f->readInt(2);
52 opl->write(0x20+op_table[i],inst[4]);
53 opl->write(0x23+op_table[i],inst[0]);
54 opl->write(0x40+op_table[i],inst[5]);
55 opl->write(0x43+op_table[i],inst[1]);
56 opl->write(0x60+op_table[i],inst[6]);
57 opl->write(0x63+op_table[i],inst[2]);
58 opl->write(0x80+op_table[i],inst[7]);
59 opl->write(0x83+op_table[i],inst[3]);
61 maxnotes = f->readInt(2);
62 songbuf = new short [(maxchannel+1)*maxnotes];
63 for(i = 0; i < maxchannel; i++) channel[i].defined = f->readInt(2);
64 for(i = 0; i < (maxchannel + 1) * maxnotes; i++)
65 songbuf[i] = f->readInt(2);
67 AdPlug_LogWrite("CmkjPlayer::load(\"%s\"): loaded file ver %.2f, %d channels,"
68 " %d notes/channel.\n", filename.c_str(), ver, maxchannel,
75 bool CmkjPlayer::update()
80 for(c = 0; c < maxchannel; c++) {
81 if(!channel[c].defined) // skip if channel is disabled
84 if(channel[c].pstat) {
89 opl->write(0xb0 + c, 0); // key off
91 assert(channel[c].songptr < (maxchannel + 1) * maxnotes);
92 note = songbuf[channel[c].songptr];
93 if(channel[c].songptr - c > maxchannel)
94 if(note && note < 250)
95 channel[c].pstat = channel[c].speed;
98 case 68: opl->write(0xa0 + c,0x81); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
99 case 69: opl->write(0xa0 + c,0xb0); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
100 case 70: opl->write(0xa0 + c,0xca); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
101 case 71: opl->write(0xa0 + c,0x2); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
102 case 65: opl->write(0xa0 + c,0x41); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
103 case 66: opl->write(0xa0 + c,0x87); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
104 case 67: opl->write(0xa0 + c,0xae); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
105 case 17: opl->write(0xa0 + c,0x6b); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
106 case 18: opl->write(0xa0 + c,0x98); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
107 case 20: opl->write(0xa0 + c,0xe5); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
108 case 21: opl->write(0xa0 + c,0x20); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
109 case 15: opl->write(0xa0 + c,0x63); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
111 channel[c].songptr += maxchannel;
112 channel[c].pstat = songbuf[channel[c].songptr];
114 case 254: // set octave
115 channel[c].songptr += maxchannel;
116 channel[c].octave = songbuf[channel[c].songptr];
118 case 253: // set speed
119 channel[c].songptr += maxchannel;
120 channel[c].speed = songbuf[channel[c].songptr];
122 case 252: // set waveform
123 channel[c].songptr += maxchannel;
124 channel[c].waveform = songbuf[channel[c].songptr] - 300;
126 opl->write(0xe0 + c + (c+6),channel[c].waveform);
128 opl->write(0xe0 + c,channel[c].waveform);
130 case 251: // song end
131 for(i = 0; i < maxchannel; i++) channel[i].songptr = i;
136 if(channel[c].songptr - c < maxnotes)
137 channel[c].songptr += maxchannel;
139 channel[c].songptr = c;
140 } while(!channel[c].pstat);
146 void CmkjPlayer::rewind(int subsong)
150 for(i = 0; i < maxchannel; i++) {
151 channel[i].pstat = 0;
152 channel[i].speed = 0;
153 channel[i].waveform = 0;
154 channel[i].songptr = i;
155 channel[i].octave = 4;
161 float CmkjPlayer::getrefresh()