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