2 AdPlug - Replayer for many OPL2/OPL3 audio file formats.
3 Copyright (C) 1999 - 2008 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 cff.cpp - BoomTracker loader by Riven the Mage <riven@ok.ru>
22 NOTE: Conversion of slides is not 100% accurate. Original volume slides
23 have effect on carrier volume only. Also, original arpeggio, frequency & volume
24 slides use previous effect data instead of current.
33 /* -------- Public Methods -------------------------------- */
35 CPlayer *CcffLoader::factory(Copl *newopl)
37 return new CcffLoader(newopl);
40 bool CcffLoader::load(const std::string &filename, const CFileProvider &fp)
42 binistream *f = fp.open(filename); if(!f) return false;
43 const unsigned char conv_inst[11] = { 2,1,10,9,4,3,6,5,0,8,7 };
44 const unsigned short conv_note[12] = { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE };
48 // '<CUD-FM-File>' - signed ?
49 f->readString(header.id, 16);
50 header.version = f->readInt(1); header.size = f->readInt(2);
51 header.packed = f->readInt(1); f->readString((char *)header.reserved, 12);
52 if (memcmp(header.id,"<CUD-FM-File>""\x1A\xDE\xE0",16))
53 { fp.close(f); return false; }
55 unsigned char *module = new unsigned char [0x10000];
60 cff_unpacker *unpacker = new cff_unpacker;
62 unsigned char *packed_module = new unsigned char [header.size + 4];
64 memset(packed_module,0,header.size + 4);
66 f->readString((char *)packed_module, header.size);
69 if (!unpacker->unpack(packed_module,module))
80 if (memcmp(&module[0x5E1],"CUD-FM-File - SEND A POSTCARD -",31))
88 f->readString((char *)module, header.size);
93 realloc_instruments(47);
95 realloc_patterns(36,64,9);
96 init_notetable(conv_note);
102 memcpy(&instruments[i],&module[i*32],sizeof(cff_instrument));
105 inst[i].data[conv_inst[j]] = instruments[i].data[j];
107 instruments[i].name[20] = 0;
110 // number of patterns
113 // load title & author
114 memcpy(song_title,&module[0x614],20);
115 memcpy(song_author,&module[0x600],20);
118 memcpy(order,&module[0x628],64);
123 unsigned char old_event_byte2[9];
125 memset(old_event_byte2,0,9);
131 cff_event *event = (cff_event *)&module[0x669 + ((i*64+k)*9+j)*3];
134 if (event->byte0 == 0x6D)
135 tracks[t][k].note = 127;
138 tracks[t][k].note = event->byte0;
141 old_event_byte2[j] = event->byte2;
144 switch (event->byte1)
146 case 'I': // set instrument
147 tracks[t][k].inst = event->byte2 + 1;
148 tracks[t][k].param1 = tracks[t][k].param2 = 0;
151 case 'H': // set tempo
152 tracks[t][k].command = 7;
153 if (event->byte2 < 16)
155 tracks[t][k].param1 = 0x07;
156 tracks[t][k].param2 = 0x0D;
160 case 'A': // set speed
161 tracks[t][k].command = 19;
162 tracks[t][k].param1 = event->byte2 >> 4;
163 tracks[t][k].param2 = event->byte2 & 15;
166 case 'L': // pattern break
167 tracks[t][k].command = 13;
168 tracks[t][k].param1 = event->byte2 >> 4;
169 tracks[t][k].param2 = event->byte2 & 15;
172 case 'K': // order jump
173 tracks[t][k].command = 11;
174 tracks[t][k].param1 = event->byte2 >> 4;
175 tracks[t][k].param2 = event->byte2 & 15;
178 case 'M': // set vibrato/tremolo
179 tracks[t][k].command = 27;
180 tracks[t][k].param1 = event->byte2 >> 4;
181 tracks[t][k].param2 = event->byte2 & 15;
184 case 'C': // set modulator volume
185 tracks[t][k].command = 21;
186 tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
187 tracks[t][k].param2 = (0x3F - event->byte2) & 15;
190 case 'G': // set carrier volume
191 tracks[t][k].command = 22;
192 tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
193 tracks[t][k].param2 = (0x3F - event->byte2) & 15;
196 case 'B': // set carrier waveform
197 tracks[t][k].command = 25;
198 tracks[t][k].param1 = event->byte2;
199 tracks[t][k].param2 = 0x0F;
202 case 'E': // fine frequency slide down
203 tracks[t][k].command = 24;
204 tracks[t][k].param1 = old_event_byte2[j] >> 4;
205 tracks[t][k].param2 = old_event_byte2[j] & 15;
208 case 'F': // fine frequency slide up
209 tracks[t][k].command = 23;
210 tracks[t][k].param1 = old_event_byte2[j] >> 4;
211 tracks[t][k].param2 = old_event_byte2[j] & 15;
214 case 'D': // fine volume slide
215 tracks[t][k].command = 14;
216 if (old_event_byte2[j] & 15)
219 tracks[t][k].param1 = 5;
220 tracks[t][k].param2 = old_event_byte2[j] & 15;
225 tracks[t][k].param1 = 4;
226 tracks[t][k].param2 = old_event_byte2[j] >> 4;
230 case 'J': // arpeggio
231 tracks[t][k].param1 = old_event_byte2[j] >> 4;
232 tracks[t][k].param2 = old_event_byte2[j] & 15;
249 if (order[i] >= 0x80)
264 void CcffLoader::rewind(int subsong)
266 CmodPlayer::rewind(subsong);
268 // default instruments
269 for (int i=0;i<9;i++)
273 channel[i].vol1 = 63 - (inst[i].data[10] & 63);
274 channel[i].vol2 = 63 - (inst[i].data[9] & 63);
278 std::string CcffLoader::gettype()
281 return std::string("BoomTracker 4, packed");
283 return std::string("BoomTracker 4");
286 std::string CcffLoader::gettitle()
288 return std::string(song_title,20);
291 std::string CcffLoader::getauthor()
293 return std::string(song_author,20);
296 std::string CcffLoader::getinstrument(unsigned int n)
298 return std::string(instruments[n].name);
301 unsigned int CcffLoader::getinstruments()
306 /* -------- Private Methods ------------------------------- */
309 #pragma warning(disable:4244)
310 #pragma warning(disable:4018)
316 long CcffLoader::cff_unpacker::unpack(unsigned char *ibuf, unsigned char *obuf)
318 if (memcmp(ibuf,"YsComp""\x07""CUD1997""\x1A\x04",16))
326 heap = (unsigned char *)malloc(0x10000);
327 dictionary = (unsigned char **)malloc(sizeof(unsigned char *)*0x8000);
329 memset(heap,0,0x10000);
330 memset(dictionary,0,0x8000);
339 new_code = get_code();
345 // 0x01: end of block
355 // 0x02: expand code length
366 unsigned char old_code_length = code_length;
370 unsigned char repeat_length = get_code() + 1;
372 code_length = 4 << get_code();
374 unsigned long repeat_counter = get_code();
376 if(output_length + repeat_counter * repeat_length > 0x10000) {
381 for (unsigned int i=0;i<repeat_counter*repeat_length;i++)
382 output[output_length++] = output[output_length - repeat_length];
384 code_length = old_code_length;
392 if (new_code >= (0x104 + dictionary_length))
394 // dictionary <- old.code.string + old.code.char
395 the_string[++the_string[0]] = the_string[1];
399 // dictionary <- old.code.string + new.code.char
400 unsigned char temp_string[256];
402 translate_code(new_code,temp_string);
404 the_string[++the_string[0]] = temp_string[1];
407 expand_dictionary(the_string);
409 // output <- new.code.string
410 translate_code(new_code,the_string);
412 if(output_length + the_string[0] > 0x10000) {
417 for (int i=0;i<the_string[0];i++)
418 output[output_length++] = the_string[i+1];
426 return output_length;
429 unsigned long CcffLoader::cff_unpacker::get_code()
433 while (bits_left < code_length)
435 bits_buffer |= ((*input++) << bits_left);
439 code = bits_buffer & ((1 << code_length) - 1);
441 bits_buffer >>= code_length;
442 bits_left -= code_length;
447 void CcffLoader::cff_unpacker::translate_code(unsigned long code, unsigned char *string)
449 unsigned char translated_string[256];
453 memcpy(translated_string,dictionary[code - 0x104],(*(dictionary[code - 0x104])) + 1);
457 translated_string[0] = 1;
458 translated_string[1] = (code - 4) & 0xFF;
461 memcpy(string,translated_string,256);
464 void CcffLoader::cff_unpacker::cleanup()
472 dictionary_length = 0;
475 int CcffLoader::cff_unpacker::startup()
477 old_code = get_code();
479 translate_code(old_code,the_string);
481 if(output_length + the_string[0] > 0x10000) {
486 for (int i=0;i<the_string[0];i++)
487 output[output_length++] = the_string[i+1];
492 void CcffLoader::cff_unpacker::expand_dictionary(unsigned char *string)
494 if (string[0] >= 0xF0)
497 memcpy(&heap[heap_length],string,string[0] + 1);
499 dictionary[dictionary_length] = &heap[heap_length];
503 heap_length += (string[0] + 1);
507 #pragma warning(default:4244)
508 #pragma warning(default:4018)