2 * Adplug - Replayer for many OPL2/OPL3 audio file formats.
3 * Copyright (C) 1999 - 2007 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 * a2m.cpp - A2M Loader by Simon Peter <dn.tlp@gmx.net>
22 * This loader detects and loads version 1, 4, 5 & 8 files.
25 * Following commands are ignored: FF1 - FF9, FAx - FEx
28 * Instrument panning is ignored. Flags byte is ignored.
29 * Following commands are ignored: Gxy, Hxy, Kxy - &xy
35 const unsigned int Ca2mLoader::MAXFREQ = 2000,
36 Ca2mLoader::MINCOPY = ADPLUG_A2M_MINCOPY,
37 Ca2mLoader::MAXCOPY = ADPLUG_A2M_MAXCOPY,
38 Ca2mLoader::COPYRANGES = ADPLUG_A2M_COPYRANGES,
39 Ca2mLoader::CODESPERRANGE = ADPLUG_A2M_CODESPERRANGE,
40 Ca2mLoader::TERMINATE = 256,
41 Ca2mLoader::FIRSTCODE = ADPLUG_A2M_FIRSTCODE,
42 Ca2mLoader::MAXCHAR = FIRSTCODE + COPYRANGES * CODESPERRANGE - 1,
43 Ca2mLoader::SUCCMAX = MAXCHAR + 1,
44 Ca2mLoader::TWICEMAX = ADPLUG_A2M_TWICEMAX,
45 Ca2mLoader::ROOT = 1, Ca2mLoader::MAXBUF = 42 * 1024,
46 Ca2mLoader::MAXDISTANCE = 21389, Ca2mLoader::MAXSIZE = 21389 + MAXCOPY;
48 const unsigned short Ca2mLoader::bitvalue[14] =
49 {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192};
51 const signed short Ca2mLoader::copybits[COPYRANGES] =
52 {4, 6, 8, 10, 12, 14};
54 const signed short Ca2mLoader::copymin[COPYRANGES] =
55 {0, 16, 80, 336, 1360, 5456};
57 CPlayer *Ca2mLoader::factory(Copl *newopl)
59 return new Ca2mLoader(newopl);
62 bool Ca2mLoader::load(const std::string &filename, const CFileProvider &fp)
64 binistream *f = fp.open(filename); if(!f) return false;
68 unsigned char *org, *orgptr, flags = 0, numpats, version;
69 unsigned long crc, alength;
70 unsigned short len[9], *secdata, *secptr;
71 const unsigned char convfx[16] = {0,1,2,23,24,3,5,4,6,9,17,13,11,19,7,14};
72 const unsigned char convinf1[16] = {0,1,2,6,7,8,9,4,5,3,10,11,12,13,14,15};
73 const unsigned char newconvfx[] = {0,1,2,3,4,5,6,23,24,21,10,11,17,13,7,19,
74 255,255,22,25,255,15,255,255,255,255,255,
75 255,255,255,255,255,255,255,255,14,255};
78 f->readString(id, 10); crc = f->readInt(4);
79 version = f->readInt(1); numpats = f->readInt(1);
81 // file validation section
82 if(strncmp(id,"_A2module_",10) || (version != 1 && version != 5 &&
83 version != 4 && version != 8)) {
88 // load, depack & convert section
89 nop = numpats; length = 128; restartpos = 0;
91 for(i=0;i<5;i++) len[i] = f->readInt(2);
93 } else { // version >= 5
94 for(i=0;i<9;i++) len[i] = f->readInt(2);
99 secdata = new unsigned short [len[0] / 2];
100 if(version == 1 || version == 5) {
101 for(i=0;i<len[0]/2;i++) secdata[i] = f->readInt(2);
102 org = new unsigned char [MAXBUF]; orgptr = org;
103 sixdepak(secdata,org,len[0]);
105 orgptr = (unsigned char *)secdata;
106 for(i=0;i<len[0];i++) orgptr[i] = f->readInt(1);
108 memcpy(songname,orgptr,43); orgptr += 43;
109 memcpy(author,orgptr,43); orgptr += 43;
110 memcpy(instname,orgptr,250*33); orgptr += 250*33;
112 for(i=0;i<250;i++) { // instruments
113 inst[i].data[0] = *(orgptr+i*13+10);
114 inst[i].data[1] = *(orgptr+i*13);
115 inst[i].data[2] = *(orgptr+i*13+1);
116 inst[i].data[3] = *(orgptr+i*13+4);
117 inst[i].data[4] = *(orgptr+i*13+5);
118 inst[i].data[5] = *(orgptr+i*13+6);
119 inst[i].data[6] = *(orgptr+i*13+7);
120 inst[i].data[7] = *(orgptr+i*13+8);
121 inst[i].data[8] = *(orgptr+i*13+9);
122 inst[i].data[9] = *(orgptr+i*13+2);
123 inst[i].data[10] = *(orgptr+i*13+3);
126 inst[i].misc = *(orgptr+i*13+11);
127 else { // version >= 5 -> OPL3 format
128 int pan = *(orgptr+i*13+11);
131 inst[i].data[0] |= (pan & 3) << 4; // set pan
133 inst[i].data[0] |= 48; // enable both speakers
136 inst[i].slide = *(orgptr+i*13+12);
140 memcpy(order,orgptr,128); orgptr += 128;
141 bpm = *orgptr; orgptr++;
142 initspeed = *orgptr; orgptr++;
143 if(version >= 5) flags = *orgptr;
144 if(version == 1 || version == 5) delete [] org;
149 for(i = 0; i < (version < 5 ? numpats / 16 : numpats / 8); i++)
152 secdata = new unsigned short [alength / 2];
153 if(version == 1 || version == 5) {
154 for(l=0;l<alength/2;l++) secdata[l] = f->readInt(2);
155 org = new unsigned char [MAXBUF * (numpats / (version == 1 ? 16 : 8) + 1)];
156 orgptr = org; secptr = secdata;
157 orgptr += sixdepak(secptr,orgptr,len[1]); secptr += len[1] / 2;
160 orgptr += sixdepak(secptr,orgptr,len[2]); secptr += len[2] / 2;
162 orgptr += sixdepak(secptr,orgptr,len[3]); secptr += len[3] / 2;
164 sixdepak(secptr,orgptr,len[4]);
167 orgptr += sixdepak(secptr,orgptr,len[2]); secptr += len[2] / 2;
169 orgptr += sixdepak(secptr,orgptr,len[3]); secptr += len[3] / 2;
171 orgptr += sixdepak(secptr,orgptr,len[4]); secptr += len[4] / 2;
173 orgptr += sixdepak(secptr,orgptr,len[5]); secptr += len[5] / 2;
175 orgptr += sixdepak(secptr,orgptr,len[6]); secptr += len[6] / 2;
177 orgptr += sixdepak(secptr,orgptr,len[7]); secptr += len[7] / 2;
179 sixdepak(secptr,orgptr,len[8]);
183 org = (unsigned char *)secdata;
184 for(l=0;l<alength;l++) org[l] = f->readInt(1);
188 for(i=0;i<numpats;i++)
191 struct Tracks *track = &tracks[i * 9 + k][j];
192 unsigned char *o = &org[i*64*t*4+j*t*4+k*4];
194 track->note = o[0] == 255 ? 127 : o[0];
196 track->command = convfx[o[2]];
197 track->param2 = o[3] & 0x0f;
198 if(track->command != 14)
199 track->param1 = o[3] >> 4;
201 track->param1 = convinf1[o[3] >> 4];
202 if(track->param1 == 15 && !track->param2) { // convert key-off
208 if(track->command == 14) {
209 switch(track->param1) {
210 case 2: // convert define waveform
212 track->param1 = track->param2;
215 case 8: // convert volume slide up
217 track->param1 = track->param2;
220 case 9: // convert volume slide down
227 } else { // version >= 5
228 realloc_patterns(64, 64, 18);
230 for(i=0;i<numpats;i++)
233 struct Tracks *track = &tracks[i * 18 + j][k];
234 unsigned char *o = &org[i*64*t*4+j*64*4+k*4];
236 track->note = o[0] == 255 ? 127 : o[0];
238 track->command = newconvfx[o[2]];
239 track->param1 = o[3] >> 4;
240 track->param2 = o[3] & 0x0f;
242 // Convert '&' command
244 switch(track->param1) {
245 case 0: // pattern delay (frames)
248 // param2 already set correctly
251 case 1: // pattern delay (rows)
254 // param2 already set correctly
262 if(version == 1 || version == 5)
269 CmodPlayer::flags |= Opl3; // All versions >= 5 are OPL3
270 if(flags & 8) CmodPlayer::flags |= Tremolo; // Tremolo depth
271 if(flags & 16) CmodPlayer::flags |= Vibrato; // Vibrato depth
279 float Ca2mLoader::getrefresh()
282 return (float) (tempo);
287 /*** private methods *************************************/
289 void Ca2mLoader::inittree()
293 for(i=2;i<=TWICEMAX;i++) {
298 for(i=1;i<=MAXCHAR;i++) {
300 rghtc[i] = 2 * i + 1;
304 void Ca2mLoader::updatefreq(unsigned short a,unsigned short b)
307 freq[dad[a]] = freq[a] + freq[b];
310 if(leftc[dad[a]] == a)
316 if(freq[ROOT] == MAXFREQ)
317 for(a=1;a<=TWICEMAX;a++)
321 void Ca2mLoader::updatemodel(unsigned short code)
323 unsigned short a=code+SUCCMAX,b,c,code1,code2;
328 if(leftc[code1] == a)
329 updatefreq(a,rghtc[code1]);
331 updatefreq(a,leftc[code1]);
335 if(leftc[code2] == code1)
340 if(freq[a] > freq[b]) {
341 if(leftc[code2] == code1)
346 if(leftc[code1] == a) {
362 } while(code1 != ROOT);
366 unsigned short Ca2mLoader::inputcode(unsigned short bits)
368 unsigned short i,code=0;
370 for(i=1;i<=bits;i++) {
372 if(ibitcount == MAXBUF)
374 ibitbuffer = wdbuf[ibufcount];
380 if(ibitbuffer > 0x7fff)
381 code |= bitvalue[i-1];
388 unsigned short Ca2mLoader::uncompress()
394 if(ibufcount == MAXBUF)
396 ibitbuffer = wdbuf[ibufcount];
402 if(ibitbuffer > 0x7fff)
407 } while(a <= MAXCHAR);
414 void Ca2mLoader::decode()
416 unsigned short i,j,k,t,c,count=0,dist,len,index;
421 while(c != TERMINATE) {
423 obuf[obufcount] = (unsigned char)c;
425 if(obufcount == MAXBUF) {
426 output_size = MAXBUF;
430 buf[count] = (unsigned char)c;
436 index = t / CODESPERRANGE;
437 len = t + MINCOPY - index * CODESPERRANGE;
438 dist = inputcode(copybits[index]) + len + copymin[index];
445 for(i=0;i<=len-1;i++) {
446 obuf[obufcount] = buf[k];
448 if(obufcount == MAXBUF) {
449 output_size = MAXBUF;
455 if(j == MAXSIZE) j = 0;
456 if(k == MAXSIZE) k = 0;
465 output_size = obufcount;
468 unsigned short Ca2mLoader::sixdepak(unsigned short *source, unsigned char *dest,
471 if((unsigned int)size + 4096 > MAXBUF)
474 buf = new unsigned char [MAXSIZE];
476 ibitcount = 0; ibitbuffer = 0;
477 obufcount = 0; ibufcount = 0;
478 wdbuf = source; obuf = dest;