2 * adl.cpp - ADL player adaption by Simon Peter <dn.tlp@gmx.net>
4 * Original ADL player by Torbjorn Andersson and Johannes Schickel
5 * 'lordhoto' <lordhoto at scummvm dot org> of the ScummVM project.
8 /* ScummVM - Scumm Interpreter
10 * This file is licensed under both GPL and LGPL
11 * Copyright (C) 2006 The ScummVM project
12 * Copyright (C) 2006 Torbjorn Andersson and Johannes Schickel
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
32 * This library is free software; you can redistribute it and/or
33 * modify it under the terms of the GNU Lesser General Public
34 * License as published by the Free Software Foundation; either
35 * version 2.1 of the License, or (at your option) any later version.
37 * This library is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
40 * Lesser General Public License for more details.
42 * You should have received a copy of the GNU Lesser General Public
43 * License along with this library; if not, write to the Free Software
44 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
46 * $URL: https://svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/kyra/sound_adlib.cpp $
47 * $Id: adl.cpp,v 1.11 2008/02/11 20:18:27 dynamite Exp $
60 # define warning(...) AdPlug_LogWrite(__VA_ARGS__); \
63 # define debugC(i1, i2, ...) AdPlug_LogWrite(__VA_ARGS__); \
66 # define kDebugLevelSound 1
68 static inline void warning(const char *str, ...)
72 static inline void debugC(int i1, int i2, const char *str, ...)
77 // #define warning(...)
78 // #define debugC(i1, i2, ...)
80 #define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
82 // Basic Adlib Programming:
83 // http://www.gamedev.net/reference/articles/article446.asp
85 #define CALLBACKS_PER_SECOND 72
87 typedef uint8_t uint8;
89 typedef uint16_t uint16;
90 typedef int16_t int16;
91 typedef uint32_t uint32;
92 typedef int32_t int32;
95 static inline uint16 READ_LE_UINT16(const void *ptr) {
96 const byte *b = (const byte *)ptr;
97 return (b[1] << 8) + b[0];
100 static inline uint16 READ_BE_UINT16(const void *ptr) {
101 const byte *b = (const byte *)ptr;
102 return (b[0] << 8) + b[1];
107 AdlibDriver(Copl *opl);
110 int callback(int opcode, ...);
114 // int readBuffer(int16 *buffer, const int numSamples) {
115 // int32 samplesLeft = numSamples;
116 // memset(buffer, 0, sizeof(int16) * numSamples);
117 // while (samplesLeft) {
118 // if (!_samplesTillCallback) {
120 // _samplesTillCallback = _samplesPerCallback;
121 // _samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
122 // if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) {
123 // _samplesTillCallback++;
124 // _samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND;
128 // int32 render = MIN(samplesLeft, _samplesTillCallback);
129 // samplesLeft -= render;
130 // _samplesTillCallback -= render;
131 // YM3812UpdateOne(_adlib, buffer, render);
134 // return numSamples;
137 bool isStereo() const { return false; }
138 bool endOfData() const { return false; }
139 // int getRate() const { return _mixer->getOutputRate(); }
142 typedef int (AdlibDriver::*DriverOpcode)(va_list &list);
143 DriverOpcode function;
147 void setupOpcodeList();
148 const OpcodeEntry *_opcodeList;
151 int snd_ret0x100(va_list &list);
152 int snd_ret0x1983(va_list &list);
153 int snd_initDriver(va_list &list);
154 int snd_deinitDriver(va_list &list);
155 int snd_setSoundData(va_list &list);
156 int snd_unkOpcode1(va_list &list);
157 int snd_startSong(va_list &list);
158 int snd_unkOpcode2(va_list &list);
159 int snd_unkOpcode3(va_list &list);
160 int snd_readByte(va_list &list);
161 int snd_writeByte(va_list &list);
162 int snd_getSoundTrigger(va_list &list);
163 int snd_unkOpcode4(va_list &list);
164 int snd_dummy(va_list &list);
165 int snd_getNullvar4(va_list &list);
166 int snd_setNullvar3(va_list &list);
167 int snd_setFlag(va_list &list);
168 int snd_clearFlag(va_list &list);
170 // These variables have not yet been named, but some of them are partly
171 // known nevertheless:
173 // unk16 - Sound-related. Possibly some sort of pitch bend.
174 // unk18 - Sound-effect. Used for secondaryEffect1()
175 // unk19 - Sound-effect. Used for secondaryEffect1()
176 // unk20 - Sound-effect. Used for secondaryEffect1()
177 // unk21 - Sound-effect. Used for secondaryEffect1()
178 // unk22 - Sound-effect. Used for secondaryEffect1()
179 // unk29 - Sound-effect. Used for primaryEffect1()
180 // unk30 - Sound-effect. Used for primaryEffect1()
181 // unk31 - Sound-effect. Used for primaryEffect1()
182 // unk32 - Sound-effect. Used for primaryEffect2()
183 // unk33 - Sound-effect. Used for primaryEffect2()
184 // unk34 - Sound-effect. Used for primaryEffect2()
185 // unk35 - Sound-effect. Used for primaryEffect2()
186 // unk36 - Sound-effect. Used for primaryEffect2()
187 // unk37 - Sound-effect. Used for primaryEffect2()
188 // unk38 - Sound-effect. Used for primaryEffect2()
189 // unk39 - Currently unused, except for updateCallback56()
190 // unk40 - Currently unused, except for updateCallback56()
191 // unk41 - Sound-effect. Used for primaryEffect2()
200 uint8 dataptrStackPos;
201 uint8 *dataptrStack[4];
221 typedef void (AdlibDriver::*Callback)(Channel&);
222 Callback primaryEffect;
223 Callback secondaryEffect;
224 uint8 fractionalSpacing;
232 uint8 durationRandomness;
244 void primaryEffect1(Channel &channel);
245 void primaryEffect2(Channel &channel);
246 void secondaryEffect1(Channel &channel);
248 void resetAdlibState();
249 void writeOPL(byte reg, byte val);
250 void initChannel(Channel &channel);
251 void noteOff(Channel &channel);
252 void unkOutput2(uint8 num);
254 uint16 getRandomNr();
255 void setupDuration(uint8 duration, Channel &channel);
257 void setupNote(uint8 rawNote, Channel &channel, bool flag = false);
258 void setupInstrument(uint8 regOffset, uint8 *dataptr, Channel &channel);
259 void noteOn(Channel &channel);
261 void adjustVolume(Channel &channel);
263 uint8 calculateOpLevel1(Channel &channel);
264 uint8 calculateOpLevel2(Channel &channel);
266 uint16 checkValue(int16 val) {
274 // The sound data has at least two lookup tables:
276 // * One for programs, starting at offset 0.
277 // * One for instruments, starting at offset 500.
279 uint8 *getProgram(int progId) {
280 return _soundData + READ_LE_UINT16(_soundData + 2 * progId);
283 uint8 *getInstrument(int instrumentId) {
284 return _soundData + READ_LE_UINT16(_soundData + 500 + 2 * instrumentId);
287 void setupPrograms();
288 void executePrograms();
290 struct ParserOpcode {
291 typedef int (AdlibDriver::*POpcode)(uint8 *&dataptr, Channel &channel, uint8 value);
296 void setupParserOpcodeTable();
297 const ParserOpcode *_parserOpcodeTable;
298 int _parserOpcodeTableSize;
300 int update_setRepeat(uint8 *&dataptr, Channel &channel, uint8 value);
301 int update_checkRepeat(uint8 *&dataptr, Channel &channel, uint8 value);
302 int update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 value);
303 int update_setNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value);
304 int update_jump(uint8 *&dataptr, Channel &channel, uint8 value);
305 int update_jumpToSubroutine(uint8 *&dataptr, Channel &channel, uint8 value);
306 int update_returnFromSubroutine(uint8 *&dataptr, Channel &channel, uint8 value);
307 int update_setBaseOctave(uint8 *&dataptr, Channel &channel, uint8 value);
308 int update_stopChannel(uint8 *&dataptr, Channel &channel, uint8 value);
309 int update_playRest(uint8 *&dataptr, Channel &channel, uint8 value);
310 int update_writeAdlib(uint8 *&dataptr, Channel &channel, uint8 value);
311 int update_setupNoteAndDuration(uint8 *&dataptr, Channel &channel, uint8 value);
312 int update_setBaseNote(uint8 *&dataptr, Channel &channel, uint8 value);
313 int update_setupSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
314 int update_stopOtherChannel(uint8 *&dataptr, Channel &channel, uint8 value);
315 int update_waitForEndOfProgram(uint8 *&dataptr, Channel &channel, uint8 value);
316 int update_setupInstrument(uint8 *&dataptr, Channel &channel, uint8 value);
317 int update_setupPrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
318 int update_removePrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
319 int update_setBaseFreq(uint8 *&dataptr, Channel &channel, uint8 value);
320 int update_setupPrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value);
321 int update_setPriority(uint8 *&dataptr, Channel &channel, uint8 value);
322 int updateCallback23(uint8 *&dataptr, Channel &channel, uint8 value);
323 int updateCallback24(uint8 *&dataptr, Channel &channel, uint8 value);
324 int update_setExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value);
325 int update_setupDuration(uint8 *&dataptr, Channel &channel, uint8 value);
326 int update_playNote(uint8 *&dataptr, Channel &channel, uint8 value);
327 int update_setFractionalNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value);
328 int update_setTempo(uint8 *&dataptr, Channel &channel, uint8 value);
329 int update_removeSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
330 int update_setChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value);
331 int update_setExtraLevel3(uint8 *&dataptr, Channel &channel, uint8 value);
332 int update_setExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value);
333 int update_changeExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value);
334 int update_setAMDepth(uint8 *&dataptr, Channel &channel, uint8 value);
335 int update_setVibratoDepth(uint8 *&dataptr, Channel &channel, uint8 value);
336 int update_changeExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value);
337 int updateCallback38(uint8 *&dataptr, Channel &channel, uint8 value);
338 int updateCallback39(uint8 *&dataptr, Channel &channel, uint8 value);
339 int update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value);
340 int updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value);
341 int update_resetToGlobalTempo(uint8 *&dataptr, Channel &channel, uint8 value);
342 int update_nop1(uint8 *&dataptr, Channel &channel, uint8 value);
343 int update_setDurationRandomness(uint8 *&dataptr, Channel &channel, uint8 value);
344 int update_changeChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value);
345 int updateCallback46(uint8 *&dataptr, Channel &channel, uint8 value);
346 int update_nop2(uint8 *&dataptr, Channel &channel, uint8 value);
347 int update_setupRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value);
348 int update_playRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value);
349 int update_removeRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value);
350 int updateCallback51(uint8 *&dataptr, Channel &channel, uint8 value);
351 int updateCallback52(uint8 *&dataptr, Channel &channel, uint8 value);
352 int updateCallback53(uint8 *&dataptr, Channel &channel, uint8 value);
353 int update_setSoundTrigger(uint8 *&dataptr, Channel &channel, uint8 value);
354 int update_setTempoReset(uint8 *&dataptr, Channel &channel, uint8 value);
355 int updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value);
357 // These variables have not yet been named, but some of them are partly
358 // known nevertheless:
360 // _unkValue1 - Unknown. Used for updating _unkValue2
361 // _unkValue2 - Unknown. Used for updating _unkValue4
362 // _unkValue3 - Unknown. Used for updating _unkValue2
363 // _unkValue4 - Unknown. Used for updating _unkValue5
364 // _unkValue5 - Unknown. Used for controlling updateCallback24().
365 // _unkValue6 - Unknown. Rhythm section volume?
366 // _unkValue7 - Unknown. Rhythm section volume?
367 // _unkValue8 - Unknown. Rhythm section volume?
368 // _unkValue9 - Unknown. Rhythm section volume?
369 // _unkValue10 - Unknown. Rhythm section volume?
370 // _unkValue11 - Unknown. Rhythm section volume?
371 // _unkValue12 - Unknown. Rhythm section volume?
372 // _unkValue13 - Unknown. Rhythm section volume?
373 // _unkValue14 - Unknown. Rhythm section volume?
374 // _unkValue15 - Unknown. Rhythm section volume?
375 // _unkValue16 - Unknown. Rhythm section volume?
376 // _unkValue17 - Unknown. Rhythm section volume?
377 // _unkValue18 - Unknown. Rhythm section volume?
378 // _unkValue19 - Unknown. Rhythm section volume?
379 // _unkValue20 - Unknown. Rhythm section volume?
380 // _unkTable[] - Probably frequences for the 12-tone scale.
381 // _unkTable2[] - Unknown. Currently only used by updateCallback46()
382 // _unkTable2_1[] - One of the tables in _unkTable2[]
383 // _unkTable2_2[] - One of the tables in _unkTable2[]
384 // _unkTable2_3[] - One of the tables in _unkTable2[]
386 int32 _samplesPerCallback;
387 int32 _samplesPerCallbackRemainder;
388 int32 _samplesTillCallback;
389 int32 _samplesTillCallbackRemainder;
424 uint8 _soundIdTable[0x10];
425 Channel _channels[10];
427 uint8 _vibratoAndAMDepthBits;
428 uint8 _rhythmSectionBits;
433 const uint8 *_tablePtr1;
434 const uint8 *_tablePtr2;
436 static const uint8 _regOffset[];
437 static const uint16 _unkTable[];
438 static const uint8 *_unkTable2[];
439 static const uint8 _unkTable2_1[];
440 static const uint8 _unkTable2_2[];
441 static const uint8 _unkTable2_3[];
442 static const uint8 _unkTables[][32];
447 AdlibDriver::AdlibDriver(Copl *newopl)
451 setupParserOpcodeTable();
456 // _adlib = makeAdlibOPL(getRate());
459 memset(_channels, 0, sizeof(_channels));
462 _vibratoAndAMDepthBits = _curRegOffset = 0;
464 _lastProcessed = _flagTrigger = _curChannel = _rhythmSectionBits = 0;
472 _unkValue1 = _unkValue2 = _unkValue4 = _unkValue5 = 0;
473 _unkValue6 = _unkValue7 = _unkValue8 = _unkValue9 = _unkValue10 = 0;
474 _unkValue11 = _unkValue12 = _unkValue13 = _unkValue14 = _unkValue15 =
475 _unkValue16 = _unkValue17 = _unkValue18 = _unkValue19 = _unkValue20 = 0;
477 _tablePtr1 = _tablePtr2 = 0;
479 // _mixer->setupPremix(this);
481 // _samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
482 // _samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
483 _samplesTillCallback = 0;
484 _samplesTillCallbackRemainder = 0;
487 AdlibDriver::~AdlibDriver() {
488 // _mixer->setupPremix(0);
489 // OPLDestroy(_adlib);
493 int AdlibDriver::callback(int opcode, ...) {
495 if (opcode >= _opcodesEntries || opcode < 0) {
496 warning("AdlibDriver: calling unknown opcode '%d'", opcode);
500 debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d)", _opcodeList[opcode].name, opcode);
503 va_start(args, opcode);
504 int returnValue = (this->*(_opcodeList[opcode].function))(args);
512 int AdlibDriver::snd_ret0x100(va_list &list) {
516 int AdlibDriver::snd_ret0x1983(va_list &list) {
520 int AdlibDriver::snd_initDriver(va_list &list) {
521 _lastProcessed = _soundsPlaying = 0;
526 int AdlibDriver::snd_deinitDriver(va_list &list) {
531 int AdlibDriver::snd_setSoundData(va_list &list) {
533 delete [] _soundData;
536 _soundData = va_arg(list, uint8*);
540 int AdlibDriver::snd_unkOpcode1(va_list &list) {
541 warning("unimplemented snd_unkOpcode1");
545 int AdlibDriver::snd_startSong(va_list &list) {
546 int songId = va_arg(list, int);
550 uint8 *ptr = getProgram(songId);
553 if ((songId << 1) != 0) {
563 _soundIdTable[_soundsPlaying++] = songId;
564 _soundsPlaying &= 0x0F;
569 int AdlibDriver::snd_unkOpcode2(va_list &list) {
570 warning("unimplemented snd_unkOpcode2");
574 int AdlibDriver::snd_unkOpcode3(va_list &list) {
575 int value = va_arg(list, int);
586 Channel &channel = _channels[_curChannel];
587 channel.priority = 0;
598 int AdlibDriver::snd_readByte(va_list &list) {
599 int a = va_arg(list, int);
600 int b = va_arg(list, int);
601 uint8 *ptr = getProgram(a) + b;
605 int AdlibDriver::snd_writeByte(va_list &list) {
606 int a = va_arg(list, int);
607 int b = va_arg(list, int);
608 int c = va_arg(list, int);
609 uint8 *ptr = getProgram(a) + b;
610 uint8 oldValue = *ptr;
615 int AdlibDriver::snd_getSoundTrigger(va_list &list) {
616 return _soundTrigger;
619 int AdlibDriver::snd_unkOpcode4(va_list &list) {
620 warning("unimplemented snd_unkOpcode4");
624 int AdlibDriver::snd_dummy(va_list &list) {
628 int AdlibDriver::snd_getNullvar4(va_list &list) {
629 warning("unimplemented snd_getNullvar4");
633 int AdlibDriver::snd_setNullvar3(va_list &list) {
634 warning("unimplemented snd_setNullvar3");
638 int AdlibDriver::snd_setFlag(va_list &list) {
639 int oldFlags = _flags;
640 _flags |= va_arg(list, int);
644 int AdlibDriver::snd_clearFlag(va_list &list) {
645 int oldFlags = _flags;
646 _flags &= ~(va_arg(list, int));
652 void AdlibDriver::callback() {
655 if (_flagTrigger < 0)
660 uint8 temp = _unkValue3;
661 _unkValue3 += _tempo;
662 if (_unkValue3 < temp) {
663 if (!(--_unkValue2)) {
664 _unkValue2 = _unkValue1;
671 void AdlibDriver::setupPrograms() {
672 while (_lastProcessed != _soundsPlaying) {
673 uint8 *ptr = getProgram(_soundIdTable[_lastProcessed]);
675 uint8 priority = *ptr++;
677 // Only start this sound if its priority is higher than the one
680 Channel &channel = _channels[chan];
682 if (priority >= channel.priority) {
683 initChannel(channel);
684 channel.priority = priority;
685 channel.dataptr = ptr;
686 channel.tempo = 0xFF;
687 channel.position = 0xFF;
688 channel.duration = 1;
693 _lastProcessed &= 0x0F;
697 // A few words on opcode parsing and timing:
699 // First of all, We simulate a timer callback 72 times per second. Each timeout
700 // we update each channel that has something to play.
702 // Each channel has its own individual tempo, which is added to its position.
703 // This will frequently cause the position to "wrap around" but that is
704 // intentional. In fact, it's the signal to go ahead and do more stuff with
707 // Each channel also has a duration, indicating how much time is left on the
708 // its current task. This duration is decreased by one. As long as it still has
709 // not reached zero, the only thing that can happen is that the note is turned
710 // off depending on manual or automatic note spacing. Once the duration reaches
711 // zero, a new set of musical opcodes are executed.
713 // An opcode is one byte, followed by a variable number of parameters. Since
714 // most opcodes have at least one one-byte parameter, we read that as well. Any
715 // opcode that doesn't have that one parameter is responsible for moving the
716 // data pointer back again.
718 // If the most significant bit of the opcode is 1, it's a function; call it.
719 // The opcode functions return either 0 (continue), 1 (stop) or 2 (stop, and do
720 // not run the effects callbacks).
722 // If the most significant bit of the opcode is 0, it's a note, and the first
723 // parameter is its duration. (There are cases where the duration is modified
724 // but that's an exception.) The note opcode is assumed to return 1, and is the
725 // last opcode unless its duration is zero.
727 // Finally, most of the times that the callback is called, it will invoke the
728 // effects callbacks. The final opcode in a set can prevent this, if it's a
729 // function and it returns anything other than 1.
731 void AdlibDriver::executePrograms() {
732 // Each channel runs its own program. There are ten channels: One for
733 // each Adlib channel (0-8), plus one "control channel" (9) which is
734 // the one that tells the other channels what to do.
736 for (_curChannel = 9; _curChannel >= 0; --_curChannel) {
739 if (!_channels[_curChannel].dataptr) {
743 Channel &channel = _channels[_curChannel];
744 _curRegOffset = _regOffset[_curChannel];
746 if (channel.tempoReset) {
747 channel.tempo = _tempo;
750 uint8 backup = channel.position;
751 channel.position += channel.tempo;
752 if (channel.position < backup) {
753 if (--channel.duration) {
754 if (channel.duration == channel.spacing2)
756 if (channel.duration == channel.spacing1 && _curChannel != 9)
759 // An opcode is not allowed to modify its own
760 // data pointer except through the 'dataptr'
761 // parameter. To enforce that, we have to work
762 // on a copy of the data pointer.
764 // This fixes a subtle music bug where the
765 // wrong music would play when getting the
767 uint8 *dataptr = channel.dataptr;
769 uint8 opcode = *dataptr++;
770 uint8 param = *dataptr++;
774 if (opcode >= _parserOpcodeTableSize)
775 opcode = _parserOpcodeTableSize - 1;
776 debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d) (channel: %d)", _parserOpcodeTable[opcode].name, opcode, _curChannel);
777 result = (this->*(_parserOpcodeTable[opcode].function))(dataptr, channel, param);
778 channel.dataptr = dataptr;
782 debugC(9, kDebugLevelSound, "Note on opcode 0x%02X (duration: %d) (channel: %d)", opcode, param, _curChannel);
783 setupNote(opcode, channel);
785 setupDuration(param, channel);
787 channel.dataptr = dataptr;
796 if (channel.primaryEffect)
797 (this->*(channel.primaryEffect))(channel);
798 if (channel.secondaryEffect)
799 (this->*(channel.secondaryEffect))(channel);
806 void AdlibDriver::resetAdlibState() {
807 debugC(9, kDebugLevelSound, "resetAdlibState()");
810 // Authorize the control of the waveforms
811 writeOPL(0x01, 0x20);
813 // Select FM music mode
814 writeOPL(0x08, 0x00);
816 // I would guess the main purpose of this is to turn off the rhythm,
817 // thus allowing us to use 9 melodic voices instead of 6.
818 writeOPL(0xBD, 0x00);
823 // Silence the channel
824 writeOPL(0x40 + _regOffset[loop], 0x3F);
825 writeOPL(0x43 + _regOffset[loop], 0x3F);
827 initChannel(_channels[loop]);
831 // Old calling style: output0x388(0xABCD)
832 // New calling style: writeOPL(0xAB, 0xCD)
834 void AdlibDriver::writeOPL(byte reg, byte val) {
835 opl->write(reg, val);
838 void AdlibDriver::initChannel(Channel &channel) {
839 debugC(9, kDebugLevelSound, "initChannel(%lu)", (long)(&channel - _channels));
840 memset(&channel.dataptr, 0, sizeof(Channel) - ((char*)&channel.dataptr - (char*)&channel));
842 channel.tempo = 0xFF;
843 channel.priority = 0;
844 // normally here are nullfuncs but we set 0 for now
845 channel.primaryEffect = 0;
846 channel.secondaryEffect = 0;
847 channel.spacing1 = 1;
850 void AdlibDriver::noteOff(Channel &channel) {
851 debugC(9, kDebugLevelSound, "noteOff(%lu)", (long)(&channel - _channels));
853 // The control channel has no corresponding Adlib channel
855 if (_curChannel >= 9)
858 // When the rhythm section is enabled, channels 6, 7 and 8 are special.
860 if (_rhythmSectionBits && _curChannel >= 6)
863 // This means the "Key On" bit will always be 0
864 channel.regBx &= 0xDF;
866 // Octave / F-Number / Key-On
867 writeOPL(0xB0 + _curChannel, channel.regBx);
870 void AdlibDriver::unkOutput2(uint8 chan) {
871 debugC(9, kDebugLevelSound, "unkOutput2(%d)", chan);
873 // The control channel has no corresponding Adlib channel
878 // I believe this has to do with channels 6, 7, and 8 being special
879 // when Adlib's rhythm section is enabled.
881 if (_rhythmSectionBits && chan >= 6)
884 uint8 offset = _regOffset[chan];
886 // The channel is cleared: First the attack/delay rate, then the
887 // sustain level/release rate, and finally the note is turned off.
889 writeOPL(0x60 + offset, 0xFF);
890 writeOPL(0x63 + offset, 0xFF);
892 writeOPL(0x80 + offset, 0xFF);
893 writeOPL(0x83 + offset, 0xFF);
895 writeOPL(0xB0 + chan, 0x00);
897 // ...and then the note is turned on again, with whatever value is
898 // still lurking in the A0 + chan register, but everything else -
899 // including the two most significant frequency bit, and the octave -
902 // This is very strange behaviour, and causes problems with the ancient
903 // FMOPL code we borrowed from AdPlug. I've added a workaround. See
904 // fmopl.cpp for more details.
906 // More recent versions of the MAME FMOPL don't seem to have this
907 // problem, but cannot currently be used because of licensing and
908 // performance issues.
910 // Ken Silverman's Adlib emulator (which can be found on his Web page -
911 // http://www.advsys.net/ken - and as part of AdPlug) also seems to be
912 // immune, but is apparently not as feature complete as MAME's.
914 writeOPL(0xB0 + chan, 0x20);
917 // I believe this is a random number generator. It actually does seem to
918 // generate an even distribution of almost all numbers from 0 through 65535,
919 // though in my tests some numbers were never generated.
921 uint16 AdlibDriver::getRandomNr() {
923 uint16 lowBits = _rnd & 7;
925 _rnd |= (lowBits << 13);
929 void AdlibDriver::setupDuration(uint8 duration, Channel &channel) {
930 debugC(9, kDebugLevelSound, "setupDuration(%d, %lu)", duration, (long)(&channel - _channels));
931 if (channel.durationRandomness) {
932 channel.duration = duration + (getRandomNr() & channel.durationRandomness);
935 if (channel.fractionalSpacing) {
936 channel.spacing2 = (duration >> 3) * channel.fractionalSpacing;
938 channel.duration = duration;
941 // This function may or may not play the note. It's usually followed by a call
942 // to noteOn(), which will always play the current note.
944 void AdlibDriver::setupNote(uint8 rawNote, Channel &channel, bool flag) {
945 debugC(9, kDebugLevelSound, "setupNote(%d, %lu)", rawNote, (long)(&channel - _channels));
947 channel.rawNote = rawNote;
949 int8 note = (rawNote & 0x0F) + channel.baseNote;
950 int8 octave = ((rawNote + channel.baseOctave) >> 4) & 0x0F;
952 // There are only twelve notes. If we go outside that, we have to
953 // adjust the note and octave.
958 } else if (note < 0) {
963 // The calculation of frequency looks quite different from the original
964 // disassembly at a first glance, but when you consider that the
965 // largest possible value would be 0x0246 + 0xFF + 0x47 (and that's if
966 // baseFreq is unsigned), freq is still a 10-bit value, just as it
967 // should be to fit in the Ax and Bx registers.
969 // If it were larger than that, it could have overflowed into the
970 // octave bits, and that could possibly have been used in some sound.
971 // But as it is now, I can't see any way it would happen.
973 uint16 freq = _unkTable[note] + channel.baseFreq;
975 // When called from callback 41, the behaviour is slightly different:
976 // We adjust the frequency, even when channel.unk16 is 0.
978 if (channel.unk16 || flag) {
981 if (channel.unk16 >= 0) {
982 table = _unkTables[(channel.rawNote & 0x0F) + 2];
983 freq += table[channel.unk16];
985 table = _unkTables[channel.rawNote & 0x0F];
986 freq -= table[-channel.unk16];
990 channel.regAx = freq & 0xFF;
991 channel.regBx = (channel.regBx & 0x20) | (octave << 2) | ((freq >> 8) & 0x03);
993 // Keep the note on or off
994 writeOPL(0xA0 + _curChannel, channel.regAx);
995 writeOPL(0xB0 + _curChannel, channel.regBx);
998 void AdlibDriver::setupInstrument(uint8 regOffset, uint8 *dataptr, Channel &channel) {
999 debugC(9, kDebugLevelSound, "setupInstrument(%d, %p, %lu)", regOffset, (const void *)dataptr, (long)(&channel - _channels));
1000 // Amplitude Modulation / Vibrato / Envelope Generator Type /
1001 // Keyboard Scaling Rate / Modulator Frequency Multiple
1002 writeOPL(0x20 + regOffset, *dataptr++);
1003 writeOPL(0x23 + regOffset, *dataptr++);
1005 uint8 temp = *dataptr++;
1007 // Feedback / Algorithm
1009 // It is very likely that _curChannel really does refer to the same
1010 // channel as regOffset, but there's only one Cx register per channel.
1012 writeOPL(0xC0 + _curChannel, temp);
1014 // The algorithm bit. I don't pretend to understand this fully, but
1015 // "If set to 0, operator 1 modulates operator 2. In this case,
1016 // operator 2 is the only one producing sound. If set to 1, both
1017 // operators produce sound directly. Complex sounds are more easily
1018 // created if the algorithm is set to 0."
1020 channel.twoChan = temp & 1;
1023 writeOPL(0xE0 + regOffset, *dataptr++);
1024 writeOPL(0xE3 + regOffset, *dataptr++);
1026 channel.opLevel1 = *dataptr++;
1027 channel.opLevel2 = *dataptr++;
1029 // Level Key Scaling / Total Level
1030 writeOPL(0x40 + regOffset, calculateOpLevel1(channel));
1031 writeOPL(0x43 + regOffset, calculateOpLevel2(channel));
1033 // Attack Rate / Decay Rate
1034 writeOPL(0x60 + regOffset, *dataptr++);
1035 writeOPL(0x63 + regOffset, *dataptr++);
1037 // Sustain Level / Release Rate
1038 writeOPL(0x80 + regOffset, *dataptr++);
1039 writeOPL(0x83 + regOffset, *dataptr++);
1042 // Apart from playing the note, this function also updates the variables for
1043 // primary effect 2.
1045 void AdlibDriver::noteOn(Channel &channel) {
1046 debugC(9, kDebugLevelSound, "noteOn(%lu)", (long)(&channel - _channels));
1048 // The "note on" bit is set, and the current note is played.
1050 channel.regBx |= 0x20;
1051 writeOPL(0xB0 + _curChannel, channel.regBx);
1053 int8 shift = 9 - channel.unk33;
1054 uint16 temp = channel.regAx | (channel.regBx << 8);
1055 channel.unk37 = ((temp & 0x3FF) >> shift) & 0xFF;
1056 channel.unk38 = channel.unk36;
1059 void AdlibDriver::adjustVolume(Channel &channel) {
1060 debugC(9, kDebugLevelSound, "adjustVolume(%lu)", (long)(&channel - _channels));
1061 // Level Key Scaling / Total Level
1063 writeOPL(0x43 + _regOffset[_curChannel], calculateOpLevel2(channel));
1064 if (channel.twoChan)
1065 writeOPL(0x40 + _regOffset[_curChannel], calculateOpLevel1(channel));
1068 // This is presumably only used for some sound effects, e.g. Malcolm blowing up
1069 // the trees in the intro (but not the effect where he "booby-traps" the big
1070 // tree) and turning Kallak to stone. Related functions and variables:
1072 // update_setupPrimaryEffect1()
1073 // - Initialises unk29, unk30 and unk31
1074 // - unk29 is not further modified
1075 // - unk30 is not further modified, except by update_removePrimaryEffect1()
1077 // update_removePrimaryEffect1()
1078 // - Deinitialises unk30
1080 // unk29 - determines how often the notes are played
1081 // unk30 - modifies the frequency
1082 // unk31 - determines how often the notes are played
1084 void AdlibDriver::primaryEffect1(Channel &channel) {
1085 debugC(9, kDebugLevelSound, "Calling primaryEffect1 (channel: %d)", _curChannel);
1086 uint8 temp = channel.unk31;
1087 channel.unk31 += channel.unk29;
1088 if (channel.unk31 >= temp)
1091 // Initialise unk1 to the current frequency
1092 uint16 unk1 = ((channel.regBx & 3) << 8) | channel.regAx;
1094 // This is presumably to shift the "note on" bit so far to the left
1095 // that it won't be affected by any of the calculations below.
1096 uint16 unk2 = ((channel.regBx & 0x20) << 8) | (channel.regBx & 0x1C);
1098 int16 unk3 = (int16)channel.unk30;
1103 // The new frequency is too high. Shift it down and go
1106 if (!(unk1 & 0x3FF))
1108 unk2 = (unk2 & 0xFF00) | ((unk2 + 4) & 0xFF);
1114 // The new frequency is too low. Shift it up and go
1117 if (!(unk1 & 0x3FF))
1119 unk2 = (unk2 & 0xFF00) | ((unk2 - 4) & 0xFF);
1124 // Make sure that the new frequency is still a 10-bit value.
1127 writeOPL(0xA0 + _curChannel, unk1 & 0xFF);
1128 channel.regAx = unk1 & 0xFF;
1130 // Shift down the "note on" bit again.
1131 uint8 value = unk1 >> 8;
1132 value |= (unk2 >> 8) & 0xFF;
1133 value |= unk2 & 0xFF;
1135 writeOPL(0xB0 + _curChannel, value);
1136 channel.regBx = value;
1139 // This is presumably only used for some sound effects, e.g. Malcolm entering
1140 // and leaving Kallak's hut. Related functions and variables:
1142 // update_setupPrimaryEffect2()
1143 // - Initialises unk32, unk33, unk34, unk35 and unk36
1144 // - unk32 is not further modified
1145 // - unk33 is not further modified
1146 // - unk34 is a countdown that gets reinitialised to unk35 on zero
1147 // - unk35 is based on unk34 and not further modified
1148 // - unk36 is not further modified
1151 // - Plays the current note
1152 // - Updates unk37 with a new (lower?) frequency
1153 // - Copies unk36 to unk38. The unk38 variable is a countdown.
1155 // unk32 - determines how often the notes are played
1156 // unk33 - modifies the frequency
1157 // unk34 - countdown, updates frequency on zero
1158 // unk35 - initialiser for unk34 countdown
1159 // unk36 - initialiser for unk38 countdown
1160 // unk37 - frequency
1161 // unk38 - countdown, begins playing on zero
1162 // unk41 - determines how often the notes are played
1164 // Note that unk41 is never initialised. Not that it should matter much, but it
1167 void AdlibDriver::primaryEffect2(Channel &channel) {
1168 debugC(9, kDebugLevelSound, "Calling primaryEffect2 (channel: %d)", _curChannel);
1169 if (channel.unk38) {
1174 uint8 temp = channel.unk41;
1175 channel.unk41 += channel.unk32;
1176 if (channel.unk41 < temp) {
1177 uint16 unk1 = channel.unk37;
1178 if (!(--channel.unk34)) {
1181 channel.unk37 = unk1;
1182 channel.unk34 = channel.unk35;
1185 uint16 unk2 = (channel.regAx | (channel.regBx << 8)) & 0x3FF;
1188 channel.regAx = unk2 & 0xFF;
1189 channel.regBx = (channel.regBx & 0xFC) | (unk2 >> 8);
1191 // Octave / F-Number / Key-On
1192 writeOPL(0xA0 + _curChannel, channel.regAx);
1193 writeOPL(0xB0 + _curChannel, channel.regBx);
1197 // I don't know where this is used. The same operation is performed several
1198 // times on the current channel, using a chunk of the _soundData[] buffer for
1199 // parameters. The parameters are used starting at the end of the chunk.
1201 // Since we use _curRegOffset to specify the final register, it's quite
1202 // unlikely that this function is ever used to play notes. It's probably only
1203 // used to modify the sound. Another thing that supports this idea is that it
1204 // can be combined with any of the effects callbacks above.
1206 // Related functions and variables:
1208 // update_setupSecondaryEffect1()
1209 // - Initialies unk18, unk19, unk20, unk21, unk22 and offset
1210 // - unk19 is not further modified
1211 // - unk20 is not further modified
1212 // - unk22 is not further modified
1213 // - offset is not further modified
1215 // unk18 - determines how often the operation is performed
1216 // unk19 - determines how often the operation is performed
1217 // unk20 - the start index into the data chunk
1218 // unk21 - the current index into the data chunk
1219 // unk22 - the operation to perform
1220 // offset - the offset to the data chunk
1222 void AdlibDriver::secondaryEffect1(Channel &channel) {
1223 debugC(9, kDebugLevelSound, "Calling secondaryEffect1 (channel: %d)", _curChannel);
1224 uint8 temp = channel.unk18;
1225 channel.unk18 += channel.unk19;
1226 if (channel.unk18 < temp) {
1227 if (--channel.unk21 < 0) {
1228 channel.unk21 = channel.unk20;
1230 writeOPL(channel.unk22 + _curRegOffset, _soundData[channel.offset + channel.unk21]);
1234 uint8 AdlibDriver::calculateOpLevel1(Channel &channel) {
1235 int8 value = channel.opLevel1 & 0x3F;
1237 if (channel.twoChan) {
1238 value += channel.opExtraLevel1;
1239 value += channel.opExtraLevel2;
1240 value += channel.opExtraLevel3;
1243 // Preserve the scaling level bits from opLevel1
1245 return checkValue(value) | (channel.opLevel1 & 0xC0);
1248 uint8 AdlibDriver::calculateOpLevel2(Channel &channel) {
1249 int8 value = channel.opLevel2 & 0x3F;
1251 value += channel.opExtraLevel1;
1252 value += channel.opExtraLevel2;
1253 value += channel.opExtraLevel3;
1255 // Preserve the scaling level bits from opLevel2
1257 return checkValue(value) | (channel.opLevel2 & 0xC0);
1262 int AdlibDriver::update_setRepeat(uint8 *&dataptr, Channel &channel, uint8 value) {
1263 channel.repeatCounter = value;
1267 int AdlibDriver::update_checkRepeat(uint8 *&dataptr, Channel &channel, uint8 value) {
1269 if (--channel.repeatCounter) {
1270 int16 add = READ_LE_UINT16(dataptr - 2);
1276 int AdlibDriver::update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 value) {
1280 uint8 *ptr = getProgram(value);
1281 uint8 chan = *ptr++;
1282 uint8 priority = *ptr++;
1284 Channel &channel2 = _channels[chan];
1286 if (priority >= channel2.priority) {
1289 initChannel(channel2);
1290 channel2.priority = priority;
1291 channel2.dataptr = ptr;
1292 channel2.tempo = 0xFF;
1293 channel2.position = 0xFF;
1294 channel2.duration = 1;
1301 int AdlibDriver::update_setNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value) {
1302 channel.spacing1 = value;
1306 int AdlibDriver::update_jump(uint8 *&dataptr, Channel &channel, uint8 value) {
1308 int16 add = READ_LE_UINT16(dataptr); dataptr += 2;
1313 int AdlibDriver::update_jumpToSubroutine(uint8 *&dataptr, Channel &channel, uint8 value) {
1315 int16 add = READ_LE_UINT16(dataptr); dataptr += 2;
1316 channel.dataptrStack[channel.dataptrStackPos++] = dataptr;
1321 int AdlibDriver::update_returnFromSubroutine(uint8 *&dataptr, Channel &channel, uint8 value) {
1322 dataptr = channel.dataptrStack[--channel.dataptrStackPos];
1326 int AdlibDriver::update_setBaseOctave(uint8 *&dataptr, Channel &channel, uint8 value) {
1327 channel.baseOctave = value;
1331 int AdlibDriver::update_stopChannel(uint8 *&dataptr, Channel &channel, uint8 value) {
1332 channel.priority = 0;
1333 if (_curChannel != 9) {
1340 int AdlibDriver::update_playRest(uint8 *&dataptr, Channel &channel, uint8 value) {
1341 setupDuration(value, channel);
1343 return (value != 0);
1346 int AdlibDriver::update_writeAdlib(uint8 *&dataptr, Channel &channel, uint8 value) {
1347 writeOPL(value, *dataptr++);
1351 int AdlibDriver::update_setupNoteAndDuration(uint8 *&dataptr, Channel &channel, uint8 value) {
1352 setupNote(value, channel);
1354 setupDuration(value, channel);
1355 return (value != 0);
1358 int AdlibDriver::update_setBaseNote(uint8 *&dataptr, Channel &channel, uint8 value) {
1359 channel.baseNote = value;
1363 int AdlibDriver::update_setupSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
1364 channel.unk18 = value;
1365 channel.unk19 = value;
1366 channel.unk20 = channel.unk21 = *dataptr++;
1367 channel.unk22 = *dataptr++;
1368 channel.offset = READ_LE_UINT16(dataptr); dataptr += 2;
1369 channel.secondaryEffect = &AdlibDriver::secondaryEffect1;
1373 int AdlibDriver::update_stopOtherChannel(uint8 *&dataptr, Channel &channel, uint8 value) {
1374 Channel &channel2 = _channels[value];
1375 channel2.duration = 0;
1376 channel2.priority = 0;
1377 channel2.dataptr = 0;
1381 int AdlibDriver::update_waitForEndOfProgram(uint8 *&dataptr, Channel &channel, uint8 value) {
1382 uint8 *ptr = getProgram(value);
1385 if (!_channels[chan].dataptr) {
1393 int AdlibDriver::update_setupInstrument(uint8 *&dataptr, Channel &channel, uint8 value) {
1394 setupInstrument(_curRegOffset, getInstrument(value), channel);
1398 int AdlibDriver::update_setupPrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
1399 channel.unk29 = value;
1400 channel.unk30 = READ_BE_UINT16(dataptr);
1402 channel.primaryEffect = &AdlibDriver::primaryEffect1;
1403 channel.unk31 = 0xFF;
1407 int AdlibDriver::update_removePrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
1409 channel.primaryEffect = 0;
1414 int AdlibDriver::update_setBaseFreq(uint8 *&dataptr, Channel &channel, uint8 value) {
1415 channel.baseFreq = value;
1419 int AdlibDriver::update_setupPrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value) {
1420 channel.unk32 = value;
1421 channel.unk33 = *dataptr++;
1422 uint8 temp = *dataptr++;
1423 channel.unk34 = temp + 1;
1424 channel.unk35 = temp << 1;
1425 channel.unk36 = *dataptr++;
1426 channel.primaryEffect = &AdlibDriver::primaryEffect2;
1430 int AdlibDriver::update_setPriority(uint8 *&dataptr, Channel &channel, uint8 value) {
1431 channel.priority = value;
1435 int AdlibDriver::updateCallback23(uint8 *&dataptr, Channel &channel, uint8 value) {
1437 _unkValue1 = _unkValue2 = value;
1439 _unkValue4 = _unkValue5 = 0;
1443 int AdlibDriver::updateCallback24(uint8 *&dataptr, Channel &channel, uint8 value) {
1445 if (_unkValue4 & value) {
1451 if (!(value & _unkValue4)) {
1456 channel.duration = 1;
1460 int AdlibDriver::update_setExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value) {
1461 channel.opExtraLevel1 = value;
1462 adjustVolume(channel);
1466 int AdlibDriver::update_setupDuration(uint8 *&dataptr, Channel &channel, uint8 value) {
1467 setupDuration(value, channel);
1468 return (value != 0);
1471 int AdlibDriver::update_playNote(uint8 *&dataptr, Channel &channel, uint8 value) {
1472 setupDuration(value, channel);
1474 return (value != 0);
1477 int AdlibDriver::update_setFractionalNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value) {
1478 channel.fractionalSpacing = value & 7;
1482 int AdlibDriver::update_setTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
1487 int AdlibDriver::update_removeSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
1489 channel.secondaryEffect = 0;
1493 int AdlibDriver::update_setChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
1494 channel.tempo = value;
1498 int AdlibDriver::update_setExtraLevel3(uint8 *&dataptr, Channel &channel, uint8 value) {
1499 channel.opExtraLevel3 = value;
1503 int AdlibDriver::update_setExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value) {
1504 int channelBackUp = _curChannel;
1506 _curChannel = value;
1507 Channel &channel2 = _channels[value];
1508 channel2.opExtraLevel2 = *dataptr++;
1509 adjustVolume(channel2);
1511 _curChannel = channelBackUp;
1515 int AdlibDriver::update_changeExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value) {
1516 int channelBackUp = _curChannel;
1518 _curChannel = value;
1519 Channel &channel2 = _channels[value];
1520 channel2.opExtraLevel2 += *dataptr++;
1521 adjustVolume(channel2);
1523 _curChannel = channelBackUp;
1527 // Apart from initialising to zero, these two functions are the only ones that
1528 // modify _vibratoAndAMDepthBits.
1530 int AdlibDriver::update_setAMDepth(uint8 *&dataptr, Channel &channel, uint8 value) {
1532 _vibratoAndAMDepthBits |= 0x80;
1534 _vibratoAndAMDepthBits &= 0x7F;
1536 writeOPL(0xBD, _vibratoAndAMDepthBits);
1540 int AdlibDriver::update_setVibratoDepth(uint8 *&dataptr, Channel &channel, uint8 value) {
1542 _vibratoAndAMDepthBits |= 0x40;
1544 _vibratoAndAMDepthBits &= 0xBF;
1546 writeOPL(0xBD, _vibratoAndAMDepthBits);
1550 int AdlibDriver::update_changeExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value) {
1551 channel.opExtraLevel1 += value;
1552 adjustVolume(channel);
1556 int AdlibDriver::updateCallback38(uint8 *&dataptr, Channel &channel, uint8 value) {
1557 int channelBackUp = _curChannel;
1559 _curChannel = value;
1560 Channel &channel2 = _channels[value];
1561 channel2.duration = channel2.priority = 0;
1562 channel2.dataptr = 0;
1563 channel2.opExtraLevel2 = 0;
1566 uint8 outValue = _regOffset[value];
1568 // Feedback strength / Connection type
1569 writeOPL(0xC0 + _curChannel, 0x00);
1571 // Key scaling level / Operator output level
1572 writeOPL(0x43 + outValue, 0x3F);
1574 // Sustain Level / Release Rate
1575 writeOPL(0x83 + outValue, 0xFF);
1577 // Key On / Octave / Frequency
1578 writeOPL(0xB0 + _curChannel, 0x00);
1581 _curChannel = channelBackUp;
1585 int AdlibDriver::updateCallback39(uint8 *&dataptr, Channel &channel, uint8 value) {
1586 uint16 unk = *dataptr++;
1588 unk &= getRandomNr();
1590 uint16 unk2 = ((channel.regBx & 0x1F) << 8) | channel.regAx;
1592 unk2 |= ((channel.regBx & 0x20) << 8);
1595 writeOPL(0xA0 + _curChannel, unk2 & 0xFF);
1597 // Key On / Octave / Frequency
1598 writeOPL(0xB0 + _curChannel, (unk2 & 0xFF00) >> 8);
1603 int AdlibDriver::update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value) {
1605 channel.primaryEffect = 0;
1609 int AdlibDriver::updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value) {
1610 channel.unk16 = value;
1611 setupNote(channel.rawNote, channel, true);
1615 int AdlibDriver::update_resetToGlobalTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
1617 channel.tempo = _tempo;
1621 int AdlibDriver::update_nop1(uint8 *&dataptr, Channel &channel, uint8 value) {
1626 int AdlibDriver::update_setDurationRandomness(uint8 *&dataptr, Channel &channel, uint8 value) {
1627 channel.durationRandomness = value;
1631 int AdlibDriver::update_changeChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
1632 int tempo = channel.tempo + (int8)value;
1636 else if (tempo > 255)
1639 channel.tempo = tempo;
1643 int AdlibDriver::updateCallback46(uint8 *&dataptr, Channel &channel, uint8 value) {
1644 uint8 entry = *dataptr++;
1645 _tablePtr1 = _unkTable2[entry++];
1646 _tablePtr2 = _unkTable2[entry];
1649 writeOPL(0xA0, _tablePtr2[0]);
1654 // TODO: This is really the same as update_nop1(), so they should be combined
1655 // into one single update_nop().
1657 int AdlibDriver::update_nop2(uint8 *&dataptr, Channel &channel, uint8 value) {
1662 int AdlibDriver::update_setupRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) {
1663 int channelBackUp = _curChannel;
1664 int regOffsetBackUp = _curRegOffset;
1667 _curRegOffset = _regOffset[6];
1669 setupInstrument(_curRegOffset, getInstrument(value), channel);
1670 _unkValue6 = channel.opLevel2;
1673 _curRegOffset = _regOffset[7];
1675 setupInstrument(_curRegOffset, getInstrument(*dataptr++), channel);
1676 _unkValue7 = channel.opLevel1;
1677 _unkValue8 = channel.opLevel2;
1680 _curRegOffset = _regOffset[8];
1682 setupInstrument(_curRegOffset, getInstrument(*dataptr++), channel);
1683 _unkValue9 = channel.opLevel1;
1684 _unkValue10 = channel.opLevel2;
1686 // Octave / F-Number / Key-On for channels 6, 7 and 8
1688 _channels[6].regBx = *dataptr++ & 0x2F;
1689 writeOPL(0xB6, _channels[6].regBx);
1690 writeOPL(0xA6, *dataptr++);
1692 _channels[7].regBx = *dataptr++ & 0x2F;
1693 writeOPL(0xB7, _channels[7].regBx);
1694 writeOPL(0xA7, *dataptr++);
1696 _channels[8].regBx = *dataptr++ & 0x2F;
1697 writeOPL(0xB8, _channels[8].regBx);
1698 writeOPL(0xA8, *dataptr++);
1700 _rhythmSectionBits = 0x20;
1702 _curRegOffset = regOffsetBackUp;
1703 _curChannel = channelBackUp;
1707 int AdlibDriver::update_playRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) {
1708 // Any instrument that we want to play, and which was already playing,
1709 // is temporarily keyed off. Instruments that were off already, or
1710 // which we don't want to play, retain their old on/off status. This is
1711 // probably so that the instrument's envelope is played from its
1712 // beginning again...
1714 writeOPL(0xBD, (_rhythmSectionBits & ~(value & 0x1F)) | 0x20);
1716 // ...but since we only set the rhythm instrument bits, and never clear
1717 // them (until the entire rhythm section is disabled), I'm not sure how
1718 // useful the cleverness above is. We could perhaps simply turn off all
1719 // the rhythm instruments instead.
1721 _rhythmSectionBits |= value;
1723 writeOPL(0xBD, _vibratoAndAMDepthBits | 0x20 | _rhythmSectionBits);
1727 int AdlibDriver::update_removeRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) {
1729 _rhythmSectionBits = 0;
1731 // All the rhythm bits are cleared. The AM and Vibrato depth bits
1732 // remain unchanged.
1734 writeOPL(0xBD, _vibratoAndAMDepthBits);
1738 int AdlibDriver::updateCallback51(uint8 *&dataptr, Channel &channel, uint8 value) {
1739 uint8 value2 = *dataptr++;
1742 _unkValue12 = value2;
1744 // Channel 7, op1: Level Key Scaling / Total Level
1745 writeOPL(0x51, checkValue(value2 + _unkValue7 + _unkValue11 + _unkValue12));
1749 _unkValue14 = value2;
1751 // Channel 8, op2: Level Key Scaling / Total Level
1752 writeOPL(0x55, checkValue(value2 + _unkValue10 + _unkValue13 + _unkValue14));
1756 _unkValue15 = value2;
1758 // Channel 8, op1: Level Key Scaling / Total Level
1759 writeOPL(0x52, checkValue(value2 + _unkValue9 + _unkValue16 + _unkValue15));
1763 _unkValue18 = value2;
1765 // Channel 7, op2: Level Key Scaling / Total Level
1766 writeOPL(0x54, checkValue(value2 + _unkValue8 + _unkValue17 + _unkValue18));
1770 _unkValue20 = value2;
1772 // Channel 6, op2: Level Key Scaling / Total Level
1773 writeOPL(0x53, checkValue(value2 + _unkValue6 + _unkValue19 + _unkValue20));
1779 int AdlibDriver::updateCallback52(uint8 *&dataptr, Channel &channel, uint8 value) {
1780 uint8 value2 = *dataptr++;
1783 _unkValue11 = checkValue(value2 + _unkValue7 + _unkValue11 + _unkValue12);
1785 // Channel 7, op1: Level Key Scaling / Total Level
1786 writeOPL(0x51, _unkValue11);
1790 _unkValue13 = checkValue(value2 + _unkValue10 + _unkValue13 + _unkValue14);
1792 // Channel 8, op2: Level Key Scaling / Total Level
1793 writeOPL(0x55, _unkValue13);
1797 _unkValue16 = checkValue(value2 + _unkValue9 + _unkValue16 + _unkValue15);
1799 // Channel 8, op1: Level Key Scaling / Total Level
1800 writeOPL(0x52, _unkValue16);
1804 _unkValue17 = checkValue(value2 + _unkValue8 + _unkValue17 + _unkValue18);
1806 // Channel 7, op2: Level Key Scaling / Total Level
1807 writeOPL(0x54, _unkValue17);
1811 _unkValue19 = checkValue(value2 + _unkValue6 + _unkValue19 + _unkValue20);
1813 // Channel 6, op2: Level Key Scaling / Total Level
1814 writeOPL(0x53, _unkValue19);
1820 int AdlibDriver::updateCallback53(uint8 *&dataptr, Channel &channel, uint8 value) {
1821 uint8 value2 = *dataptr++;
1824 _unkValue11 = value2;
1826 // Channel 7, op1: Level Key Scaling / Total Level
1827 writeOPL(0x51, checkValue(value2 + _unkValue7 + _unkValue12));
1831 _unkValue13 = value2;
1833 // Channel 8, op2: Level Key Scaling / Total Level
1834 writeOPL(0x55, checkValue(value2 + _unkValue10 + _unkValue14));
1838 _unkValue16 = value2;
1840 // Channel 8, op1: Level Key Scaling / Total Level
1841 writeOPL(0x52, checkValue(value2 + _unkValue9 + _unkValue15));
1845 _unkValue17 = value2;
1847 // Channel 7, op2: Level Key Scaling / Total Level
1848 writeOPL(0x54, checkValue(value2 + _unkValue8 + _unkValue18));
1852 _unkValue19 = value2;
1854 // Channel 6, op2: Level Key Scaling / Total Level
1855 writeOPL(0x53, checkValue(value2 + _unkValue6 + _unkValue20));
1861 int AdlibDriver::update_setSoundTrigger(uint8 *&dataptr, Channel &channel, uint8 value) {
1862 _soundTrigger = value;
1866 int AdlibDriver::update_setTempoReset(uint8 *&dataptr, Channel &channel, uint8 value) {
1867 channel.tempoReset = value;
1871 int AdlibDriver::updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value) {
1872 channel.unk39 = value;
1873 channel.unk40 = *dataptr++;
1879 #define COMMAND(x) { &AdlibDriver::x, #x }
1881 void AdlibDriver::setupOpcodeList() {
1882 static const OpcodeEntry opcodeList[] = {
1883 COMMAND(snd_ret0x100),
1884 COMMAND(snd_ret0x1983),
1885 COMMAND(snd_initDriver),
1886 COMMAND(snd_deinitDriver),
1887 COMMAND(snd_setSoundData),
1888 COMMAND(snd_unkOpcode1),
1889 COMMAND(snd_startSong),
1890 COMMAND(snd_unkOpcode2),
1891 COMMAND(snd_unkOpcode3),
1892 COMMAND(snd_readByte),
1893 COMMAND(snd_writeByte),
1894 COMMAND(snd_getSoundTrigger),
1895 COMMAND(snd_unkOpcode4),
1897 COMMAND(snd_getNullvar4),
1898 COMMAND(snd_setNullvar3),
1899 COMMAND(snd_setFlag),
1900 COMMAND(snd_clearFlag)
1903 _opcodeList = opcodeList;
1904 _opcodesEntries = ARRAYSIZE(opcodeList);
1907 void AdlibDriver::setupParserOpcodeTable() {
1908 static const ParserOpcode parserOpcodeTable[] = {
1910 COMMAND(update_setRepeat),
1911 COMMAND(update_checkRepeat),
1912 COMMAND(update_setupProgram),
1913 COMMAND(update_setNoteSpacing),
1916 COMMAND(update_jump),
1917 COMMAND(update_jumpToSubroutine),
1918 COMMAND(update_returnFromSubroutine),
1919 COMMAND(update_setBaseOctave),
1922 COMMAND(update_stopChannel),
1923 COMMAND(update_playRest),
1924 COMMAND(update_writeAdlib),
1925 COMMAND(update_setupNoteAndDuration),
1928 COMMAND(update_setBaseNote),
1929 COMMAND(update_setupSecondaryEffect1),
1930 COMMAND(update_stopOtherChannel),
1931 COMMAND(update_waitForEndOfProgram),
1934 COMMAND(update_setupInstrument),
1935 COMMAND(update_setupPrimaryEffect1),
1936 COMMAND(update_removePrimaryEffect1),
1937 COMMAND(update_setBaseFreq),
1940 COMMAND(update_stopChannel),
1941 COMMAND(update_setupPrimaryEffect2),
1942 COMMAND(update_stopChannel),
1943 COMMAND(update_stopChannel),
1946 COMMAND(update_stopChannel),
1947 COMMAND(update_stopChannel),
1948 COMMAND(update_setPriority),
1949 COMMAND(update_stopChannel),
1952 COMMAND(updateCallback23),
1953 COMMAND(updateCallback24),
1954 COMMAND(update_setExtraLevel1),
1955 COMMAND(update_stopChannel),
1958 COMMAND(update_setupDuration),
1959 COMMAND(update_playNote),
1960 COMMAND(update_stopChannel),
1961 COMMAND(update_stopChannel),
1964 COMMAND(update_setFractionalNoteSpacing),
1965 COMMAND(update_stopChannel),
1966 COMMAND(update_setTempo),
1967 COMMAND(update_removeSecondaryEffect1),
1970 COMMAND(update_stopChannel),
1971 COMMAND(update_setChannelTempo),
1972 COMMAND(update_stopChannel),
1973 COMMAND(update_setExtraLevel3),
1976 COMMAND(update_setExtraLevel2),
1977 COMMAND(update_changeExtraLevel2),
1978 COMMAND(update_setAMDepth),
1979 COMMAND(update_setVibratoDepth),
1982 COMMAND(update_changeExtraLevel1),
1983 COMMAND(update_stopChannel),
1984 COMMAND(update_stopChannel),
1985 COMMAND(updateCallback38),
1988 COMMAND(update_stopChannel),
1989 COMMAND(updateCallback39),
1990 COMMAND(update_removePrimaryEffect2),
1991 COMMAND(update_stopChannel),
1994 COMMAND(update_stopChannel),
1995 COMMAND(updateCallback41),
1996 COMMAND(update_resetToGlobalTempo),
1997 COMMAND(update_nop1),
2000 COMMAND(update_setDurationRandomness),
2001 COMMAND(update_changeChannelTempo),
2002 COMMAND(update_stopChannel),
2003 COMMAND(updateCallback46),
2006 COMMAND(update_nop2),
2007 COMMAND(update_setupRhythmSection),
2008 COMMAND(update_playRhythmSection),
2009 COMMAND(update_removeRhythmSection),
2012 COMMAND(updateCallback51),
2013 COMMAND(updateCallback52),
2014 COMMAND(updateCallback53),
2015 COMMAND(update_setSoundTrigger),
2018 COMMAND(update_setTempoReset),
2019 COMMAND(updateCallback56),
2020 COMMAND(update_stopChannel)
2023 _parserOpcodeTable = parserOpcodeTable;
2024 _parserOpcodeTableSize = ARRAYSIZE(parserOpcodeTable);
2028 // This table holds the register offset for operator 1 for each of the nine
2029 // channels. To get the register offset for operator 2, simply add 3.
2031 const uint8 AdlibDriver::_regOffset[] = {
2032 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11,
2036 // Given the size of this table, and the range of its values, it's probably the
2037 // F-Numbers (10 bits) for the notes of the 12-tone scale. However, it does not
2038 // match the table in the Adlib documentation I've seen.
2040 const uint16 AdlibDriver::_unkTable[] = {
2041 0x0134, 0x0147, 0x015A, 0x016F, 0x0184, 0x019C, 0x01B4, 0x01CE, 0x01E9,
2042 0x0207, 0x0225, 0x0246
2045 // These tables are currently only used by updateCallback46(), which only ever
2046 // uses the first element of one of the sub-tables.
2048 const uint8 *AdlibDriver::_unkTable2[] = {
2049 AdlibDriver::_unkTable2_1,
2050 AdlibDriver::_unkTable2_2,
2051 AdlibDriver::_unkTable2_1,
2052 AdlibDriver::_unkTable2_2,
2053 AdlibDriver::_unkTable2_3,
2054 AdlibDriver::_unkTable2_2
2057 const uint8 AdlibDriver::_unkTable2_1[] = {
2058 0x50, 0x50, 0x4F, 0x4F, 0x4E, 0x4E, 0x4D, 0x4D,
2059 0x4C, 0x4C, 0x4B, 0x4B, 0x4A, 0x4A, 0x49, 0x49,
2060 0x48, 0x48, 0x47, 0x47, 0x46, 0x46, 0x45, 0x45,
2061 0x44, 0x44, 0x43, 0x43, 0x42, 0x42, 0x41, 0x41,
2062 0x40, 0x40, 0x3F, 0x3F, 0x3E, 0x3E, 0x3D, 0x3D,
2063 0x3C, 0x3C, 0x3B, 0x3B, 0x3A, 0x3A, 0x39, 0x39,
2064 0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, 0x35,
2065 0x34, 0x34, 0x33, 0x33, 0x32, 0x32, 0x31, 0x31,
2066 0x30, 0x30, 0x2F, 0x2F, 0x2E, 0x2E, 0x2D, 0x2D,
2067 0x2C, 0x2C, 0x2B, 0x2B, 0x2A, 0x2A, 0x29, 0x29,
2068 0x28, 0x28, 0x27, 0x27, 0x26, 0x26, 0x25, 0x25,
2069 0x24, 0x24, 0x23, 0x23, 0x22, 0x22, 0x21, 0x21,
2070 0x20, 0x20, 0x1F, 0x1F, 0x1E, 0x1E, 0x1D, 0x1D,
2071 0x1C, 0x1C, 0x1B, 0x1B, 0x1A, 0x1A, 0x19, 0x19,
2072 0x18, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15,
2073 0x14, 0x14, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11,
2077 // no don't ask me WHY this table exsits!
2078 const uint8 AdlibDriver::_unkTable2_2[] = {
2079 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2080 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2081 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2082 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
2083 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
2084 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
2085 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
2086 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
2087 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
2088 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
2089 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
2090 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x6F,
2091 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
2092 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
2093 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
2094 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F
2097 const uint8 AdlibDriver::_unkTable2_3[] = {
2098 0x40, 0x40, 0x40, 0x3F, 0x3F, 0x3F, 0x3E, 0x3E,
2099 0x3E, 0x3D, 0x3D, 0x3D, 0x3C, 0x3C, 0x3C, 0x3B,
2100 0x3B, 0x3B, 0x3A, 0x3A, 0x3A, 0x39, 0x39, 0x39,
2101 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36,
2102 0x36, 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x33,
2103 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31,
2104 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x2F, 0x2E, 0x2E,
2105 0x2E, 0x2D, 0x2D, 0x2D, 0x2C, 0x2C, 0x2C, 0x2B,
2106 0x2B, 0x2B, 0x2A, 0x2A, 0x2A, 0x29, 0x29, 0x29,
2107 0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26,
2108 0x26, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x23,
2109 0x23, 0x23, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21,
2110 0x20, 0x20, 0x20, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E,
2111 0x1E, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1B,
2112 0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x19, 0x19, 0x19,
2113 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16, 0x16,
2117 // This table is used to modify the frequency of the notes, depending on the
2118 // note value and unk16. In theory, we could very well try to access memory
2119 // outside this table, but in reality that probably won't happen.
2121 // This could be some sort of pitch bend, but I have yet to see it used for
2122 // anything so it's hard to say.
2124 const uint8 AdlibDriver::_unkTables[][32] = {
2126 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
2127 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
2128 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x19,
2129 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21 },
2131 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x09,
2132 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11,
2133 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x1A,
2134 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x22, 0x24 },
2136 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x09,
2137 0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13,
2138 0x14, 0x15, 0x16, 0x17, 0x19, 0x1A, 0x1C, 0x1D,
2139 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26 },
2141 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A,
2142 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13,
2143 0x14, 0x15, 0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1D,
2144 0x1E, 0x1F, 0x20, 0x21, 0x23, 0x25, 0x27, 0x28 },
2146 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A,
2147 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x13, 0x15,
2148 0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20,
2149 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x28, 0x2A },
2151 { 0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B,
2152 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15,
2153 0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20,
2154 0x21, 0x22, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D },
2156 { 0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B,
2157 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15,
2158 0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1E, 0x21, 0x24,
2159 0x25, 0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30 },
2161 { 0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C,
2162 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x18,
2163 0x19, 0x1A, 0x1C, 0x1D, 0x1F, 0x21, 0x23, 0x25,
2164 0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30, 0x32 },
2166 { 0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0D,
2167 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x17, 0x1A,
2168 0x19, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x25, 0x28,
2169 0x29, 0x2A, 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0x35 },
2171 { 0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E,
2172 0x0F, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1B,
2173 0x1C, 0x1D, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x29,
2174 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x39 },
2176 { 0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E,
2177 0x0F, 0x10, 0x12, 0x14, 0x16, 0x19, 0x1B, 0x1E,
2178 0x1F, 0x21, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D,
2179 0x2E, 0x2F, 0x31, 0x32, 0x34, 0x36, 0x39, 0x3C },
2181 { 0x00, 0x01, 0x03, 0x05, 0x07, 0x0A, 0x0C, 0x0F,
2182 0x10, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1E,
2183 0x1F, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2B, 0x2E,
2184 0x2F, 0x30, 0x32, 0x34, 0x36, 0x39, 0x3C, 0x3F },
2186 { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x10,
2187 0x11, 0x12, 0x14, 0x16, 0x18, 0x1B, 0x1E, 0x21,
2188 0x22, 0x23, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32,
2189 0x33, 0x34, 0x36, 0x38, 0x3B, 0x34, 0x41, 0x44 },
2191 { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x11,
2192 0x12, 0x13, 0x15, 0x17, 0x1A, 0x1D, 0x20, 0x23,
2193 0x24, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32, 0x35,
2194 0x36, 0x37, 0x39, 0x3B, 0x3E, 0x41, 0x44, 0x47 }
2199 // At the time of writing, the only known case where Kyra 1 uses sound triggers
2200 // is in the castle, to cycle between three different songs.
2202 const int CadlPlayer::_kyra1SoundTriggers[] = {
2206 const int CadlPlayer::_kyra1NumSoundTriggers = ARRAYSIZE(CadlPlayer::_kyra1SoundTriggers);
2208 CadlPlayer::CadlPlayer(Copl *newopl)
2209 : CPlayer(newopl), numsubsongs(0), _trackEntries(), _soundDataPtr(0)
2211 memset(_trackEntries, 0, sizeof(_trackEntries));
2212 _driver = new AdlibDriver(newopl);
2215 _sfxPlayingSound = -1;
2216 // _soundFileLoaded = "";
2218 _soundTriggers = _kyra1SoundTriggers;
2219 _numSoundTriggers = _kyra1NumSoundTriggers;
2224 CadlPlayer::~CadlPlayer() {
2225 delete [] _soundDataPtr;
2229 bool CadlPlayer::init() {
2230 _driver->callback(2);
2231 _driver->callback(16, int(4));
2235 void CadlPlayer::process() {
2236 uint8 trigger = _driver->callback(11);
2238 if (trigger < _numSoundTriggers) {
2239 int soundId = _soundTriggers[trigger];
2245 warning("Unknown sound trigger %d", trigger);
2246 // TODO: At this point, we really want to clear the trigger...
2250 // void CadlPlayer::setVolume(int volume) {
2253 // int CadlPlayer::getVolume() {
2257 // void CadlPlayer::loadMusicFile(const char *file) {
2258 // loadSoundFile(file);
2261 void CadlPlayer::playTrack(uint8 track) {
2265 // void CadlPlayer::haltTrack() {
2268 // //_engine->_system->delayMillis(3 * 60);
2271 void CadlPlayer::playSoundEffect(uint8_t track) {
2275 void CadlPlayer::play(uint8_t track) {
2276 uint8 soundId = _trackEntries[track];
2277 if ((int8)soundId == -1 || !_soundDataPtr)
2280 _driver->callback(16, 0);
2281 // while ((_driver->callback(16, 0) & 8)) {
2282 // We call the system delay and not the game delay to avoid concurrency issues.
2283 // _engine->_system->delayMillis(10);
2285 if (_sfxPlayingSound != -1) {
2286 // Restore the sounds's normal values.
2287 _driver->callback(10, _sfxPlayingSound, int(1), int(_sfxPriority));
2288 _driver->callback(10, _sfxPlayingSound, int(3), int(_sfxFourthByteOfSong));
2289 _sfxPlayingSound = -1;
2292 int chan = _driver->callback(9, soundId, int(0));
2295 _sfxPlayingSound = soundId;
2296 _sfxPriority = _driver->callback(9, soundId, int(1));
2297 _sfxFourthByteOfSong = _driver->callback(9, soundId, int(3));
2299 // In the cases I've seen, the mysterious fourth byte has been
2300 // the parameter for the update_setExtraLevel3() callback.
2302 // The extra level is part of the channels "total level", which
2303 // is a six-bit value where larger values means softer volume.
2305 // So what seems to be happening here is that sounds which are
2306 // started by this function are given a slightly lower priority
2307 // and a slightly higher (i.e. softer) extra level 3 than they
2308 // would have if they were started from anywhere else. Strange.
2310 int newVal = ((((-_sfxFourthByteOfSong) + 63) * 0xFF) >> 8) & 0xFF;
2311 newVal = -newVal + 63;
2312 _driver->callback(10, soundId, int(3), newVal);
2313 newVal = ((_sfxPriority * 0xFF) >> 8) & 0xFF;
2314 _driver->callback(10, soundId, int(1), newVal);
2317 _driver->callback(6, soundId);
2320 // void CadlPlayer::beginFadeOut() {
2321 // playSoundEffect(1);
2324 bool CadlPlayer::load(const std::string &filename, const CFileProvider &fp)
2326 binistream *f = fp.open(filename);
2328 // file validation section
2329 if(!f || !fp.extension(filename, ".adl")) {
2334 // if (_soundFileLoaded == file)
2337 // if (_soundDataPtr) {
2341 uint8 *file_data = 0; uint32 file_size = 0;
2343 // char filename[25];
2344 // sprintf(filename, "%s.ADL", file);
2346 // file_data = _engine->resource()->fileData(filename, &file_size);
2347 // if (!file_data) {
2348 // warning("Couldn't find music file: '%s'", filename);
2355 file_size = fp.filesize(f);
2356 file_data = new uint8 [file_size];
2357 f->readString((char *)file_data, file_size);
2359 _driver->callback(8, int(-1));
2362 uint8 *p = file_data;
2363 memcpy(_trackEntries, p, 120*sizeof(uint8));
2366 int soundDataSize = file_size - 120;
2368 _soundDataPtr = new uint8[soundDataSize];
2369 assert(_soundDataPtr);
2371 memcpy(_soundDataPtr, p, soundDataSize*sizeof(uint8));
2373 delete [] file_data;
2377 _driver->callback(4, _soundDataPtr);
2379 // _soundFileLoaded = file;
2381 // find last subsong
2382 for(int i = 199; i >= 0; i--)
2383 if(_trackEntries[i] != 0xff) {
2384 numsubsongs = i + 1;
2394 void CadlPlayer::rewind(int subsong)
2396 if(subsong == -1) subsong = cursubsong;
2399 playSoundEffect(subsong);
2400 cursubsong = subsong;
2404 unsigned int CadlPlayer::getsubsongs()
2409 bool CadlPlayer::update()
2411 bool songend = true;
2413 // if(_trackEntries[cursubsong] == 0xff)
2416 _driver->callback();
2418 for(int i = 0; i < 10; i++)
2419 if(_driver->_channels[i].dataptr != NULL)
2425 void CadlPlayer::unk1() {
2427 //_engine->_system->delayMillis(5 * 60);
2430 void CadlPlayer::unk2() {
2434 CPlayer *CadlPlayer::factory(Copl *newopl)
2436 return new CadlPlayer(newopl);