]> 4ch.mooo.com Git - 16.git/blob - 16/adplug/adplug/src/u6m.cpp
wwww~
[16.git] / 16 / adplug / adplug / src / u6m.cpp
1 /*
2  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
3  * Copyright (C) 1999 - 2006 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  * u6m.cpp - Ultima 6 Music Player by Marc Winterrowd.
20  * This code extends the Adlib Winamp plug-in by Simon Peter <dn.tlp@gmx.net>
21  */
22
23 #include "u6m.h"
24
25 // Makes security checks on output buffer before writing
26 #define SAVE_OUTPUT_ROOT(c, d, p) \
27 if(p < d.size) \
28   output_root(c, d.data, p); \
29 else \
30   return false;
31
32 CPlayer *Cu6mPlayer::factory(Copl *newopl)
33 {
34   return new Cu6mPlayer(newopl);
35 }
36
37 bool Cu6mPlayer::load(const std::string &filename, const CFileProvider &fp)
38 {
39   // file validation section
40   // this section only checks a few *necessary* conditions
41   unsigned long filesize, decompressed_filesize;
42   binistream *f;
43
44   f = fp.open(filename); if(!f) return false;
45   filesize = fp.filesize(f);
46
47   if (filesize >= 6)
48     {
49       // check if the file has a valid pseudo-header
50       unsigned char pseudo_header[6];
51       f->readString((char *)pseudo_header, 6);
52       decompressed_filesize = pseudo_header[0] + (pseudo_header[1] << 8);
53
54       if (!( (pseudo_header[2]==0) && (pseudo_header[3]==0) &&
55              (pseudo_header[4] + ((pseudo_header[5] & 0x1)<<8) == 0x100) &&
56              (decompressed_filesize > (filesize-4)) ))
57         {
58           fp.close(f);
59           return(false);
60         }
61     }
62   else
63     {
64       fp.close(f);
65       return(false);
66     }
67
68   // load section
69   song_data = new unsigned char[decompressed_filesize];
70   unsigned char* compressed_song_data = new unsigned char[filesize-3];
71
72   f->seek(4);
73   f->readString((char *)compressed_song_data, filesize - 4);
74   fp.close(f);
75
76   // attempt to decompress the song data
77   // if unsuccessful, deallocate song_data[] on the spot, and return(false)
78   data_block source, destination;
79   source.size = filesize-4;
80   source.data = compressed_song_data;
81   destination.size = decompressed_filesize;
82   destination.data = song_data;
83         
84   if (!lzw_decompress(source,destination))
85     {
86       delete[] compressed_song_data;
87       delete[] song_data;
88       return(false);
89     }
90
91   // deallocation section
92   delete[] compressed_song_data;
93
94   rewind(0);
95   return (true);
96 }
97
98
99 bool Cu6mPlayer::update()
100 {
101   if (!driver_active)
102     {
103       driver_active = true;
104       dec_clip(read_delay);
105       if (read_delay == 0)
106         {
107           command_loop();
108         }
109
110       // on all Adlib channels: freq slide/vibrato, mute factor slide
111       for (int i = 0; i < 9; i++)
112         {
113           if (channel_freq_signed_delta[i]!=0)
114             // frequency slide + mute factor slide
115             {
116               // freq slide
117               freq_slide(i);
118
119               // mute factor slide
120               if (carrier_mf_signed_delta[i]!=0)
121                 {
122                   mf_slide(i);
123                 }
124             }
125           else
126             // vibrato + mute factor slide
127             {
128               // vibrato
129               if ((vb_multiplier[i]!=0) && ((channel_freq[i].hi & 0x20)==0x20))
130                 {
131                   vibrato(i);
132                 }
133
134               // mute factor slide
135               if (carrier_mf_signed_delta[i]!=0)
136                 {
137                   mf_slide(i);
138                 }
139             }
140         }
141
142       driver_active = false;
143     }
144
145   return !songend;
146 }
147
148
149 void Cu6mPlayer::rewind(int subsong)
150 {
151   played_ticks = 0;
152   songend = false;
153
154   // set the driver's internal variables
155   byte_pair freq_word = {0,0};
156
157   driver_active = false;
158   song_pos = 0;
159   loop_position = 0;   // position of the loop point
160   read_delay = 0;      // delay (in timer ticks) before further song data is read
161  
162   for (int i = 0; i < 9; i++)
163     {
164       // frequency
165       channel_freq_signed_delta[i] = 0;
166       channel_freq[i] = freq_word;  // Adlib freq settings for each channel
167
168       // vibrato ("vb")
169       vb_current_value[i] = 0;
170       vb_double_amplitude[i] = 0;
171       vb_multiplier[i] = 0;
172       vb_direction_flag[i] = 0;
173
174       // mute factor ("mf") == ~(volume)
175       carrier_mf[i] = 0;
176       carrier_mf_signed_delta[i] = 0;
177       carrier_mf_mod_delay_backup[i] = 0;
178       carrier_mf_mod_delay[i] = 0;
179     }
180
181   while (!subsong_stack.empty())                // empty subsong stack
182     subsong_stack.pop();
183
184   opl->init();
185   out_adlib(1,32);      // go to OPL2 mode
186 }
187
188
189 float Cu6mPlayer::getrefresh()
190 {
191   return ((float)60);   // the Ultima 6 music driver expects to be called at 60 Hz
192 }
193
194
195 // ============================================================================================
196 //
197 //
198 //    Functions called by load()
199 //
200 //
201 // ============================================================================================
202
203
204 // decompress from memory to memory
205 bool Cu6mPlayer::lzw_decompress(Cu6mPlayer::data_block source, Cu6mPlayer::data_block dest)
206 {
207   bool end_marker_reached = false;
208   int codeword_size = 9;
209   long bits_read = 0;
210   int next_free_codeword = 0x102;
211   int dictionary_size = 0x200;
212   MyDict dictionary = MyDict();
213   std::stack<unsigned char> root_stack;
214
215   long bytes_written = 0;
216
217   int cW;
218   int pW;
219   unsigned char C;
220
221   while (!end_marker_reached)
222     {
223       cW = get_next_codeword(bits_read, source.data, codeword_size);
224       switch (cW)
225         {
226           // re-init the dictionary
227         case 0x100:
228           codeword_size = 9;
229           next_free_codeword = 0x102;
230           dictionary_size = 0x200;
231           dictionary.reset();
232           cW = get_next_codeword(bits_read, source.data, codeword_size);
233           SAVE_OUTPUT_ROOT((unsigned char)cW, dest, bytes_written);
234           break;
235           // end of compressed file has been reached
236         case 0x101:
237           end_marker_reached = true;
238           break;
239           // (cW <> 0x100) && (cW <> 0x101)
240         default:
241           if (cW < next_free_codeword)  // codeword is already in the dictionary
242             {
243               // create the string associated with cW (on the stack)
244               get_string(cW,dictionary,root_stack);
245               C = root_stack.top();
246               // output the string represented by cW
247               while (!root_stack.empty())
248                 {
249                   SAVE_OUTPUT_ROOT(root_stack.top(), dest, bytes_written);
250                   root_stack.pop();
251                 }
252               // add pW+C to the dictionary
253               dictionary.add(C,pW);
254
255               next_free_codeword++;
256               if (next_free_codeword >= dictionary_size)
257                 {
258                   if (codeword_size < max_codeword_length)
259                     {
260                       codeword_size += 1;
261                       dictionary_size *= 2;
262                     }
263                 }
264             }
265           else  // codeword is not yet defined
266             {
267               // create the string associated with pW (on the stack)
268               get_string(pW,dictionary,root_stack);
269               C = root_stack.top();
270               // output the string represented by pW
271               while (!root_stack.empty())
272                 {
273                   SAVE_OUTPUT_ROOT(root_stack.top(), dest, bytes_written);
274                   root_stack.pop();
275                 }
276               // output the char C
277               SAVE_OUTPUT_ROOT(C, dest, bytes_written);
278
279               // the new dictionary entry must correspond to cW
280               // if it doesn't, something is wrong with the lzw-compressed data.
281               if (cW != next_free_codeword)
282                 {
283                   /*                        printf("cW != next_free_codeword!\n");
284                                             exit(-1); */
285                   return false;
286                 }
287               // add pW+C to the dictionary
288               dictionary.add(C,pW);
289  
290               next_free_codeword++;
291               if (next_free_codeword >= dictionary_size)
292                 {
293                   if (codeword_size < max_codeword_length)
294                     {
295                       codeword_size += 1;
296                       dictionary_size *= 2;
297                     }
298                 }
299             };
300           break;
301         }
302       // shift roles - the current cW becomes the new pW
303       pW = cW;
304     }
305
306   return(true);   // indicate successful decompression
307 }
308
309
310 // --------------------
311 // Additional functions
312 // --------------------
313
314
315 // Read the next code word from the source buffer
316 int Cu6mPlayer::get_next_codeword (long& bits_read, unsigned char *source, int codeword_size)
317 {
318   unsigned char b0,b1,b2;
319   int codeword;
320  
321   b0 = source[bits_read/8];
322   b1 = source[bits_read/8+1];
323   b2 = source[bits_read/8+2];
324
325   codeword = ((b2 << 16) + (b1 << 8) + b0);
326   codeword = codeword >> (bits_read % 8);
327   switch (codeword_size)
328     {
329     case 0x9:
330       codeword = codeword & 0x1ff;
331       break;
332     case 0xa:
333       codeword = codeword & 0x3ff;
334       break;
335     case 0xb:
336       codeword = codeword & 0x7ff;
337       break;
338     case 0xc:
339       codeword = codeword & 0xfff;
340       break;
341     default:
342       codeword = -1;   // indicates that an error has occurred
343       break;
344     }
345
346   bits_read += codeword_size;
347   return (codeword);
348 }
349
350
351 // output a root to memory
352 void Cu6mPlayer::output_root(unsigned char root, unsigned char *destination, long& position)
353 {
354   destination[position] = root;
355   position++;
356 }
357
358
359 // output the string represented by a codeword
360 void Cu6mPlayer::get_string(int codeword, Cu6mPlayer::MyDict& dictionary, std::stack<unsigned char>& root_stack)
361 {
362   unsigned char root;
363   int current_codeword;
364
365   current_codeword = codeword;
366
367   while (current_codeword > 0xff)
368     {
369       root = dictionary.get_root(current_codeword);
370       current_codeword = dictionary.get_codeword(current_codeword);
371       root_stack.push(root);
372     }
373
374   // push the root at the leaf
375   root_stack.push((unsigned char)current_codeword);
376 }
377
378
379 // ============================================================================================
380 //
381 //
382 //    Functions called by update()
383 //
384 //
385 // ============================================================================================
386
387
388 // This function reads the song data and executes the embedded commands.
389 void Cu6mPlayer::command_loop()
390 {
391   unsigned char command_byte;   // current command byte
392   int command_nibble_hi;        // command byte, bits 4-7
393   int command_nibble_lo;        // command byte, bite 0-3
394   bool repeat_loop = true;      //
395
396   do
397     {
398       // extract low and high command nibbles
399       command_byte = read_song_byte();   // implicitly increments song_pos
400       command_nibble_hi = command_byte >> 4;
401       command_nibble_lo = command_byte & 0xf;
402  
403       switch (command_nibble_hi)
404         {
405         case 0x0: command_0(command_nibble_lo); break;
406         case 0x1: command_1(command_nibble_lo); break;
407         case 0x2: command_2(command_nibble_lo); break;
408         case 0x3: command_3(command_nibble_lo); break;
409         case 0x4: command_4(command_nibble_lo); break;
410         case 0x5: command_5(command_nibble_lo); break;
411         case 0x6: command_6(command_nibble_lo); break;
412         case 0x7: command_7(command_nibble_lo); break;
413         case 0x8:
414           switch (command_nibble_lo)
415             {
416             case 1: command_81(); break;
417             case 2: command_82(); repeat_loop = false; break;
418             case 3: command_83(); break;
419             case 5: command_85(); break;
420             case 6: command_86(); break;
421             default: break; // maybe generate an error?
422             }
423           break;
424         case 0xE: command_E(); break;
425         case 0xF: command_F(); break;
426         default: break; // maybe generate an error?
427         }
428
429     } while (repeat_loop);
430 }
431
432
433 // --------------------------------------------------------
434 //    The commands supported by the U6 music file format
435 // --------------------------------------------------------
436
437 // ----------------------------------------
438 // Set octave and frequency, note off
439 // Format: 0c nn
440 // c = channel, nn = packed Adlib frequency
441 // ----------------------------------------
442 void Cu6mPlayer::command_0(int channel)
443 {
444   unsigned char freq_byte;
445   byte_pair freq_word;
446
447   freq_byte = read_song_byte();
448   freq_word = expand_freq_byte(freq_byte);
449   set_adlib_freq(channel,freq_word);
450 }
451
452
453 // ---------------------------------------------------
454 // Set octave and frequency, old note off, new note on
455 // Format: 1c nn
456 // c = channel, nn = packed Adlib frequency
457 // ---------------------------------------------------
458 void Cu6mPlayer::command_1(int channel)
459 {
460   unsigned char freq_byte;
461   byte_pair freq_word;
462
463   vb_direction_flag[channel] = 0;
464   vb_current_value[channel] = 0;
465  
466   freq_byte = read_song_byte();
467   freq_word = expand_freq_byte(freq_byte);
468   set_adlib_freq(channel,freq_word);
469
470   freq_word.hi = freq_word.hi | 0x20; // note on
471   set_adlib_freq(channel,freq_word);
472 }
473
474
475 // ----------------------------------------
476 // Set octave and frequency, note on
477 // Format: 2c nn
478 // c = channel, nn = packed Adlib frequency
479 // ----------------------------------------
480 void Cu6mPlayer::command_2(int channel)
481 {
482   unsigned char freq_byte;
483   byte_pair freq_word;
484  
485   freq_byte = read_song_byte();
486   freq_word = expand_freq_byte(freq_byte);
487   freq_word.hi = freq_word.hi | 0x20; // note on
488   set_adlib_freq(channel,freq_word);
489 }
490
491
492 // --------------------------------------
493 // Set "carrier mute factor"==not(volume)
494 // Format: 3c nn
495 // c = channel, nn = mute factor
496 // --------------------------------------
497 void Cu6mPlayer::command_3(int channel)
498 {
499   unsigned char mf_byte;
500
501   carrier_mf_signed_delta[channel] = 0;
502   mf_byte = read_song_byte();
503   set_carrier_mf(channel,mf_byte);
504 }
505
506
507 // ----------------------------------------
508 // set "modulator mute factor"==not(volume)
509 // Format: 4c nn
510 // c = channel, nn = mute factor
511 // ----------------------------------------
512 void Cu6mPlayer::command_4(int channel)
513 {
514   unsigned char mf_byte;
515
516   mf_byte = read_song_byte();
517   set_modulator_mf(channel,mf_byte);
518 }
519
520
521 // --------------------------------------------
522 // Set portamento (pitch slide)
523 // Format: 5c nn
524 // c = channel, nn = signed channel pitch delta
525 // --------------------------------------------
526 void Cu6mPlayer::command_5(int channel)
527 {
528   channel_freq_signed_delta[channel] = read_signed_song_byte();
529 }
530
531
532 // --------------------------------------------
533 // Set vibrato paramters
534 // Format: 6c mn
535 // c = channel
536 // m = vibrato double amplitude
537 // n = vibrato multiplier
538 // --------------------------------------------
539 void Cu6mPlayer::command_6(int channel)
540 {
541   unsigned char vb_parameters;
542
543   vb_parameters = read_song_byte();
544   vb_double_amplitude[channel] = vb_parameters >> 4; // high nibble
545   vb_multiplier[channel] = vb_parameters & 0xF; // low nibble
546 }
547
548
549 // ----------------------------------------
550 // Assign Adlib instrument to Adlib channel
551 // Format: 7c nn
552 // c = channel, nn = instrument number
553 // ----------------------------------------
554 void Cu6mPlayer::command_7(int channel)
555 {
556   int instrument_offset = instrument_offsets[read_song_byte()];
557   out_adlib_opcell(channel, false, 0x20, *(song_data + instrument_offset+0));
558   out_adlib_opcell(channel, false, 0x40, *(song_data + instrument_offset+1));
559   out_adlib_opcell(channel, false, 0x60, *(song_data + instrument_offset+2));
560   out_adlib_opcell(channel, false, 0x80, *(song_data + instrument_offset+3));
561   out_adlib_opcell(channel, false, 0xE0, *(song_data + instrument_offset+4));
562   out_adlib_opcell(channel, true, 0x20, *(song_data + instrument_offset+5));
563   out_adlib_opcell(channel, true, 0x40, *(song_data + instrument_offset+6));
564   out_adlib_opcell(channel, true, 0x60, *(song_data + instrument_offset+7));
565   out_adlib_opcell(channel, true, 0x80, *(song_data + instrument_offset+8));
566   out_adlib_opcell(channel, true, 0xE0, *(song_data + instrument_offset+9));
567   out_adlib(0xC0+channel, *(song_data + instrument_offset+10));
568 }
569
570
571 // -------------------------------------------
572 // Branch to a new subsong
573 // Format: 81 nn aa bb
574 // nn == number of times to repeat the subsong
575 // aa == subsong offset (low byte)
576 // bb == subsong offset (high byte)
577 // -------------------------------------------
578 void Cu6mPlayer::command_81()
579 {
580   subsong_info new_ss_info;
581  
582   new_ss_info.subsong_repetitions = read_song_byte();
583   new_ss_info.subsong_start = read_song_byte(); new_ss_info.subsong_start += read_song_byte() << 8;
584   new_ss_info.continue_pos = song_pos;
585
586   subsong_stack.push(new_ss_info);
587   song_pos = new_ss_info.subsong_start;
588 }
589
590
591 // ------------------------------------------------------------
592 // Stop interpreting commands for this timer tick
593 // Format: 82 nn
594 // nn == delay (in timer ticks) until further data will be read
595 // ------------------------------------------------------------
596 void Cu6mPlayer::command_82()
597 {
598   read_delay = read_song_byte();
599 }
600
601
602 // -----------------------------
603 // Adlib instrument data follows
604 // Format: 83 nn <11 bytes>
605 // nn == instrument number
606 // -----------------------------
607 void Cu6mPlayer::command_83()
608 {
609   unsigned char instrument_number = read_song_byte();
610   instrument_offsets[instrument_number] = song_pos;
611   song_pos += 11;
612 }
613
614
615 // ----------------------------------------------
616 // Set -1 mute factor slide (upward volume slide)
617 // Format: 85 cn
618 // c == channel
619 // n == slide delay
620 // ----------------------------------------------
621 void Cu6mPlayer::command_85()
622 {
623   unsigned char data_byte = read_song_byte();
624   int channel = data_byte >> 4; // high nibble
625   unsigned char slide_delay = data_byte & 0xF; // low nibble
626   carrier_mf_signed_delta[channel] = +1;
627   carrier_mf_mod_delay[channel] = slide_delay + 1;
628   carrier_mf_mod_delay_backup[channel] = slide_delay + 1;
629 }
630
631
632 // ------------------------------------------------
633 // Set +1 mute factor slide (downward volume slide)
634 // Format: 86 cn
635 // c == channel
636 // n == slide speed
637 // ------------------------------------------------
638 void Cu6mPlayer::command_86()
639 {
640   unsigned char data_byte = read_song_byte();
641   int channel = data_byte >> 4; // high nibble
642   unsigned char slide_delay = data_byte & 0xF; // low nibble
643   carrier_mf_signed_delta[channel] = -1;
644   carrier_mf_mod_delay[channel] = slide_delay + 1;
645   carrier_mf_mod_delay_backup[channel] = slide_delay + 1;
646 }
647
648
649 // --------------
650 // Set loop point
651 // Format: E?
652 // --------------
653 void Cu6mPlayer::command_E()
654 {
655   loop_position = song_pos;
656 }
657
658
659 // ---------------------------
660 // Return from current subsong
661 // Format: F?
662 // ---------------------------
663 void Cu6mPlayer::command_F()
664 {
665   if (!subsong_stack.empty())
666     {
667       subsong_info temp = subsong_stack.top();
668       subsong_stack.pop();
669       temp.subsong_repetitions--;
670       if (temp.subsong_repetitions==0)
671         {
672           song_pos = temp.continue_pos;
673         }
674       else
675         {
676           song_pos = temp.subsong_start;
677           subsong_stack.push(temp);
678         }
679     }
680   else
681     {
682       song_pos = loop_position;
683       songend = true;
684     }
685 }
686
687
688 // --------------------
689 // Additional functions
690 // --------------------
691
692 // This function decrements its argument, without allowing it to become negative.
693 void Cu6mPlayer::dec_clip(int& param)
694 {
695   param--;
696   if (param < 0) { param = 0; }
697 }
698
699
700 // Returns the byte at the current song position.
701 // Side effect: increments song_pos.
702 unsigned char Cu6mPlayer::read_song_byte()
703 {
704   unsigned char song_byte;
705   song_byte = song_data[song_pos];
706   song_pos++;
707   return(song_byte);
708 }
709
710
711 // Same as read_song_byte(), except that it returns a signed byte
712 signed char Cu6mPlayer::read_signed_song_byte()
713 {
714   unsigned char song_byte;
715   int signed_value;
716   song_byte = *(song_data + song_pos);
717   song_pos++;
718   if (song_byte <= 127)
719     {
720       signed_value = song_byte;
721     }
722   else
723     {
724       signed_value = (int)song_byte - 0x100;
725     }
726   return((signed char)signed_value);
727 }
728
729
730 Cu6mPlayer::byte_pair Cu6mPlayer::expand_freq_byte(unsigned char freq_byte)
731 {
732   const byte_pair freq_table[24] =
733     {
734       {0x00,0x00}, {0x58,0x01}, {0x82,0x01}, {0xB0,0x01},
735       {0xCC,0x01}, {0x03,0x02}, {0x41,0x02}, {0x86,0x02},
736       {0x00,0x00}, {0x6A,0x01}, {0x96,0x01}, {0xC7,0x01},
737       {0xE4,0x01}, {0x1E,0x02}, {0x5F,0x02}, {0xA8,0x02},
738       {0x00,0x00}, {0x47,0x01}, {0x6E,0x01}, {0x9A,0x01},
739       {0xB5,0x01}, {0xE9,0x01}, {0x24,0x02}, {0x66,0x02}
740     };
741
742   int packed_freq;
743   int octave;
744   byte_pair freq_word;
745
746   packed_freq = freq_byte & 0x1F;
747   octave = freq_byte >> 5;
748
749   // range check (not present in the original U6 music driver)
750   if (packed_freq >= 24) { packed_freq = 0; }
751
752   freq_word.hi = freq_table[packed_freq].hi + (octave << 2);
753   freq_word.lo = freq_table[packed_freq].lo;
754
755   return(freq_word);
756 }
757
758
759 void Cu6mPlayer::set_adlib_freq(int channel,Cu6mPlayer::byte_pair freq_word)
760 {
761   out_adlib(0xA0+channel,freq_word.lo);
762   out_adlib(0xB0+channel,freq_word.hi);
763   // update the Adlib register backups
764   channel_freq[channel] = freq_word;
765 }
766
767
768 // this function sets the Adlib frequency, but does not update the register backups
769 void Cu6mPlayer::set_adlib_freq_no_update(int channel,Cu6mPlayer::byte_pair freq_word)
770 {
771   out_adlib(0xA0+channel,freq_word.lo);
772   out_adlib(0xB0+channel,freq_word.hi);
773 }
774
775
776 void Cu6mPlayer::set_carrier_mf(int channel,unsigned char mute_factor)
777 {
778   out_adlib_opcell(channel,true,0x40,mute_factor);
779   carrier_mf[channel] = mute_factor;
780 }
781
782
783 void Cu6mPlayer::set_modulator_mf(int channel,unsigned char mute_factor)
784 {
785   out_adlib_opcell(channel,false,0x40,mute_factor);
786 }
787
788
789 void Cu6mPlayer::freq_slide(int channel)
790 {
791   byte_pair freq = channel_freq[channel];
792
793   long freq_word = freq.lo + (freq.hi << 8) + channel_freq_signed_delta[channel];
794   if (freq_word < 0) { freq_word += 0x10000; }
795   if (freq_word > 0xFFFF) { freq_word -= 0x10000; }
796
797   freq.lo = freq_word & 0xFF;
798   freq.hi = (freq_word >> 8) & 0xFF;
799   set_adlib_freq(channel,freq);
800 }
801
802
803 void Cu6mPlayer::vibrato(int channel)
804 {
805   byte_pair freq;
806
807   if (vb_current_value[channel] >= vb_double_amplitude[channel])
808     { vb_direction_flag[channel] = 1; }
809   else if (vb_current_value[channel] <= 0)
810     { vb_direction_flag[channel] = 0; }
811
812   if (vb_direction_flag[channel]==0)
813     { vb_current_value[channel]++; }
814   else
815     { vb_current_value[channel]--; }
816
817   long freq_word = channel_freq[channel].lo + (channel_freq[channel].hi << 8);
818   freq_word += (vb_current_value[channel] - (vb_double_amplitude[channel] >> 1))
819     * vb_multiplier[channel];
820   if (freq_word < 0) { freq_word += 0x10000; }
821   if (freq_word > 0xFFFF) { freq_word -= 0x10000; }
822
823   freq.lo = freq_word & 0xFF;
824   freq.hi = (freq_word >> 8) & 0xFF;
825   set_adlib_freq_no_update(channel,freq);
826 }
827
828
829 void Cu6mPlayer::mf_slide(int channel)
830 {
831   carrier_mf_mod_delay[channel]--;
832   if (carrier_mf_mod_delay[channel]==0)
833     {
834       carrier_mf_mod_delay[channel] = carrier_mf_mod_delay_backup[channel];
835       int current_mf = carrier_mf[channel] + carrier_mf_signed_delta[channel];
836       if (current_mf > 0x3F)
837         {
838           current_mf = 0x3F;
839           carrier_mf_signed_delta[channel] = 0;
840         }
841       else if (current_mf < 0)
842         {
843           current_mf = 0;
844           carrier_mf_signed_delta[channel] = 0;
845         }
846
847       set_carrier_mf(channel,(unsigned char)current_mf);
848     }
849 }
850
851
852 void Cu6mPlayer::out_adlib(unsigned char adlib_register, unsigned char adlib_data)
853 {
854   opl->write(adlib_register,adlib_data);
855 }
856
857
858 void Cu6mPlayer::out_adlib_opcell(int channel, bool carrier, unsigned char adlib_register, unsigned char out_byte)
859 {
860   const unsigned char adlib_channel_to_carrier_offset[9] =
861     {0x03,0x04,0x05,0x0B,0x0C,0x0D,0x13,0x14,0x15};
862   const unsigned char adlib_channel_to_modulator_offset[9] =
863     {0x00,0x01,0x02,0x08,0x09,0x0A,0x10,0x11,0x12};
864
865   if (carrier)
866     {
867       out_adlib(adlib_register+adlib_channel_to_carrier_offset[channel],out_byte);
868     }
869   else
870     {
871       out_adlib(adlib_register+adlib_channel_to_modulator_offset[channel],out_byte);
872     }
873 }
874
875
876 // ============================================================================================
877 //
878 //
879 //    The Dictionary
880 //
881 //
882 // ============================================================================================
883
884
885 Cu6mPlayer::MyDict::MyDict()
886 {
887   dict_size = default_dict_size;
888   dictionary = new dict_entry[dict_size-0x100]; // don't allocate space for the roots
889   contains = 0x102;
890 }
891
892
893 Cu6mPlayer::MyDict::MyDict(int max_size)
894 {
895   dict_size = max_size;
896   dictionary = new dict_entry[dict_size-0x100]; // don't allocate space for the roots
897   contains = 0x102;
898 }
899
900
901 Cu6mPlayer::MyDict::~MyDict()
902 {
903   delete [] dictionary;
904 }
905
906 // re-initializes the dictionary
907 void Cu6mPlayer::MyDict::reset()
908 {
909   contains = 0x102;
910 }
911
912
913 // Note: If the dictionary is already full, this function does nothing.
914 void Cu6mPlayer::MyDict::add(unsigned char root, int codeword)
915 {
916   if (contains < dict_size)
917     {
918       dictionary[contains-0x100].root = root;
919       dictionary[contains-0x100].codeword = codeword;
920       contains++;
921     }
922 }
923
924
925 unsigned char Cu6mPlayer::MyDict::get_root(int codeword)
926 {
927   return (dictionary[codeword-0x100].root);
928 }
929
930
931 int Cu6mPlayer::MyDict::get_codeword(int codeword)
932 {
933   return (dictionary[codeword-0x100].codeword);
934 }