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 cff.cpp - BoomTracker loader by Riven the Mage <riven@ok.ru>
20 */
21 /*
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.
25 */
26
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "cff.h"
31
32 /* -------- Public Methods -------------------------------- */
33
factory(Copl * newopl)34 CPlayer *CcffLoader::factory(Copl *newopl)
35 {
36 return new CcffLoader(newopl);
37 }
38
load(const char * filename,const CFileProvider & fp)39 bool CcffLoader::load(const char *filename, const CFileProvider &fp)
40 {
41 binistream *f = fp.open(filename); if(!f) return false;
42 const unsigned char conv_inst[11] = { 2,1,10,9,4,3,6,5,0,8,7 };
43 const unsigned short conv_note[12] = { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE };
44
45 int i,j,k,t=0;
46
47 // '<CUD-FM-File>' - signed ?
48 f->readString(header.id, 16);
49 header.version = f->readInt(1); header.size = f->readInt(2);
50 header.packed = f->readInt(1); f->readString((char *)header.reserved, 12);
51 if (memcmp(header.id,"<CUD-FM-File>""\x1A\xDE\xE0",16))
52 { fp.close(f); return false; }
53
54 unsigned char *module = new unsigned char [0x10000];
55
56 // packed ?
57 if (header.packed)
58 {
59 cff_unpacker *unpacker = new cff_unpacker;
60
61 unsigned char *packed_module = new unsigned char [header.size + 4];
62
63 memset(packed_module,0,header.size + 4);
64
65 f->readString((char *)packed_module, header.size);
66 fp.close(f);
67
68 if (!unpacker->unpack(packed_module,module))
69 {
70 delete unpacker;
71 delete packed_module;
72 delete module;
73 return false;
74 }
75
76 delete unpacker;
77 delete packed_module;
78
79 if (memcmp(&module[0x5E1],"CUD-FM-File - SEND A POSTCARD -",31))
80 {
81 delete module;
82 return false;
83 }
84 }
85 else
86 {
87 f->readString((char *)module, header.size);
88 fp.close(f);
89 }
90
91 // init CmodPlayer
92 realloc_instruments(47);
93 realloc_order(64);
94 realloc_patterns(36,64,9);
95 init_notetable(conv_note);
96 init_trackord();
97
98 // load instruments
99 for (i=0;i<47;i++)
100 {
101 memcpy(&instruments[i],&module[i*32],sizeof(cff_instrument));
102
103 for (j=0;j<11;j++)
104 inst[i].data[conv_inst[j]] = instruments[i].data[j];
105
106 instruments[i].name[20] = 0;
107 }
108
109 // number of patterns
110 nop = module[0x5E0];
111
112 // load title & author
113 memcpy(song_title,&module[0x614],20);
114 memcpy(song_author,&module[0x600],20);
115
116 // load order
117 memcpy(order,&module[0x628],64);
118
119 // load tracks
120 for (i=0;i<nop;i++)
121 {
122 unsigned char old_event_byte2[9];
123
124 memset(old_event_byte2,0,9);
125
126 for (j=0;j<9;j++)
127 {
128 for (k=0;k<64;k++)
129 {
130 cff_event *event = (cff_event *)&module[0x669 + ((i*64+k)*9+j)*3];
131
132 // convert note
133 if (event->byte0 == 0x6D)
134 tracks[t][k].note = 127;
135 else
136 if (event->byte0)
137 tracks[t][k].note = event->byte0;
138
139 if (event->byte2)
140 old_event_byte2[j] = event->byte2;
141
142 // convert effect
143 switch (event->byte1)
144 {
145 case 'I': // set instrument
146 tracks[t][k].inst = event->byte2 + 1;
147 tracks[t][k].param1 = tracks[t][k].param2 = 0;
148 break;
149
150 case 'H': // set tempo
151 tracks[t][k].command = 7;
152 if (event->byte2 < 16)
153 {
154 tracks[t][k].param1 = 0x07;
155 tracks[t][k].param2 = 0x0D;
156 }
157 break;
158
159 case 'A': // set speed
160 tracks[t][k].command = 19;
161 tracks[t][k].param1 = event->byte2 >> 4;
162 tracks[t][k].param2 = event->byte2 & 15;
163 break;
164
165 case 'L': // pattern break
166 tracks[t][k].command = 13;
167 tracks[t][k].param1 = event->byte2 >> 4;
168 tracks[t][k].param2 = event->byte2 & 15;
169 break;
170
171 case 'K': // order jump
172 tracks[t][k].command = 11;
173 tracks[t][k].param1 = event->byte2 >> 4;
174 tracks[t][k].param2 = event->byte2 & 15;
175 break;
176
177 case 'M': // set vibrato/tremolo
178 tracks[t][k].command = 27;
179 tracks[t][k].param1 = event->byte2 >> 4;
180 tracks[t][k].param2 = event->byte2 & 15;
181 break;
182
183 case 'C': // set modulator volume
184 tracks[t][k].command = 21;
185 tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
186 tracks[t][k].param2 = (0x3F - event->byte2) & 15;
187 break;
188
189 case 'G': // set carrier volume
190 tracks[t][k].command = 22;
191 tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
192 tracks[t][k].param2 = (0x3F - event->byte2) & 15;
193 break;
194
195 case 'B': // set carrier waveform
196 tracks[t][k].command = 25;
197 tracks[t][k].param1 = event->byte2;
198 tracks[t][k].param2 = 0x0F;
199 break;
200
201 case 'E': // fine frequency slide down
202 tracks[t][k].command = 24;
203 tracks[t][k].param1 = old_event_byte2[j] >> 4;
204 tracks[t][k].param2 = old_event_byte2[j] & 15;
205 break;
206
207 case 'F': // fine frequency slide up
208 tracks[t][k].command = 23;
209 tracks[t][k].param1 = old_event_byte2[j] >> 4;
210 tracks[t][k].param2 = old_event_byte2[j] & 15;
211 break;
212
213 case 'D': // fine volume slide
214 tracks[t][k].command = 14;
215 if (old_event_byte2[j] & 15)
216 {
217 // slide down
218 tracks[t][k].param1 = 5;
219 tracks[t][k].param2 = old_event_byte2[j] & 15;
220 }
221 else
222 {
223 // slide up
224 tracks[t][k].param1 = 4;
225 tracks[t][k].param2 = old_event_byte2[j] >> 4;
226 }
227 break;
228
229 case 'J': // arpeggio
230 tracks[t][k].param1 = old_event_byte2[j] >> 4;
231 tracks[t][k].param2 = old_event_byte2[j] & 15;
232 break;
233 }
234 }
235
236 t++;
237 }
238 }
239
240 delete [] module;
241
242 // order loop
243 restartpos = 0;
244
245 // order length
246 for (i=0;i<64;i++)
247 {
248 if (order[i] >= 0x80)
249 {
250 length = i;
251 break;
252 }
253 }
254
255 // default tempo
256 bpm = 0x7D;
257
258 rewind(0);
259
260 return true;
261 }
262
rewind(int subsong)263 void CcffLoader::rewind(int subsong)
264 {
265 CmodPlayer::rewind(subsong);
266
267 // default instruments
268 for (int i=0;i<9;i++)
269 {
270 channel[i].inst = i;
271
272 channel[i].vol1 = 63 - (inst[i].data[10] & 63);
273 channel[i].vol2 = 63 - (inst[i].data[9] & 63);
274 }
275 }
276
gettype()277 const char * CcffLoader::gettype()
278 {
279 if (header.packed)
280 return "BoomTracker 4, packed";
281 else
282 return "BoomTracker 4";
283 }
284
gettitle()285 const char * CcffLoader::gettitle()
286 {
287 return song_title;
288 }
289
getauthor()290 const char * CcffLoader::getauthor()
291 {
292 return song_author;
293 }
294
getinstrument(unsigned int n)295 const char * CcffLoader::getinstrument(unsigned int n)
296 {
297 return instruments[n].name;
298 }
299
getinstruments()300 unsigned int CcffLoader::getinstruments()
301 {
302 return 47;
303 }
304
305 /* -------- Private Methods ------------------------------- */
306
307 #ifdef _WIN32
308 #pragma warning(disable:4244)
309 #pragma warning(disable:4018)
310 #endif
311
312 /*
313 Lempel-Ziv-Tyr ;-)
314 */
unpack(unsigned char * ibuf,unsigned char * obuf)315 long CcffLoader::cff_unpacker::unpack(unsigned char *ibuf, unsigned char *obuf)
316 {
317 if (memcmp(ibuf,"YsComp""\x07""CUD1997""\x1A\x04",16))
318 return 0;
319
320 input = ibuf + 16;
321 output = obuf;
322
323 output_length = 0;
324
325 heap = (unsigned char *)malloc(0x10000);
326 dictionary = (unsigned char **)malloc(sizeof(unsigned char *)*0x8000);
327
328 memset(heap,0,0x10000);
329 memset(dictionary,0,0x8000);
330
331 cleanup();
332 if(!startup())
333 goto out;
334
335 // LZW
336 while (1)
337 {
338 new_code = get_code();
339
340 // 0x00: end of data
341 if (new_code == 0)
342 break;
343
344 // 0x01: end of block
345 if (new_code == 1)
346 {
347 cleanup();
348 if(!startup())
349 goto out;
350
351 continue;
352 }
353
354 // 0x02: expand code length
355 if (new_code == 2)
356 {
357 code_length++;
358
359 continue;
360 }
361
362 // 0x03: RLE
363 if (new_code == 3)
364 {
365 unsigned char old_code_length = code_length;
366
367 code_length = 2;
368
369 unsigned char repeat_length = get_code() + 1;
370
371 code_length = 4 << get_code();
372
373 unsigned long repeat_counter = get_code();
374
375 if(output_length + repeat_counter * repeat_length > 0x10000) {
376 output_length = 0;
377 goto out;
378 }
379
380 for (unsigned int i=0;i<repeat_counter*repeat_length;i++)
381 output[output_length++] = output[output_length - repeat_length];
382
383 code_length = old_code_length;
384
385 if(!startup())
386 goto out;
387
388 continue;
389 }
390
391 if (new_code >= (0x104 + dictionary_length))
392 {
393 // dictionary <- old.code.string + old.code.char
394 the_string[++the_string[0]] = the_string[1];
395 }
396 else
397 {
398 // dictionary <- old.code.string + new.code.char
399 unsigned char temp_string[256];
400
401 translate_code(new_code,temp_string);
402
403 the_string[++the_string[0]] = temp_string[1];
404 }
405
406 expand_dictionary(the_string);
407
408 // output <- new.code.string
409 translate_code(new_code,the_string);
410
411 if(output_length + the_string[0] > 0x10000) {
412 output_length = 0;
413 goto out;
414 }
415
416 for (int i=0;i<the_string[0];i++)
417 output[output_length++] = the_string[i+1];
418
419 old_code = new_code;
420 }
421
422 out:
423 free(heap);
424 free(dictionary);
425 return output_length;
426 }
427
get_code()428 unsigned long CcffLoader::cff_unpacker::get_code()
429 {
430 unsigned long code;
431
432 while (bits_left < code_length)
433 {
434 bits_buffer |= ((*input++) << bits_left);
435 bits_left += 8;
436 }
437
438 code = bits_buffer & ((1 << code_length) - 1);
439
440 bits_buffer >>= code_length;
441 bits_left -= code_length;
442
443 return code;
444 }
445
translate_code(unsigned long code,unsigned char * string)446 void CcffLoader::cff_unpacker::translate_code(unsigned long code, unsigned char *string)
447 {
448 unsigned char translated_string[256];
449
450 if (code >= 0x104)
451 {
452 memcpy(translated_string,dictionary[code - 0x104],(*(dictionary[code - 0x104])) + 1);
453 }
454 else
455 {
456 translated_string[0] = 1;
457 translated_string[1] = (code - 4) & 0xFF;
458 }
459
460 memcpy(string,translated_string,256);
461 }
462
cleanup()463 void CcffLoader::cff_unpacker::cleanup()
464 {
465 code_length = 9;
466
467 bits_buffer = 0;
468 bits_left = 0;
469
470 heap_length = 0;
471 dictionary_length = 0;
472 }
473
startup()474 int CcffLoader::cff_unpacker::startup()
475 {
476 old_code = get_code();
477
478 translate_code(old_code,the_string);
479
480 if(output_length + the_string[0] > 0x10000) {
481 output_length = 0;
482 return 0;
483 }
484
485 for (int i=0;i<the_string[0];i++)
486 output[output_length++] = the_string[i+1];
487
488 return 1;
489 }
490
expand_dictionary(unsigned char * string)491 void CcffLoader::cff_unpacker::expand_dictionary(unsigned char *string)
492 {
493 if (string[0] >= 0xF0)
494 return;
495
496 memcpy(&heap[heap_length],string,string[0] + 1);
497
498 dictionary[dictionary_length] = &heap[heap_length];
499
500 dictionary_length++;
501
502 heap_length += (string[0] + 1);
503 }
504
505 #ifdef _WIN32
506 #pragma warning(default:4244)
507 #pragma warning(default:4018)
508 #endif
509