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