diff options
Diffstat (limited to 'audio')
102 files changed, 1983 insertions, 1784 deletions
diff --git a/audio/audiostream.cpp b/audio/audiostream.cpp index 776f904e77..e6587a6543 100644 --- a/audio/audiostream.cpp +++ b/audio/audiostream.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "common/debug.h" diff --git a/audio/audiostream.h b/audio/audiostream.h index 22de21cb34..0ffaa241ce 100644 --- a/audio/audiostream.h +++ b/audio/audiostream.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef SOUND_AUDIOSTREAM_H diff --git a/audio/decoders/adpcm.cpp b/audio/decoders/adpcm.cpp index a9284973d5..d28ed222a5 100644 --- a/audio/decoders/adpcm.cpp +++ b/audio/decoders/adpcm.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "common/stream.h" diff --git a/audio/decoders/adpcm.h b/audio/decoders/adpcm.h index 10344101e2..1dd4d510df 100644 --- a/audio/decoders/adpcm.h +++ b/audio/decoders/adpcm.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/decoders/adpcm_intern.h b/audio/decoders/adpcm_intern.h index f875bd88c7..c9f894fb84 100644 --- a/audio/decoders/adpcm_intern.h +++ b/audio/decoders/adpcm_intern.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/decoders/aiff.cpp b/audio/decoders/aiff.cpp index 957fb13638..f3b0dfb559 100644 --- a/audio/decoders/aiff.cpp +++ b/audio/decoders/aiff.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /* diff --git a/audio/decoders/aiff.h b/audio/decoders/aiff.h index dddbffb520..558a018f57 100644 --- a/audio/decoders/aiff.h +++ b/audio/decoders/aiff.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/decoders/flac.cpp b/audio/decoders/flac.cpp index fe15877ac6..b818d4f7e9 100644 --- a/audio/decoders/flac.cpp +++ b/audio/decoders/flac.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  // Disable symbol overrides for FILE as that is used in FLAC headers diff --git a/audio/decoders/flac.h b/audio/decoders/flac.h index 69222f22a1..3182b26425 100644 --- a/audio/decoders/flac.h +++ b/audio/decoders/flac.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/decoders/iff_sound.cpp b/audio/decoders/iff_sound.cpp index 8efe017e75..4efdce0338 100644 --- a/audio/decoders/iff_sound.cpp +++ b/audio/decoders/iff_sound.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/decoders/iff_sound.h" diff --git a/audio/decoders/iff_sound.h b/audio/decoders/iff_sound.h index 4d26b32e71..b266e629a1 100644 --- a/audio/decoders/iff_sound.h +++ b/audio/decoders/iff_sound.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/decoders/mac_snd.cpp b/audio/decoders/mac_snd.cpp index fc69988860..43253a9ddf 100644 --- a/audio/decoders/mac_snd.cpp +++ b/audio/decoders/mac_snd.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /* diff --git a/audio/decoders/mac_snd.h b/audio/decoders/mac_snd.h index bf6331a265..cbbd82bbe0 100644 --- a/audio/decoders/mac_snd.h +++ b/audio/decoders/mac_snd.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/decoders/mp3.cpp b/audio/decoders/mp3.cpp index 91bd49873a..8d7f006ec7 100644 --- a/audio/decoders/mp3.cpp +++ b/audio/decoders/mp3.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/decoders/mp3.h" diff --git a/audio/decoders/mp3.h b/audio/decoders/mp3.h index d3a5b70d45..86ddc599ea 100644 --- a/audio/decoders/mp3.h +++ b/audio/decoders/mp3.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/decoders/raw.cpp b/audio/decoders/raw.cpp index cf787f9b12..4789fd0f36 100644 --- a/audio/decoders/raw.cpp +++ b/audio/decoders/raw.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "common/endian.h" diff --git a/audio/decoders/raw.h b/audio/decoders/raw.h index 23ed02182d..5a7897b688 100644 --- a/audio/decoders/raw.h +++ b/audio/decoders/raw.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef SOUND_RAW_H diff --git a/audio/decoders/vag.cpp b/audio/decoders/vag.cpp index 2c3a36202a..10ef69708c 100644 --- a/audio/decoders/vag.cpp +++ b/audio/decoders/vag.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/decoders/vag.h" diff --git a/audio/decoders/vag.h b/audio/decoders/vag.h index 4adc1d3dde..b80fbdb98f 100644 --- a/audio/decoders/vag.h +++ b/audio/decoders/vag.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/decoders/voc.cpp b/audio/decoders/voc.cpp index 9c2dc4f337..74ea4440a1 100644 --- a/audio/decoders/voc.cpp +++ b/audio/decoders/voc.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "common/debug.h" diff --git a/audio/decoders/voc.h b/audio/decoders/voc.h index 38250dcf7a..8bc6dcf46f 100644 --- a/audio/decoders/voc.h +++ b/audio/decoders/voc.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/decoders/vorbis.cpp b/audio/decoders/vorbis.cpp index 63f7ba8207..2724dd1f02 100644 --- a/audio/decoders/vorbis.cpp +++ b/audio/decoders/vorbis.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  // Disable symbol overrides for FILE and fseek as those are used in the diff --git a/audio/decoders/vorbis.h b/audio/decoders/vorbis.h index 51d0b82d5f..e3d989e9b8 100644 --- a/audio/decoders/vorbis.h +++ b/audio/decoders/vorbis.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** @@ -36,6 +33,7 @@   *  - scumm   *  - sword1   *  - sword2 + *  - sword25   *  - touche   *  - tucker   */ diff --git a/audio/decoders/wave.cpp b/audio/decoders/wave.cpp index a64874887a..3cf4566d0c 100644 --- a/audio/decoders/wave.cpp +++ b/audio/decoders/wave.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "common/debug.h" diff --git a/audio/decoders/wave.h b/audio/decoders/wave.h index 33c3e798a0..6a34bc175a 100644 --- a/audio/decoders/wave.h +++ b/audio/decoders/wave.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/fmopl.cpp b/audio/fmopl.cpp index 5952a987a7..a24c2a533c 100644 --- a/audio/fmopl.cpp +++ b/audio/fmopl.cpp @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #include "audio/fmopl.h" diff --git a/audio/fmopl.h b/audio/fmopl.h index 33235f3545..fbce36f077 100644 --- a/audio/fmopl.h +++ b/audio/fmopl.h @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #ifndef SOUND_FMOPL_H diff --git a/audio/mididrv.cpp b/audio/mididrv.cpp index 6cc3366847..7beb76352c 100644 --- a/audio/mididrv.cpp +++ b/audio/mididrv.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "common/config-manager.h" diff --git a/audio/mididrv.h b/audio/mididrv.h index c6c5179051..7369cab26b 100644 --- a/audio/mididrv.h +++ b/audio/mididrv.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef SOUND_MIDIDRV_H diff --git a/audio/midiparser.cpp b/audio/midiparser.cpp index a1399d0c30..943a6067a4 100644 --- a/audio/midiparser.cpp +++ b/audio/midiparser.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/midiparser.h" diff --git a/audio/midiparser.h b/audio/midiparser.h index 24f2ba7963..9dff4b54ba 100644 --- a/audio/midiparser.h +++ b/audio/midiparser.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /// \brief Declarations related to the MidiParser class diff --git a/audio/midiparser_smf.cpp b/audio/midiparser_smf.cpp index 8ead95de4c..e883471b54 100644 --- a/audio/midiparser_smf.cpp +++ b/audio/midiparser_smf.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/midiparser.h" diff --git a/audio/midiparser_xmidi.cpp b/audio/midiparser_xmidi.cpp index 1146084cde..84e1aa2ec7 100644 --- a/audio/midiparser_xmidi.cpp +++ b/audio/midiparser_xmidi.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/midiparser.h" diff --git a/audio/midiplayer.cpp b/audio/midiplayer.cpp index f4a13a0438..7fab02a5be 100644 --- a/audio/midiplayer.cpp +++ b/audio/midiplayer.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/midiplayer.h" diff --git a/audio/midiplayer.h b/audio/midiplayer.h index 0cf373d646..e1da0bfb79 100644 --- a/audio/midiplayer.h +++ b/audio/midiplayer.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef SOUND_MIDIPLAYER_H diff --git a/audio/mixer.cpp b/audio/mixer.cpp index 4d23487e71..fb4fffb8d8 100644 --- a/audio/mixer.cpp +++ b/audio/mixer.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "common/util.h" @@ -260,6 +257,8 @@ int MixerImpl::mixCallback(byte *samples, uint len) {  	Common::StackLock lock(_mutex);  	int16 *buf = (int16 *)samples; +	// we store stereo, 16-bit samples +	assert(len % 4 == 0);  	len >>= 2;  	// Since the mixer callback has been called, the mixer must be ready... diff --git a/audio/mixer.h b/audio/mixer.h index 5802abdd6b..1fbe265488 100644 --- a/audio/mixer.h +++ b/audio/mixer.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef SOUND_MIXER_H diff --git a/audio/mixer_intern.h b/audio/mixer_intern.h index d7764e50d9..a04eb55c5b 100644 --- a/audio/mixer_intern.h +++ b/audio/mixer_intern.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef SOUND_MIXER_INTERN_H @@ -129,6 +126,8 @@ public:  	 * the backend (e.g. from an audio mixing thread). All the actual mixing  	 * work is done from here.  	 * +	 * @param samples Sample buffer, in which stereo 16-bit samples will be stored. +	 * @param len Length of the provided buffer to fill (in bytes, should be divisible by 4).  	 * @return number of sample pairs processed (which can still be silence!)  	 */  	int mixCallback(byte *samples, uint len); diff --git a/audio/mods/infogrames.cpp b/audio/mods/infogrames.cpp index 8bfffeacb6..5b4d39fe49 100644 --- a/audio/mods/infogrames.cpp +++ b/audio/mods/infogrames.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/mods/infogrames.h" diff --git a/audio/mods/infogrames.h b/audio/mods/infogrames.h index 9787210e82..307a26d4e1 100644 --- a/audio/mods/infogrames.h +++ b/audio/mods/infogrames.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/mods/maxtrax.cpp b/audio/mods/maxtrax.cpp index 0738966dab..953bb8f8d2 100644 --- a/audio/mods/maxtrax.cpp +++ b/audio/mods/maxtrax.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "common/scummsys.h" diff --git a/audio/mods/maxtrax.h b/audio/mods/maxtrax.h index 2f890afe2d..bef6669d2a 100644 --- a/audio/mods/maxtrax.h +++ b/audio/mods/maxtrax.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  // see if all engines using this class are DISABLED diff --git a/audio/mods/module.cpp b/audio/mods/module.cpp index 987b17bc8d..8d09671d26 100644 --- a/audio/mods/module.cpp +++ b/audio/mods/module.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/mods/module.h" diff --git a/audio/mods/module.h b/audio/mods/module.h index c9b72bd2d6..a57a89225e 100644 --- a/audio/mods/module.h +++ b/audio/mods/module.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef SOUND_MODS_MODULE_H diff --git a/audio/mods/paula.cpp b/audio/mods/paula.cpp index ef841ac9bf..4b49d6e750 100644 --- a/audio/mods/paula.cpp +++ b/audio/mods/paula.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/mods/paula.h" diff --git a/audio/mods/paula.h b/audio/mods/paula.h index f6f159d5a6..cd797f51cb 100644 --- a/audio/mods/paula.h +++ b/audio/mods/paula.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef SOUND_MODS_PAULA_H diff --git a/audio/mods/protracker.cpp b/audio/mods/protracker.cpp index f781920505..084b0edf9a 100644 --- a/audio/mods/protracker.cpp +++ b/audio/mods/protracker.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/mods/protracker.h" diff --git a/audio/mods/protracker.h b/audio/mods/protracker.h index fa9895b81f..15f708d801 100644 --- a/audio/mods/protracker.h +++ b/audio/mods/protracker.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/mods/rjp1.cpp b/audio/mods/rjp1.cpp index eaa99e6928..45c6caa106 100644 --- a/audio/mods/rjp1.cpp +++ b/audio/mods/rjp1.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "common/debug.h" diff --git a/audio/mods/rjp1.h b/audio/mods/rjp1.h index e3cb0b853d..232b1926e9 100644 --- a/audio/mods/rjp1.h +++ b/audio/mods/rjp1.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/mods/soundfx.cpp b/audio/mods/soundfx.cpp index 44fdd65986..767d1ce9c8 100644 --- a/audio/mods/soundfx.cpp +++ b/audio/mods/soundfx.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "common/endian.h" diff --git a/audio/mods/soundfx.h b/audio/mods/soundfx.h index 9dd5240160..48ccff2da6 100644 --- a/audio/mods/soundfx.h +++ b/audio/mods/soundfx.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /** diff --git a/audio/mods/tfmx.cpp b/audio/mods/tfmx.cpp index f7cfc50c10..afc7d3b40b 100644 --- a/audio/mods/tfmx.cpp +++ b/audio/mods/tfmx.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "common/scummsys.h" diff --git a/audio/mods/tfmx.h b/audio/mods/tfmx.h index 1930487eb8..2b07e2e660 100644 --- a/audio/mods/tfmx.h +++ b/audio/mods/tfmx.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  // see if all engines using this class are DISABLED diff --git a/audio/module.mk b/audio/module.mk index a9d9bfc869..840b6d6692 100644 --- a/audio/module.mk +++ b/audio/module.mk @@ -39,10 +39,11 @@ MODULE_OBJS := \  	softsynth/opl/mame.o \  	softsynth/fmtowns_pc98/towns_audio.o \  	softsynth/fmtowns_pc98/towns_euphony.o \ +	softsynth/fmtowns_pc98/towns_midi.o \  	softsynth/fmtowns_pc98/towns_pc98_driver.o \  	softsynth/fmtowns_pc98/towns_pc98_fmsynth.o \ +	softsynth/fmtowns_pc98/towns_pc98_plugins.o \  	softsynth/appleiigs.o \ -	softsynth/ym2612.o \  	softsynth/fluidsynth.o \  	softsynth/mt32.o \  	softsynth/eas.o \ diff --git a/audio/mpu401.cpp b/audio/mpu401.cpp index 4834772c07..caad945258 100644 --- a/audio/mpu401.cpp +++ b/audio/mpu401.cpp @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #include "audio/mpu401.h" diff --git a/audio/mpu401.h b/audio/mpu401.h index 5f1a5108ac..15728a6d97 100644 --- a/audio/mpu401.h +++ b/audio/mpu401.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef SOUND_MPU401_H diff --git a/audio/musicplugin.cpp b/audio/musicplugin.cpp index eb28d2f4c9..7c77c3455c 100644 --- a/audio/musicplugin.cpp +++ b/audio/musicplugin.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/musicplugin.h" diff --git a/audio/musicplugin.h b/audio/musicplugin.h index 53a2ae426d..2a25962b87 100644 --- a/audio/musicplugin.h +++ b/audio/musicplugin.h @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #ifndef SOUND_MUSICPLUGIN_H diff --git a/audio/null.cpp b/audio/null.cpp index 2066a6d048..36c894aa7c 100644 --- a/audio/null.cpp +++ b/audio/null.cpp @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #include "common/error.h" diff --git a/audio/null.h b/audio/null.h index 8570d4d293..97c7c8cc93 100644 --- a/audio/null.h +++ b/audio/null.h @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #ifndef SOUND_NULL_H diff --git a/audio/rate.cpp b/audio/rate.cpp index fd52503b8c..83abd6150b 100644 --- a/audio/rate.cpp +++ b/audio/rate.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /* diff --git a/audio/rate.h b/audio/rate.h index af37994d02..72bcbf48c5 100644 --- a/audio/rate.h +++ b/audio/rate.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef SOUND_RATE_H diff --git a/audio/rate_arm.cpp b/audio/rate_arm.cpp index 1eb55d0dc3..433a7d3423 100644 --- a/audio/rate_arm.cpp +++ b/audio/rate_arm.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /* diff --git a/audio/rate_arm_asm.s b/audio/rate_arm_asm.s index 9431ae0649..d86d96267e 100644 --- a/audio/rate_arm_asm.s +++ b/audio/rate_arm_asm.s @@ -18,9 +18,6 @@  @ along with this program@ if not, write to the Free Software  @ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  @ -@ $URL$ -@ $Id$ -@  @ @author Robin Watts (robin@wss.co.uk)  @  @ This file, together with rate_arm.cpp, provides an ARM optimised version diff --git a/audio/softsynth/adlib.cpp b/audio/softsynth/adlib.cpp index 0b5215e5d6..60de8fad60 100644 --- a/audio/softsynth/adlib.cpp +++ b/audio/softsynth/adlib.cpp @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #include "audio/softsynth/emumidi.h" @@ -71,8 +68,6 @@ struct AdLibInstrument {  	byte flags_b;  	InstrumentExtra extra_b;  	byte duration; - -	AdLibInstrument() { memset(this, 0, sizeof(AdLibInstrument)); }  } PACKED_STRUCT;  #include "common/pack-end.h" @@ -117,6 +112,8 @@ public:  		_owner = 0;  		_allocated = false;  		_channel = 0; + +		memset(&_part_instr, 0, sizeof(_part_instr));  	}  	MidiDriver *device(); @@ -306,185 +303,185 @@ static const byte note_to_f_num[] = {  	242, 243, 245, 247, 249, 251, 252, 254  }; -static const byte map_gm_to_fm[128][30] = { +static const AdLibInstrument map_gm_to_fm[128] = {  	// 0x00 -{ 0xC2, 0xC5, 0x2B, 0x99, 0x58, 0xC2, 0x1F, 0x1E, 0xC8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x23 }, -{ 0x22, 0x53, 0x0E, 0x8A, 0x30, 0x14, 0x06, 0x1D, 0x7A, 0x5C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x06, 0x00, 0x1C, 0x79, 0x40, 0x02, 0x00, 0x4B, 0x79, 0x58, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xC2, 0x89, 0x2A, 0x89, 0x49, 0xC2, 0x16, 0x1C, 0xB8, 0x7C, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x23 }, -{ 0xC2, 0x17, 0x3D, 0x6A, 0x00, 0xC4, 0x2E, 0x2D, 0xC9, 0x20, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x06, 0x1E, 0x1C, 0x99, 0x00, 0x02, 0x3A, 0x4C, 0x79, 0x00, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x84, 0x40, 0x3B, 0x5A, 0x6F, 0x81, 0x0E, 0x3B, 0x5A, 0x7F, 0x0B, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x84, 0x40, 0x3B, 0x5A, 0x63, 0x81, 0x00, 0x3B, 0x5A, 0x7F, 0x01, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x8C, 0x80, 0x05, 0xEA, 0x59, 0x82, 0x0A, 0x3C, 0xAA, 0x64, 0x07, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x85, 0x40, 0x0D, 0xEC, 0x71, 0x84, 0x58, 0x3E, 0xCB, 0x7C, 0x01, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x8A, 0xC0, 0x0C, 0xDC, 0x50, 0x88, 0x58, 0x3D, 0xDA, 0x7C, 0x01, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xC9, 0x40, 0x2B, 0x78, 0x42, 0xC2, 0x04, 0x4C, 0x8A, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x1A }, -{ 0x2A, 0x0E, 0x17, 0x89, 0x28, 0x22, 0x0C, 0x1B, 0x09, 0x70, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE7, 0x9B, 0x08, 0x08, 0x26, 0xE2, 0x06, 0x0A, 0x08, 0x70, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xC5, 0x05, 0x00, 0xFC, 0x40, 0x84, 0x00, 0x00, 0xDC, 0x50, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x86, 0x40, 0x5D, 0x5A, 0x41, 0x81, 0x00, 0x0B, 0x5A, 0x7F, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, +{ 0xC2, 0xC5, 0x2B, 0x99, 0x58, 0xC2, 0x1F, 0x1E, 0xC8, 0x7C, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x23 }, +{ 0x22, 0x53, 0x0E, 0x8A, 0x30, 0x14, 0x06, 0x1D, 0x7A, 0x5C, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x06, 0x00, 0x1C, 0x79, 0x40, 0x02, 0x00, 0x4B, 0x79, 0x58, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xC2, 0x89, 0x2A, 0x89, 0x49, 0xC2, 0x16, 0x1C, 0xB8, 0x7C, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x23 }, +{ 0xC2, 0x17, 0x3D, 0x6A, 0x00, 0xC4, 0x2E, 0x2D, 0xC9, 0x20, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x06, 0x1E, 0x1C, 0x99, 0x00, 0x02, 0x3A, 0x4C, 0x79, 0x00, 0x0C, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x84, 0x40, 0x3B, 0x5A, 0x6F, 0x81, 0x0E, 0x3B, 0x5A, 0x7F, 0x0B, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x84, 0x40, 0x3B, 0x5A, 0x63, 0x81, 0x00, 0x3B, 0x5A, 0x7F, 0x01, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x8C, 0x80, 0x05, 0xEA, 0x59, 0x82, 0x0A, 0x3C, 0xAA, 0x64, 0x07, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x85, 0x40, 0x0D, 0xEC, 0x71, 0x84, 0x58, 0x3E, 0xCB, 0x7C, 0x01, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x8A, 0xC0, 0x0C, 0xDC, 0x50, 0x88, 0x58, 0x3D, 0xDA, 0x7C, 0x01, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xC9, 0x40, 0x2B, 0x78, 0x42, 0xC2, 0x04, 0x4C, 0x8A, 0x7C, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x1A }, +{ 0x2A, 0x0E, 0x17, 0x89, 0x28, 0x22, 0x0C, 0x1B, 0x09, 0x70, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE7, 0x9B, 0x08, 0x08, 0x26, 0xE2, 0x06, 0x0A, 0x08, 0x70, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xC5, 0x05, 0x00, 0xFC, 0x40, 0x84, 0x00, 0x00, 0xDC, 0x50, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x86, 0x40, 0x5D, 0x5A, 0x41, 0x81, 0x00, 0x0B, 0x5A, 0x7F, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 },  	// 0x10 -{ 0xED, 0x00, 0x7B, 0xC8, 0x40, 0xE1, 0x99, 0x4A, 0xE9, 0x7E, 0x07, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE8, 0x4F, 0x3A, 0xD7, 0x7C, 0xE2, 0x97, 0x49, 0xF9, 0x7D, 0x05, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE1, 0x10, 0x2F, 0xF7, 0x7D, 0xF3, 0x45, 0x8F, 0xC7, 0x62, 0x07, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x01, 0x8C, 0x9F, 0xDA, 0x70, 0xE4, 0x50, 0x9F, 0xDA, 0x6A, 0x09, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x08, 0xD5, 0x9D, 0xA5, 0x45, 0xE2, 0x3F, 0x9F, 0xD6, 0x49, 0x07, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE5, 0x0F, 0x7D, 0xB8, 0x2E, 0xA2, 0x0F, 0x7C, 0xC7, 0x61, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xF2, 0x2A, 0x9F, 0xDB, 0x01, 0xE1, 0x04, 0x8F, 0xD7, 0x62, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0x88, 0x9C, 0x50, 0x64, 0xE2, 0x18, 0x70, 0xC4, 0x7C, 0x0B, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x02, 0xA3, 0x0D, 0xDA, 0x01, 0xC2, 0x35, 0x5D, 0x58, 0x00, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x18 }, -{ 0x42, 0x55, 0x3E, 0xEB, 0x24, 0xD4, 0x08, 0x0D, 0xA9, 0x71, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x18 }, -{ 0xC2, 0x00, 0x2B, 0x17, 0x51, 0xC2, 0x1E, 0x4D, 0x97, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x19 }, -{ 0xC6, 0x01, 0x2D, 0xA7, 0x44, 0xC2, 0x06, 0x0E, 0xA7, 0x79, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xC2, 0x0C, 0x06, 0x06, 0x55, 0xC2, 0x3F, 0x09, 0x86, 0x7D, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0A }, -{ 0xC2, 0x2E, 0x4F, 0x77, 0x00, 0xC4, 0x08, 0x0E, 0x98, 0x59, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xC2, 0x30, 0x4F, 0xCA, 0x01, 0xC4, 0x0D, 0x0E, 0xB8, 0x7F, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xC4, 0x29, 0x4F, 0xCA, 0x03, 0xC8, 0x0D, 0x0C, 0xB7, 0x7D, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0B }, +{ 0xED, 0x00, 0x7B, 0xC8, 0x40, 0xE1, 0x99, 0x4A, 0xE9, 0x7E, 0x07, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE8, 0x4F, 0x3A, 0xD7, 0x7C, 0xE2, 0x97, 0x49, 0xF9, 0x7D, 0x05, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE1, 0x10, 0x2F, 0xF7, 0x7D, 0xF3, 0x45, 0x8F, 0xC7, 0x62, 0x07, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x01, 0x8C, 0x9F, 0xDA, 0x70, 0xE4, 0x50, 0x9F, 0xDA, 0x6A, 0x09, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x08, 0xD5, 0x9D, 0xA5, 0x45, 0xE2, 0x3F, 0x9F, 0xD6, 0x49, 0x07, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE5, 0x0F, 0x7D, 0xB8, 0x2E, 0xA2, 0x0F, 0x7C, 0xC7, 0x61, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xF2, 0x2A, 0x9F, 0xDB, 0x01, 0xE1, 0x04, 0x8F, 0xD7, 0x62, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0x88, 0x9C, 0x50, 0x64, 0xE2, 0x18, 0x70, 0xC4, 0x7C, 0x0B, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x02, 0xA3, 0x0D, 0xDA, 0x01, 0xC2, 0x35, 0x5D, 0x58, 0x00, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x18 }, +{ 0x42, 0x55, 0x3E, 0xEB, 0x24, 0xD4, 0x08, 0x0D, 0xA9, 0x71, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x18 }, +{ 0xC2, 0x00, 0x2B, 0x17, 0x51, 0xC2, 0x1E, 0x4D, 0x97, 0x7C, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x19 }, +{ 0xC6, 0x01, 0x2D, 0xA7, 0x44, 0xC2, 0x06, 0x0E, 0xA7, 0x79, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xC2, 0x0C, 0x06, 0x06, 0x55, 0xC2, 0x3F, 0x09, 0x86, 0x7D, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x0A }, +{ 0xC2, 0x2E, 0x4F, 0x77, 0x00, 0xC4, 0x08, 0x0E, 0x98, 0x59, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xC2, 0x30, 0x4F, 0xCA, 0x01, 0xC4, 0x0D, 0x0E, 0xB8, 0x7F, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xC4, 0x29, 0x4F, 0xCA, 0x03, 0xC8, 0x0D, 0x0C, 0xB7, 0x7D, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x0B },  	// 0x20 -{ 0xC2, 0x40, 0x3C, 0x96, 0x58, 0xC4, 0xDE, 0x0E, 0xC7, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x20 }, -{ 0x31, 0x13, 0x2D, 0xD7, 0x3C, 0xE2, 0x18, 0x2E, 0xB8, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x22, 0x86, 0x0D, 0xD7, 0x50, 0xE4, 0x18, 0x5E, 0xB8, 0x7C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x28 }, -{ 0xF2, 0x0A, 0x0D, 0xD7, 0x40, 0xE4, 0x1F, 0x5E, 0xB8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xF2, 0x09, 0x4B, 0xD6, 0x48, 0xE4, 0x1F, 0x1C, 0xB8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x28 }, -{ 0x62, 0x11, 0x0C, 0xE6, 0x3C, 0xE4, 0x1F, 0x0C, 0xC8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x12, 0x3D, 0xE6, 0x34, 0xE4, 0x1F, 0x7D, 0xB8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x13, 0x3D, 0xE6, 0x34, 0xE4, 0x1F, 0x5D, 0xB8, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xA2, 0x40, 0x5D, 0xBA, 0x3F, 0xE2, 0x00, 0x8F, 0xD8, 0x79, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x40, 0x3D, 0xDA, 0x3B, 0xE1, 0x00, 0x7E, 0xD8, 0x7A, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x62, 0x00, 0x6D, 0xFA, 0x5D, 0xE2, 0x00, 0x8F, 0xC8, 0x79, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE1, 0x00, 0x4E, 0xDB, 0x4A, 0xE3, 0x18, 0x6F, 0xE9, 0x7E, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE1, 0x00, 0x4E, 0xDB, 0x66, 0xE2, 0x00, 0x7F, 0xE9, 0x7E, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x02, 0x0F, 0x66, 0xAA, 0x51, 0x02, 0x64, 0x29, 0xF9, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 }, -{ 0x16, 0x4A, 0x04, 0xBA, 0x39, 0xC2, 0x58, 0x2D, 0xCA, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 }, -{ 0x02, 0x00, 0x01, 0x7A, 0x79, 0x02, 0x3F, 0x28, 0xEA, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, +{ 0xC2, 0x40, 0x3C, 0x96, 0x58, 0xC4, 0xDE, 0x0E, 0xC7, 0x7C, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x20 }, +{ 0x31, 0x13, 0x2D, 0xD7, 0x3C, 0xE2, 0x18, 0x2E, 0xB8, 0x7C, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x22, 0x86, 0x0D, 0xD7, 0x50, 0xE4, 0x18, 0x5E, 0xB8, 0x7C, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x28 }, +{ 0xF2, 0x0A, 0x0D, 0xD7, 0x40, 0xE4, 0x1F, 0x5E, 0xB8, 0x7C, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xF2, 0x09, 0x4B, 0xD6, 0x48, 0xE4, 0x1F, 0x1C, 0xB8, 0x7C, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x28 }, +{ 0x62, 0x11, 0x0C, 0xE6, 0x3C, 0xE4, 0x1F, 0x0C, 0xC8, 0x7C, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x12, 0x3D, 0xE6, 0x34, 0xE4, 0x1F, 0x7D, 0xB8, 0x7C, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x13, 0x3D, 0xE6, 0x34, 0xE4, 0x1F, 0x5D, 0xB8, 0x7D, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xA2, 0x40, 0x5D, 0xBA, 0x3F, 0xE2, 0x00, 0x8F, 0xD8, 0x79, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x40, 0x3D, 0xDA, 0x3B, 0xE1, 0x00, 0x7E, 0xD8, 0x7A, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x62, 0x00, 0x6D, 0xFA, 0x5D, 0xE2, 0x00, 0x8F, 0xC8, 0x79, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE1, 0x00, 0x4E, 0xDB, 0x4A, 0xE3, 0x18, 0x6F, 0xE9, 0x7E, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE1, 0x00, 0x4E, 0xDB, 0x66, 0xE2, 0x00, 0x7F, 0xE9, 0x7E, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x02, 0x0F, 0x66, 0xAA, 0x51, 0x02, 0x64, 0x29, 0xF9, 0x7C, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x04 }, +{ 0x16, 0x4A, 0x04, 0xBA, 0x39, 0xC2, 0x58, 0x2D, 0xCA, 0x7C, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x03 }, +{ 0x02, 0x00, 0x01, 0x7A, 0x79, 0x02, 0x3F, 0x28, 0xEA, 0x7C, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 },  	// 0x30 -{ 0x62, 0x53, 0x9C, 0xBA, 0x31, 0x62, 0x5B, 0xAD, 0xC9, 0x55, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xF2, 0x40, 0x6E, 0xDA, 0x49, 0xE2, 0x13, 0x8F, 0xF9, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x40, 0x8F, 0xFA, 0x50, 0xF2, 0x04, 0x7F, 0xFA, 0x7D, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0xA0, 0xCE, 0x5B, 0x02, 0xE2, 0x32, 0x7F, 0xFB, 0x3D, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE6, 0x80, 0x9C, 0x99, 0x42, 0xE2, 0x04, 0x7D, 0x78, 0x60, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xEA, 0xA0, 0xAC, 0x67, 0x02, 0xE2, 0x00, 0x7C, 0x7A, 0x7C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE7, 0x94, 0xAD, 0xB7, 0x03, 0xE2, 0x00, 0x7C, 0xBA, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xC3, 0x3F, 0x4B, 0xE9, 0x7E, 0xC1, 0x3F, 0x9B, 0xF9, 0x7F, 0x0B, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x06 }, -{ 0xB2, 0x20, 0xAD, 0xE9, 0x00, 0x62, 0x05, 0x8F, 0xC8, 0x68, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xF2, 0x00, 0x8F, 0xFB, 0x50, 0xF6, 0x47, 0x8F, 0xE9, 0x68, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xF2, 0x00, 0xAF, 0x88, 0x58, 0xF2, 0x54, 0x6E, 0xC9, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xF2, 0x2A, 0x9F, 0x98, 0x01, 0xE2, 0x84, 0x4E, 0x78, 0x6C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x02, 0x9F, 0xB8, 0x48, 0x22, 0x89, 0x9F, 0xE8, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x2A, 0x7F, 0xB8, 0x01, 0xE4, 0x00, 0x0D, 0xC5, 0x7C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0x28, 0x8E, 0xE8, 0x01, 0xF2, 0x00, 0x4D, 0xD6, 0x7D, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x62, 0x23, 0x8F, 0xEA, 0x00, 0xF2, 0x00, 0x5E, 0xD9, 0x7C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, +{ 0x62, 0x53, 0x9C, 0xBA, 0x31, 0x62, 0x5B, 0xAD, 0xC9, 0x55, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xF2, 0x40, 0x6E, 0xDA, 0x49, 0xE2, 0x13, 0x8F, 0xF9, 0x7D, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x40, 0x8F, 0xFA, 0x50, 0xF2, 0x04, 0x7F, 0xFA, 0x7D, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0xA0, 0xCE, 0x5B, 0x02, 0xE2, 0x32, 0x7F, 0xFB, 0x3D, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE6, 0x80, 0x9C, 0x99, 0x42, 0xE2, 0x04, 0x7D, 0x78, 0x60, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xEA, 0xA0, 0xAC, 0x67, 0x02, 0xE2, 0x00, 0x7C, 0x7A, 0x7C, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE7, 0x94, 0xAD, 0xB7, 0x03, 0xE2, 0x00, 0x7C, 0xBA, 0x7C, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xC3, 0x3F, 0x4B, 0xE9, 0x7E, 0xC1, 0x3F, 0x9B, 0xF9, 0x7F, 0x0B, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x06 }, +{ 0xB2, 0x20, 0xAD, 0xE9, 0x00, 0x62, 0x05, 0x8F, 0xC8, 0x68, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xF2, 0x00, 0x8F, 0xFB, 0x50, 0xF6, 0x47, 0x8F, 0xE9, 0x68, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xF2, 0x00, 0xAF, 0x88, 0x58, 0xF2, 0x54, 0x6E, 0xC9, 0x7C, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xF2, 0x2A, 0x9F, 0x98, 0x01, 0xE2, 0x84, 0x4E, 0x78, 0x6C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x02, 0x9F, 0xB8, 0x48, 0x22, 0x89, 0x9F, 0xE8, 0x7C, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x2A, 0x7F, 0xB8, 0x01, 0xE4, 0x00, 0x0D, 0xC5, 0x7C, 0x0C, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0x28, 0x8E, 0xE8, 0x01, 0xF2, 0x00, 0x4D, 0xD6, 0x7D, 0x0C, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x62, 0x23, 0x8F, 0xEA, 0x00, 0xF2, 0x00, 0x5E, 0xD9, 0x7C, 0x0C, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 },  	// 0x40 -{ 0xB4, 0x26, 0x6E, 0x98, 0x01, 0x62, 0x00, 0x7D, 0xC8, 0x7D, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x2E, 0x20, 0xD9, 0x01, 0xF2, 0x0F, 0x90, 0xF8, 0x78, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0x28, 0x7E, 0xF8, 0x01, 0xE2, 0x23, 0x8E, 0xE8, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xB8, 0x28, 0x9E, 0x98, 0x01, 0x62, 0x00, 0x3D, 0xC8, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x62, 0x00, 0x8E, 0xC9, 0x3D, 0xE6, 0x00, 0x7E, 0xD8, 0x68, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x00, 0x5F, 0xF9, 0x48, 0xE6, 0x98, 0x8F, 0xF8, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x62, 0x0C, 0x6E, 0xD8, 0x3D, 0x2A, 0x06, 0x7D, 0xD8, 0x58, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0x00, 0x7E, 0x89, 0x38, 0xE6, 0x84, 0x80, 0xF8, 0x68, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0x80, 0x6C, 0xD9, 0x30, 0xE2, 0x00, 0x8D, 0xC8, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x80, 0x88, 0x48, 0x40, 0xE2, 0x0A, 0x7D, 0xA8, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0x00, 0x77, 0xC5, 0x54, 0xE2, 0x00, 0x9E, 0xD7, 0x70, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0x80, 0x86, 0xB9, 0x64, 0xE2, 0x05, 0x9F, 0xD7, 0x78, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x00, 0x68, 0x68, 0x56, 0xE2, 0x08, 0x9B, 0xB3, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0x00, 0xA6, 0x87, 0x41, 0xE2, 0x0A, 0x7E, 0xC9, 0x7C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0x80, 0x9A, 0xB8, 0x48, 0xE2, 0x00, 0x9E, 0xF9, 0x60, 0x09, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x80, 0x8E, 0x64, 0x68, 0xE2, 0x28, 0x6F, 0x73, 0x7C, 0x01, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, +{ 0xB4, 0x26, 0x6E, 0x98, 0x01, 0x62, 0x00, 0x7D, 0xC8, 0x7D, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x2E, 0x20, 0xD9, 0x01, 0xF2, 0x0F, 0x90, 0xF8, 0x78, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0x28, 0x7E, 0xF8, 0x01, 0xE2, 0x23, 0x8E, 0xE8, 0x7D, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xB8, 0x28, 0x9E, 0x98, 0x01, 0x62, 0x00, 0x3D, 0xC8, 0x7D, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x62, 0x00, 0x8E, 0xC9, 0x3D, 0xE6, 0x00, 0x7E, 0xD8, 0x68, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x00, 0x5F, 0xF9, 0x48, 0xE6, 0x98, 0x8F, 0xF8, 0x7D, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x62, 0x0C, 0x6E, 0xD8, 0x3D, 0x2A, 0x06, 0x7D, 0xD8, 0x58, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0x00, 0x7E, 0x89, 0x38, 0xE6, 0x84, 0x80, 0xF8, 0x68, 0x0C, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0x80, 0x6C, 0xD9, 0x30, 0xE2, 0x00, 0x8D, 0xC8, 0x7C, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x80, 0x88, 0x48, 0x40, 0xE2, 0x0A, 0x7D, 0xA8, 0x7C, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0x00, 0x77, 0xC5, 0x54, 0xE2, 0x00, 0x9E, 0xD7, 0x70, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0x80, 0x86, 0xB9, 0x64, 0xE2, 0x05, 0x9F, 0xD7, 0x78, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x00, 0x68, 0x68, 0x56, 0xE2, 0x08, 0x9B, 0xB3, 0x7C, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0x00, 0xA6, 0x87, 0x41, 0xE2, 0x0A, 0x7E, 0xC9, 0x7C, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0x80, 0x9A, 0xB8, 0x48, 0xE2, 0x00, 0x9E, 0xF9, 0x60, 0x09, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x80, 0x8E, 0x64, 0x68, 0xE2, 0x28, 0x6F, 0x73, 0x7C, 0x01, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 },  	// 0x50 -{ 0xE8, 0x00, 0x7D, 0x99, 0x54, 0xE6, 0x80, 0x80, 0xF8, 0x7C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE6, 0x00, 0x9F, 0xB9, 0x6D, 0xE1, 0x00, 0x8F, 0xC8, 0x7D, 0x02, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0x00, 0x09, 0x68, 0x4A, 0xE2, 0x2B, 0x9E, 0xF3, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xC4, 0x00, 0x99, 0xE8, 0x3B, 0xE2, 0x25, 0x6F, 0x93, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE6, 0x00, 0x6F, 0xDA, 0x69, 0xE2, 0x05, 0x2F, 0xD8, 0x6A, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xEC, 0x60, 0x9D, 0xC7, 0x00, 0xE2, 0x21, 0x7F, 0xC9, 0x7C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE3, 0x00, 0x0F, 0xF7, 0x7D, 0xE1, 0x3F, 0x0F, 0xA7, 0x01, 0x0D, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0xA9, 0x0F, 0xA8, 0x02, 0xE2, 0x3C, 0x5F, 0xDA, 0x3C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE8, 0x40, 0x0D, 0x89, 0x7D, 0xE2, 0x17, 0x7E, 0xD9, 0x7C, 0x07, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE1, 0x00, 0xDF, 0x8A, 0x56, 0xE2, 0x5E, 0xCF, 0xBA, 0x7E, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE2, 0x00, 0x0B, 0x68, 0x60, 0xE2, 0x01, 0x9E, 0xB8, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xEA, 0x00, 0xAE, 0xAB, 0x49, 0xE2, 0x00, 0xAE, 0xBA, 0x6C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xEB, 0x80, 0x8C, 0xCB, 0x3A, 0xE2, 0x86, 0xAF, 0xCA, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE5, 0x40, 0xDB, 0x3B, 0x3C, 0xE2, 0x80, 0xBE, 0xCA, 0x71, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE4, 0x00, 0x9E, 0xAA, 0x3D, 0xE1, 0x43, 0x0F, 0xBA, 0x7E, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE7, 0x40, 0xEC, 0xCA, 0x44, 0xE2, 0x03, 0xBF, 0xBA, 0x66, 0x02, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, +{ 0xE8, 0x00, 0x7D, 0x99, 0x54, 0xE6, 0x80, 0x80, 0xF8, 0x7C, 0x0C, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE6, 0x00, 0x9F, 0xB9, 0x6D, 0xE1, 0x00, 0x8F, 0xC8, 0x7D, 0x02, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0x00, 0x09, 0x68, 0x4A, 0xE2, 0x2B, 0x9E, 0xF3, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xC4, 0x00, 0x99, 0xE8, 0x3B, 0xE2, 0x25, 0x6F, 0x93, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE6, 0x00, 0x6F, 0xDA, 0x69, 0xE2, 0x05, 0x2F, 0xD8, 0x6A, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xEC, 0x60, 0x9D, 0xC7, 0x00, 0xE2, 0x21, 0x7F, 0xC9, 0x7C, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE3, 0x00, 0x0F, 0xF7, 0x7D, 0xE1, 0x3F, 0x0F, 0xA7, 0x01, 0x0D, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0xA9, 0x0F, 0xA8, 0x02, 0xE2, 0x3C, 0x5F, 0xDA, 0x3C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE8, 0x40, 0x0D, 0x89, 0x7D, 0xE2, 0x17, 0x7E, 0xD9, 0x7C, 0x07, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE1, 0x00, 0xDF, 0x8A, 0x56, 0xE2, 0x5E, 0xCF, 0xBA, 0x7E, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE2, 0x00, 0x0B, 0x68, 0x60, 0xE2, 0x01, 0x9E, 0xB8, 0x7C, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xEA, 0x00, 0xAE, 0xAB, 0x49, 0xE2, 0x00, 0xAE, 0xBA, 0x6C, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xEB, 0x80, 0x8C, 0xCB, 0x3A, 0xE2, 0x86, 0xAF, 0xCA, 0x7C, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE5, 0x40, 0xDB, 0x3B, 0x3C, 0xE2, 0x80, 0xBE, 0xCA, 0x71, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE4, 0x00, 0x9E, 0xAA, 0x3D, 0xE1, 0x43, 0x0F, 0xBA, 0x7E, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE7, 0x40, 0xEC, 0xCA, 0x44, 0xE2, 0x03, 0xBF, 0xBA, 0x66, 0x02, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 },  	// 0x60 -{ 0xEA, 0x00, 0x68, 0xB8, 0x48, 0xE2, 0x0A, 0x8E, 0xB8, 0x7C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x61, 0x00, 0xBE, 0x99, 0x7E, 0xE3, 0x40, 0xCF, 0xCA, 0x7D, 0x09, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xCD, 0x00, 0x0B, 0x00, 0x48, 0xC2, 0x58, 0x0C, 0x00, 0x7C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x1C }, -{ 0xE2, 0x00, 0x0E, 0x00, 0x52, 0xE2, 0x58, 0x5F, 0xD0, 0x7D, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xCC, 0x00, 0x7D, 0xDA, 0x40, 0xC2, 0x00, 0x5E, 0x9B, 0x58, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE9, 0xC0, 0xEE, 0xD8, 0x43, 0xE2, 0x05, 0xDD, 0xAA, 0x70, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xDA, 0x00, 0x8F, 0xAC, 0x4A, 0x22, 0x05, 0x8D, 0x8A, 0x75, 0x02, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x62, 0x8A, 0xCB, 0x7A, 0x74, 0xE6, 0x56, 0xAF, 0xDB, 0x70, 0x02, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xC2, 0x41, 0xAC, 0x5B, 0x5B, 0xC2, 0x80, 0x0D, 0xCB, 0x7D, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x12 }, -{ 0x75, 0x00, 0x0E, 0xCB, 0x5A, 0xE2, 0x1E, 0x0A, 0xC9, 0x7D, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x10 }, -{ 0x41, 0x00, 0x0E, 0xEA, 0x53, 0xC2, 0x00, 0x08, 0xCA, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x07 }, -{ 0xC1, 0x40, 0x0C, 0x59, 0x6A, 0xC2, 0x80, 0x3C, 0xAB, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0D }, -{ 0x4B, 0x00, 0x0A, 0xF5, 0x61, 0xC2, 0x19, 0x0C, 0xE9, 0x7C, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x07 }, -{ 0x62, 0x00, 0x7F, 0xD8, 0x54, 0xEA, 0x00, 0x8F, 0xD8, 0x7D, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE1, 0x00, 0x7F, 0xD9, 0x56, 0xE1, 0x00, 0x8F, 0xD8, 0x7E, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0xE1, 0x00, 0x7F, 0xD9, 0x56, 0xE1, 0x00, 0x8F, 0xD8, 0x7E, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, +{ 0xEA, 0x00, 0x68, 0xB8, 0x48, 0xE2, 0x0A, 0x8E, 0xB8, 0x7C, 0x0C, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x61, 0x00, 0xBE, 0x99, 0x7E, 0xE3, 0x40, 0xCF, 0xCA, 0x7D, 0x09, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xCD, 0x00, 0x0B, 0x00, 0x48, 0xC2, 0x58, 0x0C, 0x00, 0x7C, 0x0C, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x1C }, +{ 0xE2, 0x00, 0x0E, 0x00, 0x52, 0xE2, 0x58, 0x5F, 0xD0, 0x7D, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xCC, 0x00, 0x7D, 0xDA, 0x40, 0xC2, 0x00, 0x5E, 0x9B, 0x58, 0x0C, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE9, 0xC0, 0xEE, 0xD8, 0x43, 0xE2, 0x05, 0xDD, 0xAA, 0x70, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xDA, 0x00, 0x8F, 0xAC, 0x4A, 0x22, 0x05, 0x8D, 0x8A, 0x75, 0x02, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x62, 0x8A, 0xCB, 0x7A, 0x74, 0xE6, 0x56, 0xAF, 0xDB, 0x70, 0x02, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xC2, 0x41, 0xAC, 0x5B, 0x5B, 0xC2, 0x80, 0x0D, 0xCB, 0x7D, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x12 }, +{ 0x75, 0x00, 0x0E, 0xCB, 0x5A, 0xE2, 0x1E, 0x0A, 0xC9, 0x7D, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x10 }, +{ 0x41, 0x00, 0x0E, 0xEA, 0x53, 0xC2, 0x00, 0x08, 0xCA, 0x7C, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x07 }, +{ 0xC1, 0x40, 0x0C, 0x59, 0x6A, 0xC2, 0x80, 0x3C, 0xAB, 0x7C, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x0D }, +{ 0x4B, 0x00, 0x0A, 0xF5, 0x61, 0xC2, 0x19, 0x0C, 0xE9, 0x7C, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x07 }, +{ 0x62, 0x00, 0x7F, 0xD8, 0x54, 0xEA, 0x00, 0x8F, 0xD8, 0x7D, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE1, 0x00, 0x7F, 0xD9, 0x56, 0xE1, 0x00, 0x8F, 0xD8, 0x7E, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0xE1, 0x00, 0x7F, 0xD9, 0x56, 0xE1, 0x00, 0x8F, 0xD8, 0x7E, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 },  	// 0x70 -{ 0xCF, 0x40, 0x09, 0xEA, 0x54, 0xC4, 0x00, 0x0C, 0xDB, 0x64, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0xCF, 0x40, 0x0C, 0xAA, 0x54, 0xC4, 0x00, 0x18, 0xF9, 0x64, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0xC9, 0x0E, 0x88, 0xD9, 0x3E, 0xC2, 0x08, 0x1A, 0xEA, 0x6C, 0x0C, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 }, -{ 0x03, 0x00, 0x15, 0x00, 0x64, 0x02, 0x00, 0x08, 0x00, 0x7C, 0x09, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0x01, 0x00, 0x47, 0xD7, 0x6C, 0x01, 0x3F, 0x0C, 0xFB, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 }, -{ 0x00, 0x00, 0x36, 0x67, 0x7C, 0x01, 0x3F, 0x0E, 0xFA, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 }, -{ 0x02, 0x00, 0x36, 0x68, 0x7C, 0x01, 0x3F, 0x0E, 0xFA, 0x7C, 0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 }, -{ 0xCB, 0x00, 0xAF, 0x00, 0x7E, 0xC0, 0x00, 0xC0, 0x06, 0x7F, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0F }, -{ 0x05, 0x0D, 0x80, 0xA6, 0x7F, 0x0B, 0x38, 0xA9, 0xD8, 0x00, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 }, -{ 0x0F, 0x00, 0x90, 0xFA, 0x68, 0x06, 0x00, 0xA7, 0x39, 0x54, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x06 }, -{ 0xC9, 0x15, 0xDD, 0xFF, 0x7C, 0x00, 0x00, 0xE7, 0xFC, 0x6C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x38 }, -{ 0x48, 0x3C, 0x30, 0xF6, 0x03, 0x0A, 0x38, 0x97, 0xE8, 0x00, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 }, -{ 0x07, 0x80, 0x0B, 0xC8, 0x65, 0x02, 0x3F, 0x0C, 0xEA, 0x7C, 0x0F, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 }, -{ 0x00, 0x21, 0x66, 0x40, 0x03, 0x00, 0x3F, 0x47, 0x00, 0x00, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0x08, 0x00, 0x0B, 0x3C, 0x7C, 0x08, 0x3F, 0x06, 0xF3, 0x00, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0x00, 0x3F, 0x4C, 0xFB, 0x00, 0x00, 0x3F, 0x0A, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 } +{ 0xCF, 0x40, 0x09, 0xEA, 0x54, 0xC4, 0x00, 0x0C, 0xDB, 0x64, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0xCF, 0x40, 0x0C, 0xAA, 0x54, 0xC4, 0x00, 0x18, 0xF9, 0x64, 0x0C, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0xC9, 0x0E, 0x88, 0xD9, 0x3E, 0xC2, 0x08, 0x1A, 0xEA, 0x6C, 0x0C, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x05 }, +{ 0x03, 0x00, 0x15, 0x00, 0x64, 0x02, 0x00, 0x08, 0x00, 0x7C, 0x09, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0x01, 0x00, 0x47, 0xD7, 0x6C, 0x01, 0x3F, 0x0C, 0xFB, 0x7C, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x04 }, +{ 0x00, 0x00, 0x36, 0x67, 0x7C, 0x01, 0x3F, 0x0E, 0xFA, 0x7C, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x05 }, +{ 0x02, 0x00, 0x36, 0x68, 0x7C, 0x01, 0x3F, 0x0E, 0xFA, 0x7C, 0x00, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x05 }, +{ 0xCB, 0x00, 0xAF, 0x00, 0x7E, 0xC0, 0x00, 0xC0, 0x06, 0x7F, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x0F }, +{ 0x05, 0x0D, 0x80, 0xA6, 0x7F, 0x0B, 0x38, 0xA9, 0xD8, 0x00, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x04 }, +{ 0x0F, 0x00, 0x90, 0xFA, 0x68, 0x06, 0x00, 0xA7, 0x39, 0x54, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x06 }, +{ 0xC9, 0x15, 0xDD, 0xFF, 0x7C, 0x00, 0x00, 0xE7, 0xFC, 0x6C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x38 }, +{ 0x48, 0x3C, 0x30, 0xF6, 0x03, 0x0A, 0x38, 0x97, 0xE8, 0x00, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x04 }, +{ 0x07, 0x80, 0x0B, 0xC8, 0x65, 0x02, 0x3F, 0x0C, 0xEA, 0x7C, 0x0F, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x05 }, +{ 0x00, 0x21, 0x66, 0x40, 0x03, 0x00, 0x3F, 0x47, 0x00, 0x00, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0x08, 0x00, 0x0B, 0x3C, 0x7C, 0x08, 0x3F, 0x06, 0xF3, 0x00, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0x00, 0x3F, 0x4C, 0xFB, 0x00, 0x00, 0x3F, 0x0A, 0xE9, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x05 }  }; -static byte gm_percussion_to_fm[39][30] = { -{ 0x1A, 0x3F, 0x15, 0x05, 0x7C, 0x02, 0x21, 0x2B, 0xE4, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x06 }, -{ 0x11, 0x12, 0x04, 0x07, 0x7C, 0x02, 0x23, 0x0B, 0xE5, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 }, -{ 0x0A, 0x3F, 0x0B, 0x01, 0x7C, 0x1F, 0x1C, 0x46, 0xD0, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x01 }, -{ 0x00, 0x3F, 0x0F, 0x00, 0x7C, 0x10, 0x12, 0x07, 0x00, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0x0F, 0x3F, 0x0B, 0x00, 0x7C, 0x1F, 0x0F, 0x19, 0xD0, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0x00, 0x3F, 0x1F, 0x00, 0x7E, 0x1F, 0x16, 0x07, 0x00, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 }, -{ 0x12, 0x3F, 0x05, 0x06, 0x7C, 0x03, 0x1F, 0x4A, 0xD9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 }, -{ 0xCF, 0x7F, 0x08, 0xFF, 0x7E, 0x00, 0xC7, 0x2D, 0xF7, 0x73, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0x12, 0x3F, 0x05, 0x06, 0x7C, 0x43, 0x21, 0x0C, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 }, -{ 0xCF, 0x7F, 0x08, 0xCF, 0x7E, 0x00, 0x45, 0x2A, 0xF8, 0x4B, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0C }, -{ 0x12, 0x3F, 0x06, 0x17, 0x7C, 0x03, 0x27, 0x0B, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 }, -{ 0xCF, 0x7F, 0x08, 0xCD, 0x7E, 0x00, 0x40, 0x1A, 0x69, 0x63, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0C }, -{ 0x13, 0x3F, 0x05, 0x06, 0x7C, 0x03, 0x17, 0x0A, 0xD9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 }, -{ 0x15, 0x3F, 0x05, 0x06, 0x7C, 0x03, 0x21, 0x0C, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 }, -{ 0xCF, 0x3F, 0x2B, 0xFB, 0x7E, 0xC0, 0x1E, 0x1A, 0xCA, 0x7F, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x10 }, -{ 0x17, 0x3F, 0x04, 0x09, 0x7C, 0x03, 0x22, 0x0D, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 }, -{ 0xCF, 0x3F, 0x0F, 0x5E, 0x7C, 0xC6, 0x13, 0x00, 0xCA, 0x7F, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 }, -{ 0xCF, 0x3F, 0x7E, 0x9D, 0x7C, 0xC8, 0xC0, 0x0A, 0xBA, 0x74, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x06 }, -{ 0xCF, 0x3F, 0x4D, 0x9F, 0x7C, 0xC6, 0x00, 0x08, 0xDA, 0x5B, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 }, -{ 0xCF, 0x3F, 0x5D, 0xAA, 0x7A, 0xC0, 0xA4, 0x67, 0x99, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0xCF, 0x3F, 0x4A, 0xFD, 0x7C, 0xCF, 0x00, 0x59, 0xEA, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0x0F, 0x18, 0x0A, 0xFA, 0x57, 0x06, 0x07, 0x06, 0x39, 0x7C, 0x0A, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0xCF, 0x3F, 0x2B, 0xFC, 0x7C, 0xCC, 0xC6, 0x0B, 0xEA, 0x7F, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x10 }, -{ 0x05, 0x1A, 0x04, 0x00, 0x7C, 0x12, 0x10, 0x0C, 0xEA, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x07 }, -{ 0x04, 0x19, 0x04, 0x00, 0x7C, 0x12, 0x10, 0x2C, 0xEA, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x04 }, -{ 0x04, 0x0A, 0x04, 0x00, 0x6C, 0x01, 0x07, 0x0D, 0xFA, 0x74, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x07 }, -{ 0x15, 0x14, 0x05, 0x00, 0x7D, 0x01, 0x07, 0x5C, 0xE9, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 }, -{ 0x10, 0x10, 0x05, 0x08, 0x7C, 0x01, 0x08, 0x0D, 0xEA, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x05 }, -{ 0x11, 0x00, 0x06, 0x87, 0x7F, 0x02, 0x40, 0x09, 0x59, 0x68, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x08 }, -{ 0x13, 0x26, 0x04, 0x6A, 0x7F, 0x01, 0x00, 0x08, 0x5A, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x08 }, -{ 0xCF, 0x4E, 0x0C, 0xAA, 0x50, 0xC4, 0x00, 0x18, 0xF9, 0x54, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0xCF, 0x4E, 0x0C, 0xAA, 0x50, 0xC3, 0x00, 0x18, 0xF8, 0x54, 0x04, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0xCB, 0x3F, 0x8F, 0x00, 0x7E, 0xC5, 0x00, 0x98, 0xD6, 0x5F, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x0D }, -{ 0x0C, 0x18, 0x87, 0xB3, 0x7F, 0x19, 0x10, 0x55, 0x75, 0x7C, 0x0E, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0x05, 0x11, 0x15, 0x00, 0x64, 0x02, 0x08, 0x08, 0x00, 0x5C, 0x09, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0x04, 0x08, 0x15, 0x00, 0x48, 0x01, 0x08, 0x08, 0x00, 0x60, 0x08, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x02 }, -{ 0xDA, 0x00, 0x53, 0x30, 0x68, 0x07, 0x1E, 0x49, 0xC4, 0x7E, 0x03, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 }, -{ 0x1C, 0x00, 0x07, 0xBC, 0x6C, 0x0C, 0x14, 0x0B, 0x6A, 0x7E, 0x0B, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x03 }, -{ 0x0A, 0x0E, 0x7F, 0x00, 0x7D, 0x13, 0x20, 0x28, 0x03, 0x7C, 0x06, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x00 } +static AdLibInstrument gm_percussion_to_fm[39] = { +{ 0x1A, 0x3F, 0x15, 0x05, 0x7C, 0x02, 0x21, 0x2B, 0xE4, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x06 }, +{ 0x11, 0x12, 0x04, 0x07, 0x7C, 0x02, 0x23, 0x0B, 0xE5, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x05 }, +{ 0x0A, 0x3F, 0x0B, 0x01, 0x7C, 0x1F, 0x1C, 0x46, 0xD0, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x01 }, +{ 0x00, 0x3F, 0x0F, 0x00, 0x7C, 0x10, 0x12, 0x07, 0x00, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0x0F, 0x3F, 0x0B, 0x00, 0x7C, 0x1F, 0x0F, 0x19, 0xD0, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0x00, 0x3F, 0x1F, 0x00, 0x7E, 0x1F, 0x16, 0x07, 0x00, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x03 }, +{ 0x12, 0x3F, 0x05, 0x06, 0x7C, 0x03, 0x1F, 0x4A, 0xD9, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x03 }, +{ 0xCF, 0x7F, 0x08, 0xFF, 0x7E, 0x00, 0xC7, 0x2D, 0xF7, 0x73, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0x12, 0x3F, 0x05, 0x06, 0x7C, 0x43, 0x21, 0x0C, 0xE9, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x03 }, +{ 0xCF, 0x7F, 0x08, 0xCF, 0x7E, 0x00, 0x45, 0x2A, 0xF8, 0x4B, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x0C }, +{ 0x12, 0x3F, 0x06, 0x17, 0x7C, 0x03, 0x27, 0x0B, 0xE9, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x03 }, +{ 0xCF, 0x7F, 0x08, 0xCD, 0x7E, 0x00, 0x40, 0x1A, 0x69, 0x63, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x0C }, +{ 0x13, 0x3F, 0x05, 0x06, 0x7C, 0x03, 0x17, 0x0A, 0xD9, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x03 }, +{ 0x15, 0x3F, 0x05, 0x06, 0x7C, 0x03, 0x21, 0x0C, 0xE9, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x03 }, +{ 0xCF, 0x3F, 0x2B, 0xFB, 0x7E, 0xC0, 0x1E, 0x1A, 0xCA, 0x7F, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x10 }, +{ 0x17, 0x3F, 0x04, 0x09, 0x7C, 0x03, 0x22, 0x0D, 0xE9, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x03 }, +{ 0xCF, 0x3F, 0x0F, 0x5E, 0x7C, 0xC6, 0x13, 0x00, 0xCA, 0x7F, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x03 }, +{ 0xCF, 0x3F, 0x7E, 0x9D, 0x7C, 0xC8, 0xC0, 0x0A, 0xBA, 0x74, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x06 }, +{ 0xCF, 0x3F, 0x4D, 0x9F, 0x7C, 0xC6, 0x00, 0x08, 0xDA, 0x5B, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x04 }, +{ 0xCF, 0x3F, 0x5D, 0xAA, 0x7A, 0xC0, 0xA4, 0x67, 0x99, 0x7C, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0xCF, 0x3F, 0x4A, 0xFD, 0x7C, 0xCF, 0x00, 0x59, 0xEA, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0x0F, 0x18, 0x0A, 0xFA, 0x57, 0x06, 0x07, 0x06, 0x39, 0x7C, 0x0A, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0xCF, 0x3F, 0x2B, 0xFC, 0x7C, 0xCC, 0xC6, 0x0B, 0xEA, 0x7F, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x10 }, +{ 0x05, 0x1A, 0x04, 0x00, 0x7C, 0x12, 0x10, 0x0C, 0xEA, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x07 }, +{ 0x04, 0x19, 0x04, 0x00, 0x7C, 0x12, 0x10, 0x2C, 0xEA, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x04 }, +{ 0x04, 0x0A, 0x04, 0x00, 0x6C, 0x01, 0x07, 0x0D, 0xFA, 0x74, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x07 }, +{ 0x15, 0x14, 0x05, 0x00, 0x7D, 0x01, 0x07, 0x5C, 0xE9, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x05 }, +{ 0x10, 0x10, 0x05, 0x08, 0x7C, 0x01, 0x08, 0x0D, 0xEA, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x05 }, +{ 0x11, 0x00, 0x06, 0x87, 0x7F, 0x02, 0x40, 0x09, 0x59, 0x68, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x08 }, +{ 0x13, 0x26, 0x04, 0x6A, 0x7F, 0x01, 0x00, 0x08, 0x5A, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x08 }, +{ 0xCF, 0x4E, 0x0C, 0xAA, 0x50, 0xC4, 0x00, 0x18, 0xF9, 0x54, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0xCF, 0x4E, 0x0C, 0xAA, 0x50, 0xC3, 0x00, 0x18, 0xF8, 0x54, 0x04, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0xCB, 0x3F, 0x8F, 0x00, 0x7E, 0xC5, 0x00, 0x98, 0xD6, 0x5F, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x0D }, +{ 0x0C, 0x18, 0x87, 0xB3, 0x7F, 0x19, 0x10, 0x55, 0x75, 0x7C, 0x0E, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0x05, 0x11, 0x15, 0x00, 0x64, 0x02, 0x08, 0x08, 0x00, 0x5C, 0x09, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0x04, 0x08, 0x15, 0x00, 0x48, 0x01, 0x08, 0x08, 0x00, 0x60, 0x08, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x02 }, +{ 0xDA, 0x00, 0x53, 0x30, 0x68, 0x07, 0x1E, 0x49, 0xC4, 0x7E, 0x03, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }, +{ 0x1C, 0x00, 0x07, 0xBC, 0x6C, 0x0C, 0x14, 0x0B, 0x6A, 0x7E, 0x0B, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x03 }, +{ 0x0A, 0x0E, 0x7F, 0x00, 0x7D, 0x13, 0x20, 0x28, 0x03, 0x7C, 0x06, 0, { 0,0,0,0,0,0,0,0 }, 0, { 0,0,0,0,0,0,0,0 }, 0x00 }  };  static const byte gm_percussion_lookup[128] = { @@ -616,7 +613,7 @@ private:  	void adlib_note_on(int chan, byte note, int mod);  	void adlib_note_on_ex(int chan, byte note, int mod);  	int adlib_get_reg_value_param(int chan, byte data); -	void adlib_setup_channel(int chan, AdLibInstrument * instr, byte vol_1, byte vol_2); +	void adlib_setup_channel(int chan, AdLibInstrument *instr, byte vol_1, byte vol_2);  	byte adlib_get_reg_value(byte reg) {  		return _adlib_reg_cache[reg];  	} @@ -627,16 +624,16 @@ private:  	AdLibVoice *allocate_voice(byte pri); -	void mc_off(AdLibVoice * voice); +	void mc_off(AdLibVoice *voice);  	static void link_mc(AdLibPart *part, AdLibVoice *voice); -	void mc_inc_stuff(AdLibVoice *voice, Struct10 * s10, Struct11 * s11); -	void mc_init_stuff(AdLibVoice *voice, Struct10 * s10, Struct11 * s11, byte flags, -						InstrumentExtra * ie); +	void mc_inc_stuff(AdLibVoice *voice, Struct10 *s10, Struct11 *s11); +	void mc_init_stuff(AdLibVoice *voice, Struct10 *s10, Struct11 *s11, byte flags, +						InstrumentExtra *ie); -	void struct10_init(Struct10 * s10, InstrumentExtra * ie); -	static byte struct10_ontimer(Struct10 * s10, Struct11 * s11); -	static void struct10_setup(Struct10 * s10); +	void struct10_init(Struct10 *s10, InstrumentExtra *ie); +	static byte struct10_ontimer(Struct10 *s10, Struct11 *s11); +	static void struct10_setup(Struct10 *s10);  	static int random_nr(int a);  	void mc_key_on(AdLibVoice *voice, AdLibInstrument *instr, byte note, byte velocity);  }; @@ -676,12 +673,14 @@ void AdLibPart::programChange(byte program) {  	if (program > 127)  		return; +/*  	uint i;  	uint count = 0;  	for (i = 0; i < ARRAYSIZE(map_gm_to_fm[0]); ++i)  		count += map_gm_to_fm[program][i];  	if (!count) -		warning("No AdLib instrument defined for GM program %d", (int) program); +		warning("No AdLib instrument defined for GM program %d", (int)program); +*/  	_program = program;  	memcpy(&_part_instr, &map_gm_to_fm[program], sizeof(AdLibInstrument));  } @@ -790,8 +789,7 @@ void AdLibPart::allNotesOff() {  void AdLibPart::sysEx_customInstrument(uint32 type, const byte *instr) {  	if (type == 'ADL ') { -		AdLibInstrument *i = &_part_instr; -		memcpy(i, instr, sizeof(AdLibInstrument)); +		memcpy(&_part_instr, instr, sizeof(AdLibInstrument));  	}  } @@ -840,7 +838,7 @@ void AdLibPercussionChannel::noteOn(byte note, byte velocity) {  		// Use the default GM to FM mapping as a fallback as a fallback  		byte key = gm_percussion_lookup[note];  		if (key != 0xFF) -			inst = (AdLibInstrument *)&gm_percussion_to_fm[key]; +			inst = &gm_percussion_to_fm[key];  	}  	if (!inst) { @@ -1482,8 +1480,8 @@ void MidiDriver_ADLIB::adlib_note_on_ex(int chan, byte note, int mod)  	adlib_playnote(chan, code);  } -void MidiDriver_ADLIB::mc_init_stuff(AdLibVoice *voice, Struct10 * s10, -									Struct11 * s11, byte flags, InstrumentExtra * ie) { +void MidiDriver_ADLIB::mc_init_stuff(AdLibVoice *voice, Struct10 *s10, +									Struct11 *s11, byte flags, InstrumentExtra *ie) {  	AdLibPart *part = voice->_part;  	s11->modify_val = 0;  	s11->flag0x40 = flags & 0x40; diff --git a/audio/softsynth/appleiigs.cpp b/audio/softsynth/appleiigs.cpp index 80159c79ce..6ee70d1202 100644 --- a/audio/softsynth/appleiigs.cpp +++ b/audio/softsynth/appleiigs.cpp @@ -18,9 +18,6 @@  * along with this program; if not, write to the Free Software  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  * -* $URL$ -* $Id$ -*  */  #include "audio/null.h" diff --git a/audio/softsynth/cms.cpp b/audio/softsynth/cms.cpp index fcc15f127e..67eacd1a41 100644 --- a/audio/softsynth/cms.cpp +++ b/audio/softsynth/cms.cpp @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #include "audio/softsynth/cms.h" diff --git a/audio/softsynth/cms.h b/audio/softsynth/cms.h index d5bb7f0a42..48064746a8 100644 --- a/audio/softsynth/cms.h +++ b/audio/softsynth/cms.h @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #ifndef SOUND_SOFTSYNTH_CMS_H diff --git a/audio/softsynth/eas.cpp b/audio/softsynth/eas.cpp index 7d17655d20..d829e3b39a 100644 --- a/audio/softsynth/eas.cpp +++ b/audio/softsynth/eas.cpp @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #include "common/scummsys.h" diff --git a/audio/softsynth/emumidi.h b/audio/softsynth/emumidi.h index 190b70c392..f3d7645f87 100644 --- a/audio/softsynth/emumidi.h +++ b/audio/softsynth/emumidi.h @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #ifndef SOUND_SOFTSYNTH_EMUMIDI_H diff --git a/audio/softsynth/fluidsynth.cpp b/audio/softsynth/fluidsynth.cpp index a4877a4ec1..2451336784 100644 --- a/audio/softsynth/fluidsynth.cpp +++ b/audio/softsynth/fluidsynth.cpp @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #include "common/scummsys.h" diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.cpp b/audio/softsynth/fmtowns_pc98/towns_audio.cpp index 7b6658ab3a..719bc981ee 100644 --- a/audio/softsynth/fmtowns_pc98/towns_audio.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_audio.cpp @@ -18,19 +18,19 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/softsynth/fmtowns_pc98/towns_audio.h" +#include "audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h" +  #include "common/endian.h"  #include "common/util.h" +#include "common/textconsole.h"  #include "backends/audiocd/audiocd.h"  class TownsAudio_PcmChannel { -friend class TownsAudioInterface; +friend class TownsAudioInterfaceIntern;  public:  	TownsAudio_PcmChannel();  	~TownsAudio_PcmChannel(); @@ -80,7 +80,7 @@ private:  };  class TownsAudio_WaveTable { -friend class TownsAudioInterface; +friend class TownsAudioInterfaceIntern;  public:  	TownsAudio_WaveTable();  	~TownsAudio_WaveTable(); @@ -101,14 +101,164 @@ private:  	int8 *data;  }; -TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) : TownsPC98_FmSynth(mixer, kTypeTowns), +class TownsAudioInterfaceIntern : public TownsPC98_FmSynth { +public: +	TownsAudioInterfaceIntern(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver); +	~TownsAudioInterfaceIntern(); + +	static TownsAudioInterfaceIntern *addNewRef(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver); +	static void releaseRef(); +	bool checkPluginDriver(TownsAudioInterfacePluginDriver *driver); + +	bool init(); + +	int callback(int command, ...); +	int processCommand(int command, va_list &args); + +	void setMusicVolume(int volume); +	void setSoundEffectVolume(int volume); +	// Defines the channels used as sound effect channels for the purpose of ScummVM GUI volume control. +	// The first 6 bits are the 6 fm channels. The next 8 bits are pcm channels. +	void setSoundEffectChanMask(int mask); + +private: +	void nextTickEx(int32 *buffer, uint32 bufferSize); + +	void timerCallbackA(); +	void timerCallbackB(); + +	typedef int (TownsAudioInterfaceIntern::*TownsAudioIntfCallback)(va_list &); +	const TownsAudioIntfCallback *_intfOpcodes; + +	int intf_reset(va_list &args); +	int intf_keyOn(va_list &args); +	int intf_keyOff(va_list &args); +	int intf_setPanPos(va_list &args); +	int intf_setInstrument(va_list &args); +	int intf_loadInstrument(va_list &args); +	int intf_setPitch(va_list &args); +	int intf_setLevel(va_list &args); +	int intf_chanOff(va_list &args); +	int intf_writeReg(va_list &args); +	int intf_writeRegBuffer(va_list &args); +	int intf_readRegBuffer(va_list &args); +	int intf_setTimerA(va_list &args); +	int intf_setTimerB(va_list &args); +	int intf_enableTimerA(va_list &args); +	int intf_enableTimerB(va_list &args); +	int intf_loadSamples(va_list &args); +	int intf_reserveEffectChannels(va_list &args); +	int intf_loadWaveTable(va_list &args); +	int intf_unloadWaveTable(va_list &args); +	int intf_pcmPlayEffect(va_list &args); +	int intf_pcmChanOff(va_list &args); +	int intf_pcmEffectPlaying(va_list &args); +	int intf_fmKeyOn(va_list &args); +	int intf_fmKeyOff(va_list &args); +	int intf_fmSetPanPos(va_list &args); +	int intf_fmSetInstrument(va_list &args); +	int intf_fmLoadInstrument(va_list &args); +	int intf_fmSetPitch(va_list &args); +	int intf_fmSetLevel(va_list &args); +	int intf_fmReset(va_list &args); +	int intf_setOutputVolume(va_list &args); +	int intf_resetOutputVolume(va_list &args); +	int intf_getOutputVolume(va_list &args); +	int intf_setOutputMute(va_list &args); +	int intf_cdaToggle(va_list &args); +	int intf_getOutputVolume2(va_list &args); +	int intf_getOutputMute(va_list &args); +	int intf_pcmUpdateEnvelopeGenerator(va_list &args); + +	int intf_notImpl(va_list &args); + +	void fmReset(); +	int fmKeyOn(int chan, int note, int velo); +	int fmKeyOff(int chan); +	int fmChanOff(int chan); +	int fmSetPanPos(int chan, int mode); +	int fmSetInstrument(int chan, int instrId); +	int fmLoadInstrument(int instrId, const uint8 *data); +	int fmSetPitch(int chan, int pitch); +	int fmSetLevel(int chan, int lvl); + +	void bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value); + +	uint8 _fmChanPlaying; +	uint8 _fmChanNote[6]; +	int16 _fmChanPitch[6]; + +	uint8 *_fmSaveReg[2]; +	uint8 *_fmInstruments; + +	void pcmReset(); +	int pcmKeyOn(int chan, int note, int velo); +	int pcmKeyOff(int chan); +	int pcmChanOff(int chan); +	int pcmSetPanPos(int chan, int mode); +	int pcmSetInstrument(int chan, int instrId); +	int pcmLoadInstrument(int instrId, const uint8 *data); +	int pcmSetPitch(int chan, int pitch); +	int pcmSetLevel(int chan, int lvl); +	void pcmUpdateEnvelopeGenerator(int chan); + +	TownsAudio_PcmChannel *_pcmChan; +	uint8 _pcmChanOut; +	uint8 _pcmChanReserved; +	uint8 _pcmChanKeyPressed; +	uint8 _pcmChanEffectPlaying; +	uint8 _pcmChanKeyPlaying; + +	uint8 _pcmChanNote[8]; +	uint8 _pcmChanVelo[8]; +	uint8 _pcmChanLevel[8]; + +	uint8 _numReservedChannels; +	uint8 *_pcmInstruments; + +	TownsAudio_WaveTable *_waveTables; +	uint8 _numWaveTables; +	uint32 _waveTablesTotalDataSize; + +	void pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_WaveTable *w); + +	void updateOutputVolume(); +	uint8 _outputVolumeFlags; +	uint8 _outputLevel[16]; +	uint8 _outputMute[16]; + +	const float _baserate; +	uint32 _timerBase; +	uint32 _tickLength; +	uint32 _timer; + +	uint16 _musicVolume; +	uint16 _sfxVolume; +	int _pcmSfxChanMask; + +	TownsAudioInterfacePluginDriver *_drv; +	bool _ready; + +	static TownsAudioInterfaceIntern *_refInstance; +	static int _refCount; + +	static const uint8 _chanFlags[]; +	static const uint16 _frequency[]; +	static const uint8 _carrier[]; +	static const uint8 _fmDefaultInstrument[]; +	static const uint16 _pcmPhase1[]; +	static const uint16 _pcmPhase2[]; +}; + +TownsAudioInterfaceIntern::TownsAudioInterfaceIntern(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) : TownsPC98_FmSynth(mixer, kTypeTowns),  	_fmInstruments(0), _pcmInstruments(0), _pcmChan(0), _waveTables(0), _waveTablesTotalDataSize(0),  	_baserate(55125.0f / (float)mixer->getOutputRate()), _tickLength(0), _timer(0), _drv(driver),  	_pcmSfxChanMask(0),	_musicVolume(Audio::Mixer::kMaxMixerVolume), _sfxVolume(Audio::Mixer::kMaxMixerVolume), -	_outputVolumeFlags(0), _outputMuteFlags(0), _pcmChanOut(0), _pcmChanReserved(0), _pcmChanKeyPressed(0), -	_pcmChanEffectPlaying(0), _pcmChanKeyPlaying(0), _ready(false) { +	_outputVolumeFlags(0), _pcmChanOut(0), _pcmChanReserved(0), _pcmChanKeyPressed(0), +	_pcmChanEffectPlaying(0), _pcmChanKeyPlaying(0), _fmChanPlaying(0),  +	_numReservedChannels(0), _numWaveTables(0), _ready(false) { -#define INTCB(x) &TownsAudioInterface::intf_##x +#define INTCB(x) &TownsAudioInterfaceIntern::intf_##x  	static const TownsAudioIntfCallback intfCb[] = {  		// 0  		INTCB(reset), @@ -197,14 +347,14 @@ TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfac  		INTCB(setOutputVolume),  		// 68  		INTCB(resetOutputVolume), -		INTCB(notImpl), -		INTCB(updateOutputVolume), +		INTCB(getOutputVolume), +		INTCB(setOutputMute),  		INTCB(notImpl),  		// 72  		INTCB(notImpl),  		INTCB(cdaToggle), -		INTCB(notImpl), -		INTCB(notImpl), +		INTCB(getOutputVolume2), +		INTCB(getOutputMute),  		// 76  		INTCB(notImpl),  		INTCB(notImpl), @@ -219,13 +369,19 @@ TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfac  	_intfOpcodes = intfCb;  	memset(_fmSaveReg, 0, sizeof(_fmSaveReg)); +	memset(_fmChanNote, 0, sizeof(_fmChanNote)); +	memset(_fmChanPitch, 0, sizeof(_fmChanPitch)); +	memset(_pcmChanNote, 0, sizeof(_pcmChanNote));	 +	memset(_pcmChanVelo, 0, sizeof(_pcmChanVelo)); +	memset(_pcmChanLevel, 0, sizeof(_pcmChanLevel));  	memset(_outputLevel, 0, sizeof(_outputLevel)); +	memset(_outputMute, 0, sizeof(_outputMute));  	_timerBase = (uint32)(_baserate * 1000000.0f);  	_tickLength = 2 * _timerBase;  } -TownsAudioInterface::~TownsAudioInterface() { +TownsAudioInterfaceIntern::~TownsAudioInterfaceIntern() {  	_ready = false;  	deinit(); @@ -237,7 +393,47 @@ TownsAudioInterface::~TownsAudioInterface() {  	delete[] _pcmChan;  } -bool TownsAudioInterface::init() { +TownsAudioInterfaceIntern *TownsAudioInterfaceIntern::addNewRef(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) { +	_refCount++; +	if (_refCount == 1 && _refInstance == 0) +		_refInstance = new TownsAudioInterfaceIntern(mixer, driver); +	else if (_refCount < 2 || _refInstance == 0) +		error("TownsAudioInterfaceIntern::addNewRef(): Internal reference management failure"); +	else if (!_refInstance->checkPluginDriver(driver)) +		error("TownsAudioInterfaceIntern::addNewRef(): Plugin driver conflict"); + +	return _refInstance; +} + +void TownsAudioInterfaceIntern::releaseRef() { +	if (!_refCount) +		return; + +	_refCount--; +	 +	if (!_refCount) { +		delete _refInstance; +		_refInstance = 0; +	} +} + +bool TownsAudioInterfaceIntern::checkPluginDriver(TownsAudioInterfacePluginDriver *driver) { +	if (_refCount <= 1) +		return true; + +	if (_drv) { +		if (driver && driver != _drv) +			return false; +	} else { +		lock(); +		_drv = driver; +		unlock(); +	} + +	return true; +} + +bool TownsAudioInterfaceIntern::init() {  	if (_ready)  		return true; @@ -261,41 +457,50 @@ bool TownsAudioInterface::init() {  	return true;  } -int TownsAudioInterface::callback(int command, ...) { +int TownsAudioInterfaceIntern::callback(int command, ...) {  	if (!_ready)  		return 1;  	va_list args;  	va_start(args, command); -	if (command > 81) { -		va_end(args); -		return 4; -	} +	int res = processCommand(command, args); + +	va_end(args); +	return res; +} + +int TownsAudioInterfaceIntern::processCommand(int command, va_list &args) { +	if (!_ready) +		return 1; +	if (command < 0 || command > 81) +		return 4; +	 +	lock();  	int res = (this->*_intfOpcodes[command])(args); +	unlock(); -	va_end(args);  	return res;  } -void TownsAudioInterface::setMusicVolume(int volume) { +void TownsAudioInterfaceIntern::setMusicVolume(int volume) {  	_musicVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume);  	setVolumeIntern(_musicVolume, _sfxVolume);  } -void TownsAudioInterface::setSoundEffectVolume(int volume) { +void TownsAudioInterfaceIntern::setSoundEffectVolume(int volume) {  	_sfxVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume);  	setVolumeIntern(_musicVolume, _sfxVolume);  } -void TownsAudioInterface::setSoundEffectChanMask(int mask) { +void TownsAudioInterfaceIntern::setSoundEffectChanMask(int mask) {  	_pcmSfxChanMask = mask >> 6;  	mask &= 0x3f;  	setVolumeChannelMasks(~mask, mask);  } -void TownsAudioInterface::nextTickEx(int32 *buffer, uint32 bufferSize) { +void TownsAudioInterfaceIntern::nextTickEx(int32 *buffer, uint32 bufferSize) {  	if (!_ready)  		return; @@ -346,14 +551,12 @@ void TownsAudioInterface::nextTickEx(int32 *buffer, uint32 bufferSize) {  	}  } -void TownsAudioInterface::timerCallbackA() { -	Common::StackLock lock(_mutex); +void TownsAudioInterfaceIntern::timerCallbackA() {  	if (_drv && _ready)  		_drv->timerCallback(0);  } -void TownsAudioInterface::timerCallbackB() { -	Common::StackLock lock(_mutex); +void TownsAudioInterfaceIntern::timerCallbackB() {  	if (_ready) {  		if (_drv)  			_drv->timerCallback(1); @@ -361,62 +564,62 @@ void TownsAudioInterface::timerCallbackB() {  	}  } -int TownsAudioInterface::intf_reset(va_list &args) { +int TownsAudioInterfaceIntern::intf_reset(va_list &args) {  	fmReset();  	pcmReset();  	callback(68);  	return 0;  } -int TownsAudioInterface::intf_keyOn(va_list &args) { +int TownsAudioInterfaceIntern::intf_keyOn(va_list &args) {  	int chan = va_arg(args, int);  	int note = va_arg(args, int);  	int velo = va_arg(args, int);  	return (chan & 0x40) ? pcmKeyOn(chan, note, velo) : fmKeyOn(chan, note, velo);  } -int TownsAudioInterface::intf_keyOff(va_list &args) { +int TownsAudioInterfaceIntern::intf_keyOff(va_list &args) {  	int chan = va_arg(args, int);  	return (chan & 0x40) ? pcmKeyOff(chan) : fmKeyOff(chan);  } -int TownsAudioInterface::intf_setPanPos(va_list &args) { +int TownsAudioInterfaceIntern::intf_setPanPos(va_list &args) {  	int chan = va_arg(args, int);  	int mode = va_arg(args, int);  	return (chan & 0x40) ? pcmSetPanPos(chan, mode) : fmSetPanPos(chan, mode);  } -int TownsAudioInterface::intf_setInstrument(va_list &args) { +int TownsAudioInterfaceIntern::intf_setInstrument(va_list &args) {  	int chan = va_arg(args, int);  	int instrId = va_arg(args, int);  	return (chan & 0x40) ? pcmSetInstrument(chan, instrId) : fmSetInstrument(chan, instrId);  } -int TownsAudioInterface::intf_loadInstrument(va_list &args) { +int TownsAudioInterfaceIntern::intf_loadInstrument(va_list &args) {  	int chanType = va_arg(args, int);  	int instrId = va_arg(args, int);  	uint8 *instrData = va_arg(args, uint8 *);  	return (chanType & 0x40) ? pcmLoadInstrument(instrId, instrData) : fmLoadInstrument(instrId, instrData);  } -int TownsAudioInterface::intf_setPitch(va_list &args) { +int TownsAudioInterfaceIntern::intf_setPitch(va_list &args) {  	int chan = va_arg(args, int);  	int16 pitch = (int16)(va_arg(args, int) & 0xffff);  	return (chan & 0x40) ? pcmSetPitch(chan, pitch) : fmSetPitch(chan, pitch);  } -int TownsAudioInterface::intf_setLevel(va_list &args) { +int TownsAudioInterfaceIntern::intf_setLevel(va_list &args) {  	int chan = va_arg(args, int);  	int lvl = va_arg(args, int);  	return (chan & 0x40) ? pcmSetLevel(chan, lvl) : fmSetLevel(chan, lvl);  } -int TownsAudioInterface::intf_chanOff(va_list &args) { +int TownsAudioInterfaceIntern::intf_chanOff(va_list &args) {  	int chan = va_arg(args, int);  	return (chan & 0x40) ? pcmChanOff(chan) : fmChanOff(chan);  } -int TownsAudioInterface::intf_writeReg(va_list &args) { +int TownsAudioInterfaceIntern::intf_writeReg(va_list &args) {  	int part = va_arg(args, int) ? 1 : 0;  	int reg = va_arg(args, int);  	int val = va_arg(args, int); @@ -427,7 +630,7 @@ int TownsAudioInterface::intf_writeReg(va_list &args) {  	return 0;  } -int TownsAudioInterface::intf_writeRegBuffer(va_list &args) { +int TownsAudioInterfaceIntern::intf_writeRegBuffer(va_list &args) {  	int part = va_arg(args, int) ? 1 : 0;  	int reg = va_arg(args, int);  	int val = va_arg(args, int); @@ -439,7 +642,7 @@ int TownsAudioInterface::intf_writeRegBuffer(va_list &args) {  	return 0;  } -int TownsAudioInterface::intf_readRegBuffer(va_list &args) { +int TownsAudioInterfaceIntern::intf_readRegBuffer(va_list &args) {  	int part = va_arg(args, int) ? 1 : 0;  	int reg = va_arg(args, int);  	uint8 *dst = va_arg(args, uint8 *); @@ -452,7 +655,7 @@ int TownsAudioInterface::intf_readRegBuffer(va_list &args) {  	return 0;  } -int TownsAudioInterface::intf_setTimerA(va_list &args) { +int TownsAudioInterfaceIntern::intf_setTimerA(va_list &args) {  	int enable = va_arg(args, int);  	int tempo = va_arg(args, int); @@ -467,7 +670,7 @@ int TownsAudioInterface::intf_setTimerA(va_list &args) {  	return 0;  } -int TownsAudioInterface::intf_setTimerB(va_list &args) { +int TownsAudioInterfaceIntern::intf_setTimerB(va_list &args) {  	int enable = va_arg(args, int);  	int tempo = va_arg(args, int); @@ -481,17 +684,17 @@ int TownsAudioInterface::intf_setTimerB(va_list &args) {  	return 0;  } -int TownsAudioInterface::intf_enableTimerA(va_list &args) { +int TownsAudioInterfaceIntern::intf_enableTimerA(va_list &args) {  	bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x15);  	return 0;  } -int TownsAudioInterface::intf_enableTimerB(va_list &args) { +int TownsAudioInterfaceIntern::intf_enableTimerB(va_list &args) {  	bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x2a);  	return 0;  } -int TownsAudioInterface::intf_loadSamples(va_list &args) { +int TownsAudioInterfaceIntern::intf_loadSamples(va_list &args) {  	uint32 dest = va_arg(args, uint32);  	int size = va_arg(args, int);  	uint8 *src = va_arg(args, uint8*); @@ -514,7 +717,7 @@ int TownsAudioInterface::intf_loadSamples(va_list &args) {  	return 0;  } -int TownsAudioInterface::intf_reserveEffectChannels(va_list &args) { +int TownsAudioInterfaceIntern::intf_reserveEffectChannels(va_list &args) {  	int numChan = va_arg(args, int);  	if (numChan > 8)  		return 3; @@ -546,7 +749,7 @@ int TownsAudioInterface::intf_reserveEffectChannels(va_list &args) {  	return 0;  } -int TownsAudioInterface::intf_loadWaveTable(va_list &args) { +int TownsAudioInterfaceIntern::intf_loadWaveTable(va_list &args) {  	uint8 *data = va_arg(args, uint8 *);  	if (_numWaveTables > 127)  		return 3; @@ -573,7 +776,7 @@ int TownsAudioInterface::intf_loadWaveTable(va_list &args) {  	return 0;  } -int TownsAudioInterface::intf_unloadWaveTable(va_list &args) { +int TownsAudioInterfaceIntern::intf_unloadWaveTable(va_list &args) {  	int id = va_arg(args, int);  	if (id == -1) { @@ -600,7 +803,7 @@ int TownsAudioInterface::intf_unloadWaveTable(va_list &args) {  	return 0;  } -int TownsAudioInterface::intf_pcmPlayEffect(va_list &args) { +int TownsAudioInterfaceIntern::intf_pcmPlayEffect(va_list &args) {  	int chan = va_arg(args, int);  	int note = va_arg(args, int);  	int velo = va_arg(args, int); @@ -650,13 +853,13 @@ int TownsAudioInterface::intf_pcmPlayEffect(va_list &args) {  	return 0;  } -int TownsAudioInterface::intf_pcmChanOff(va_list &args) { +int TownsAudioInterfaceIntern::intf_pcmChanOff(va_list &args) {  	int chan = va_arg(args, int);  	pcmChanOff(chan);  	return 0;  } -int TownsAudioInterface::intf_pcmEffectPlaying(va_list &args) { +int TownsAudioInterfaceIntern::intf_pcmEffectPlaying(va_list &args) {  	int chan = va_arg(args, int);  	if (chan < 0x40 || chan > 0x47)  		return 1; @@ -664,54 +867,54 @@ int TownsAudioInterface::intf_pcmEffectPlaying(va_list &args) {  	return (_pcmChanEffectPlaying & _chanFlags[chan]) ? 1 : 0;  } -int TownsAudioInterface::intf_fmKeyOn(va_list &args) { +int TownsAudioInterfaceIntern::intf_fmKeyOn(va_list &args) {  	int chan = va_arg(args, int);  	int note = va_arg(args, int);  	int velo = va_arg(args, int);  	return fmKeyOn(chan, note, velo);  } -int TownsAudioInterface::intf_fmKeyOff(va_list &args) { +int TownsAudioInterfaceIntern::intf_fmKeyOff(va_list &args) {  	int chan = va_arg(args, int);  	return fmKeyOff(chan);  } -int TownsAudioInterface::intf_fmSetPanPos(va_list &args) { +int TownsAudioInterfaceIntern::intf_fmSetPanPos(va_list &args) {  	int chan = va_arg(args, int);  	int mode = va_arg(args, int);  	return fmSetPanPos(chan, mode);  } -int TownsAudioInterface::intf_fmSetInstrument(va_list &args) { +int TownsAudioInterfaceIntern::intf_fmSetInstrument(va_list &args) {  	int chan = va_arg(args, int);  	int instrId = va_arg(args, int);  	return fmSetInstrument(chan, instrId);  } -int TownsAudioInterface::intf_fmLoadInstrument(va_list &args) { +int TownsAudioInterfaceIntern::intf_fmLoadInstrument(va_list &args) {  	int instrId = va_arg(args, int);  	uint8 *instrData = va_arg(args, uint8 *);  	return fmLoadInstrument(instrId, instrData);  } -int TownsAudioInterface::intf_fmSetPitch(va_list &args) { +int TownsAudioInterfaceIntern::intf_fmSetPitch(va_list &args) {  	int chan = va_arg(args, int);  	uint16 freq = va_arg(args, int) & 0xffff;  	return fmSetPitch(chan, freq);  } -int TownsAudioInterface::intf_fmSetLevel(va_list &args) { +int TownsAudioInterfaceIntern::intf_fmSetLevel(va_list &args) {  	int chan = va_arg(args, int);  	int lvl = va_arg(args, int);  	return fmSetLevel(chan, lvl);  } -int TownsAudioInterface::intf_fmReset(va_list &args) { +int TownsAudioInterfaceIntern::intf_fmReset(va_list &args) {  	fmReset();  	return 0;  } -int TownsAudioInterface::intf_setOutputVolume(va_list &args) { +int TownsAudioInterfaceIntern::intf_setOutputVolume(va_list &args) {  	int chanType = va_arg(args, int);  	int left = va_arg(args, int);  	int right = va_arg(args, int); @@ -727,18 +930,20 @@ int TownsAudioInterface::intf_setOutputVolume(va_list &args) {  	left = (left & 0x7e) >> 1;  	right = (right & 0x7e) >> 1; -	if (chan) +	if (chan == 12)  		_outputVolumeFlags |= flags[chanType];  	else  		_outputVolumeFlags &= ~flags[chanType];  	if (chanType > 1) {  		_outputLevel[chan + chanType] = left; +		_outputMute[chan + chanType] = 0;  	} else {  		if (chanType == 0)  			chan -= 8;  		_outputLevel[chan] = left;  		_outputLevel[chan + 1] = right; +		_outputMute[chan] = _outputMute[chan + 1] = 0;  	}  	updateOutputVolume(); @@ -746,38 +951,87 @@ int TownsAudioInterface::intf_setOutputVolume(va_list &args) {  	return 0;  } -int TownsAudioInterface::intf_resetOutputVolume(va_list &args) { +int TownsAudioInterfaceIntern::intf_resetOutputVolume(va_list &args) {  	memset(_outputLevel, 0, sizeof(_outputLevel)); -	_outputMuteFlags = 0;  	_outputVolumeFlags = 0;  	updateOutputVolume();  	return 0;  } -int TownsAudioInterface::intf_updateOutputVolume(va_list &args) { +int TownsAudioInterfaceIntern::intf_getOutputVolume(va_list &args) { +	int chanType = va_arg(args, int); +	int *left = va_arg(args, int*); +	int *right = va_arg(args, int*); + +	uint8 chan = (chanType & 0x40) ? 8 : 12; +	chanType &= 3; + +	if (chanType > 1) { +		*left = _outputLevel[chan + chanType] & 0x3f; +	} else { +		if (chanType == 0) +			chan -= 8; +		*left = _outputLevel[chan] & 0x3f; +		*right = _outputLevel[chan + 1] & 0x3f; +	} + +	return 0; +} + +int TownsAudioInterfaceIntern::intf_setOutputMute(va_list &args) {  	int flags = va_arg(args, int); -	_outputMuteFlags = flags & 3; +	_outputVolumeFlags = flags; +	uint8 mute = flags & 3; +	uint8 f = flags & 0xff; + +	memset(_outputMute, 1, 8); +	if (mute & 2) +		memset(&_outputMute[12], 1, 4); +	if (mute & 1) +		memset(&_outputMute[8], 1, 4);	 + +	_outputMute[(f < 0x80) ? 11 : 15] = 0; +	f += f; +	_outputMute[(f < 0x80) ? 10 : 14] = 0; +	f += f; +	_outputMute[(f < 0x80) ? 8 : 12] = 0; +	f += f; +	_outputMute[(f < 0x80) ? 9 : 13] = 0; +	f += f; +	_outputMute[(f < 0x80) ? 0 : 4] = 0; +	f += f; +	_outputMute[(f < 0x80) ? 1 : 5] = 0; +	f += f;	 +	  	updateOutputVolume();  	return 0;  } -int TownsAudioInterface::intf_cdaToggle(va_list &args) { +int TownsAudioInterfaceIntern::intf_cdaToggle(va_list &args) {  	//int mode = va_arg(args, int);  	//_unkMask = mode ? 0x7f : 0x3f;  	return 0;  } -int TownsAudioInterface::intf_pcmUpdateEnvelopeGenerator(va_list &args) { +int TownsAudioInterfaceIntern::intf_getOutputVolume2(va_list &args) { +	return 0; +} + +int TownsAudioInterfaceIntern::intf_getOutputMute (va_list &args) { +	return 0; +} + +int TownsAudioInterfaceIntern::intf_pcmUpdateEnvelopeGenerator(va_list &args) {  	for (int i = 0; i < 8; i++)  		pcmUpdateEnvelopeGenerator(i);  	return 0;  } -int TownsAudioInterface::intf_notImpl(va_list &args) { +int TownsAudioInterfaceIntern::intf_notImpl(va_list &args) {  	return 4;  } -void TownsAudioInterface::fmReset() { +void TownsAudioInterfaceIntern::fmReset() {  	TownsPC98_FmSynth::reset();  	_fmChanPlaying = 0; @@ -805,7 +1059,7 @@ void TownsAudioInterface::fmReset() {  	}  } -int TownsAudioInterface::fmKeyOn(int chan, int note, int velo) { +int TownsAudioInterfaceIntern::fmKeyOn(int chan, int note, int velo) {  	if (chan > 5)  		return 1;  	if (note < 12 || note > 107 || (velo & 0x80)) @@ -885,7 +1139,7 @@ int TownsAudioInterface::fmKeyOn(int chan, int note, int velo) {  	return 0;  } -int TownsAudioInterface::fmKeyOff(int chan) { +int TownsAudioInterfaceIntern::fmKeyOff(int chan) {  	if (chan > 5)  		return 1;  	_fmChanPlaying &= ~_chanFlags[chan]; @@ -895,7 +1149,7 @@ int TownsAudioInterface::fmKeyOff(int chan) {  	return 0;  } -int TownsAudioInterface::fmChanOff(int chan) { +int TownsAudioInterfaceIntern::fmChanOff(int chan) {  	if (chan > 5)  		return 1;  	_fmChanPlaying &= ~_chanFlags[chan]; @@ -913,7 +1167,7 @@ int TownsAudioInterface::fmChanOff(int chan) {  	return 0;  } -int TownsAudioInterface::fmSetPanPos(int chan, int value) { +int TownsAudioInterfaceIntern::fmSetPanPos(int chan, int value) {  	if (chan > 5)  		return 1; @@ -932,7 +1186,7 @@ int TownsAudioInterface::fmSetPanPos(int chan, int value) {  	return 0;  } -int TownsAudioInterface::fmSetInstrument(int chan, int instrId) { +int TownsAudioInterfaceIntern::fmSetInstrument(int chan, int instrId) {  	if (chan > 5)  		return 1;  	if (instrId > 127) @@ -976,7 +1230,7 @@ int TownsAudioInterface::fmSetInstrument(int chan, int instrId) {  	return 0;  } -int TownsAudioInterface::fmLoadInstrument(int instrId, const uint8 *data) { +int TownsAudioInterfaceIntern::fmLoadInstrument(int instrId, const uint8 *data) {  	if (instrId > 127)  		return 3;  	assert(data); @@ -984,7 +1238,7 @@ int TownsAudioInterface::fmLoadInstrument(int instrId, const uint8 *data) {  	return 0;  } -int TownsAudioInterface::fmSetPitch(int chan, int pitch) { +int TownsAudioInterfaceIntern::fmSetPitch(int chan, int pitch) {  	if (chan > 5)  		return 1; @@ -1071,7 +1325,7 @@ int TownsAudioInterface::fmSetPitch(int chan, int pitch) {  	return 0;  } -int TownsAudioInterface::fmSetLevel(int chan, int lvl) { +int TownsAudioInterfaceIntern::fmSetLevel(int chan, int lvl) {  	if (chan > 5)  		return 1;  	if (lvl > 127) @@ -1094,12 +1348,12 @@ int TownsAudioInterface::fmSetLevel(int chan, int lvl) {  	return 0;  } -void TownsAudioInterface::bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value) { +void TownsAudioInterfaceIntern::bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value) {  	_fmSaveReg[part][regAddress] = value;  	writeReg(part, regAddress, value);  } -void TownsAudioInterface::pcmReset() { +void TownsAudioInterfaceIntern::pcmReset() {  	_pcmChanOut = 0;  	_pcmChanReserved = _pcmChanKeyPressed = _pcmChanEffectPlaying = _pcmChanKeyPlaying = 0;  	_numReservedChannels = 0; @@ -1127,7 +1381,7 @@ void TownsAudioInterface::pcmReset() {  	}  } -int TownsAudioInterface::pcmKeyOn(int chan, int note, int velo) { +int TownsAudioInterfaceIntern::pcmKeyOn(int chan, int note, int velo) {  	if (chan < 0x40 || chan > 0x47)  		return 1; @@ -1198,7 +1452,7 @@ int TownsAudioInterface::pcmKeyOn(int chan, int note, int velo) {  	return 0;  } -int TownsAudioInterface::pcmKeyOff(int chan) { +int TownsAudioInterfaceIntern::pcmKeyOff(int chan) {  	if (chan < 0x40 || chan > 0x47)  		return 1; @@ -1208,7 +1462,7 @@ int TownsAudioInterface::pcmKeyOff(int chan) {  	return 0;  } -int TownsAudioInterface::pcmChanOff(int chan) { +int TownsAudioInterfaceIntern::pcmChanOff(int chan) {  	if (chan < 0x40 || chan > 0x47)  		return 1; @@ -1222,7 +1476,7 @@ int TownsAudioInterface::pcmChanOff(int chan) {  	return 0;  } -int TownsAudioInterface::pcmSetPanPos(int chan, int mode) { +int TownsAudioInterfaceIntern::pcmSetPanPos(int chan, int mode) {  	if (chan > 0x47)  		return 1;  	if (mode & 0x80) @@ -1245,7 +1499,7 @@ int TownsAudioInterface::pcmSetPanPos(int chan, int mode) {  	return 0;  } -int TownsAudioInterface::pcmSetInstrument(int chan, int instrId) { +int TownsAudioInterfaceIntern::pcmSetInstrument(int chan, int instrId) {  	if (chan > 0x47)  		return 1;  	if (instrId > 31) @@ -1255,7 +1509,7 @@ int TownsAudioInterface::pcmSetInstrument(int chan, int instrId) {  	return 0;  } -int TownsAudioInterface::pcmLoadInstrument(int instrId, const uint8 *data) { +int TownsAudioInterfaceIntern::pcmLoadInstrument(int instrId, const uint8 *data) {  	if (instrId > 31)  		return 3;  	assert(data); @@ -1263,7 +1517,7 @@ int TownsAudioInterface::pcmLoadInstrument(int instrId, const uint8 *data) {  	return 0;  } -int TownsAudioInterface::pcmSetPitch(int chan, int pitch) { +int TownsAudioInterfaceIntern::pcmSetPitch(int chan, int pitch) {  	if (chan > 0x47)  		return 1; @@ -1293,7 +1547,7 @@ int TownsAudioInterface::pcmSetPitch(int chan, int pitch) {  	return 0;  } -int TownsAudioInterface::pcmSetLevel(int chan, int lvl) { +int TownsAudioInterfaceIntern::pcmSetLevel(int chan, int lvl) {  	if (chan > 0x47)  		return 1; @@ -1322,7 +1576,7 @@ int TownsAudioInterface::pcmSetLevel(int chan, int lvl) {  	return 0;  } -void TownsAudioInterface::pcmUpdateEnvelopeGenerator(int chan) { +void TownsAudioInterfaceIntern::pcmUpdateEnvelopeGenerator(int chan) {  	TownsAudio_PcmChannel *p = &_pcmChan[chan];  	if (!p->envCurrentLevel) {  		_pcmChanKeyPlaying &= ~_chanFlags[chan]; @@ -1364,7 +1618,7 @@ void TownsAudioInterface::pcmUpdateEnvelopeGenerator(int chan) {  	p->velo = (p->envCurrentLevel >> 8) << 1;  } -void TownsAudioInterface::pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_WaveTable *w) { +void TownsAudioInterfaceIntern::pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_WaveTable *w) {  	int8 diff = p->note - w->baseNote;  	uint16 r = w->rate + w->rateOffs;  	uint16 bl = 0; @@ -1393,45 +1647,49 @@ void TownsAudioInterface::pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_  	p->step = (s * p->stepPitch) >> 14;  } -void TownsAudioInterface::updateOutputVolume() { +void TownsAudioInterfaceIntern::updateOutputVolume() {  	// FM Towns seems to support volumes of 0 - 63 for each channel.  	// We recalculate sane values for our 0 to 255 volume range and  	// balance values for our -128 to 127 volume range  	// CD-AUDIO -	uint32 maxVol = MAX(_outputLevel[12], _outputLevel[13]); +	uint32 maxVol = MAX(_outputLevel[12] * (_outputMute[12] ^ 1), _outputLevel[13] * (_outputMute[13] ^ 1));  	int volume = (int)(((float)(maxVol * 255) / 63.0f)); -	int balance = maxVol ? (int)( ( ((int)_outputLevel[13] - _outputLevel[12]) * 127) / (float)maxVol) : 0; +	int balance = maxVol ? (int)( ( ((int)_outputLevel[13] * (_outputMute[13] ^ 1) - _outputLevel[12] * (_outputMute[12] ^ 1)) * 127) / (float)maxVol) : 0;  	g_system->getAudioCDManager()->setVolume(volume);  	g_system->getAudioCDManager()->setBalance(balance);  } -const uint8 TownsAudioInterface::_chanFlags[] = { +TownsAudioInterfaceIntern *TownsAudioInterfaceIntern::_refInstance = 0; + +int TownsAudioInterfaceIntern::_refCount = 0; + +const uint8 TownsAudioInterfaceIntern::_chanFlags[] = {  	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80  }; -const uint16 TownsAudioInterface::_frequency[] = { +const uint16 TownsAudioInterfaceIntern::_frequency[] = {  	0x028C, 0x02B4, 0x02DC, 0x030A, 0x0338, 0x0368, 0x039C, 0x03D4, 0x040E, 0x044A, 0x048C, 0x04D0  }; -const uint8 TownsAudioInterface::_carrier[] = { +const uint8 TownsAudioInterfaceIntern::_carrier[] = {  	0x10, 0x10, 0x10, 0x10, 0x30, 0x70, 0x70, 0xF0  }; -const uint8 TownsAudioInterface::_fmDefaultInstrument[] = { +const uint8 TownsAudioInterfaceIntern::_fmDefaultInstrument[] = {  	0x45, 0x4C, 0x45, 0x50, 0x49, 0x41, 0x4E, 0x4F, 0x01, 0x0A, 0x02, 0x01,  	0x1E, 0x32, 0x05, 0x00, 0x9C, 0xDC, 0x9C, 0xDC, 0x07, 0x03, 0x14, 0x08,  	0x00, 0x03, 0x05, 0x05, 0x55, 0x45, 0x27, 0xA7, 0x04, 0xC0, 0x00, 0x00,  	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  }; -const uint16 TownsAudioInterface::_pcmPhase1[] =  { +const uint16 TownsAudioInterfaceIntern::_pcmPhase1[] =  {  	0x879B, 0x0F37, 0x1F58, 0x306E, 0x4288, 0x55B6, 0x6A08, 0x7F8F, 0x965E, 0xAE88, 0xC882, 0xE341  }; -const uint16 TownsAudioInterface::_pcmPhase2[] =  { +const uint16 TownsAudioInterfaceIntern::_pcmPhase2[] =  {  	0xFEFE, 0xF1A0, 0xE411, 0xD744, 0xCB2F, 0xBFC7, 0xB504, 0xAAE2, 0xA144, 0x9827, 0x8FAC  }; @@ -1582,3 +1840,37 @@ void TownsAudio_WaveTable::clear() {  	data = 0;  } +TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver) { +	_intf = TownsAudioInterfaceIntern::addNewRef(mixer, driver); +} + +TownsAudioInterface::~TownsAudioInterface() { +	TownsAudioInterfaceIntern::releaseRef(); +	_intf = 0; +} + +bool TownsAudioInterface::init() { +	return _intf->init(); +} + +int TownsAudioInterface::callback(int command, ...) { +	va_list args; +	va_start(args, command); + +	int res = _intf->processCommand(command, args); + +	va_end(args); +	return res; +} + +void TownsAudioInterface::setMusicVolume(int volume) { +	_intf->setMusicVolume(volume); +} + +void TownsAudioInterface::setSoundEffectVolume(int volume) { +	_intf->setSoundEffectVolume(volume); +} + +void TownsAudioInterface::setSoundEffectChanMask(int mask) { +	_intf->setSoundEffectChanMask(mask); +} diff --git a/audio/softsynth/fmtowns_pc98/towns_audio.h b/audio/softsynth/fmtowns_pc98/towns_audio.h index 2819ab2d57..2c58d46d06 100644 --- a/audio/softsynth/fmtowns_pc98/towns_audio.h +++ b/audio/softsynth/fmtowns_pc98/towns_audio.h @@ -18,15 +18,14 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef TOWNS_AUDIO_H  #define TOWNS_AUDIO_H -#include "audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h" +#include "audio/mixer.h" + +class TownsAudioInterfaceIntern;  class TownsAudioInterfacePluginDriver {  public: @@ -34,10 +33,7 @@ public:  	virtual void timerCallback(int timerId) = 0;  }; -class TownsAudio_PcmChannel; -class TownsAudio_WaveTable; - -class TownsAudioInterface : public TownsPC98_FmSynth { +class TownsAudioInterface {  public:  	TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver);  	~TownsAudioInterface(); @@ -53,126 +49,7 @@ public:  	void setSoundEffectChanMask(int mask);  private: -	void nextTickEx(int32 *buffer, uint32 bufferSize); - -	void timerCallbackA(); -	void timerCallbackB(); - -	typedef int (TownsAudioInterface::*TownsAudioIntfCallback)(va_list &); -	const TownsAudioIntfCallback *_intfOpcodes; - -	int intf_reset(va_list &args); -	int intf_keyOn(va_list &args); -	int intf_keyOff(va_list &args); -	int intf_setPanPos(va_list &args); -	int intf_setInstrument(va_list &args); -	int intf_loadInstrument(va_list &args); -	int intf_setPitch(va_list &args); -	int intf_setLevel(va_list &args); -	int intf_chanOff(va_list &args); -	int intf_writeReg(va_list &args); -	int intf_writeRegBuffer(va_list &args); -	int intf_readRegBuffer(va_list &args); -	int intf_setTimerA(va_list &args); -	int intf_setTimerB(va_list &args); -	int intf_enableTimerA(va_list &args); -	int intf_enableTimerB(va_list &args); -	int intf_loadSamples(va_list &args); -	int intf_reserveEffectChannels(va_list &args); -	int intf_loadWaveTable(va_list &args); -	int intf_unloadWaveTable(va_list &args); -	int intf_pcmPlayEffect(va_list &args); -	int intf_pcmChanOff(va_list &args); -	int intf_pcmEffectPlaying(va_list &args); -	int intf_fmKeyOn(va_list &args); -	int intf_fmKeyOff(va_list &args); -	int intf_fmSetPanPos(va_list &args); -	int intf_fmSetInstrument(va_list &args); -	int intf_fmLoadInstrument(va_list &args); -	int intf_fmSetPitch(va_list &args); -	int intf_fmSetLevel(va_list &args); -	int intf_fmReset(va_list &args); -	int intf_setOutputVolume(va_list &args); -	int intf_resetOutputVolume(va_list &args); -	int intf_updateOutputVolume(va_list &args); -	int intf_cdaToggle(va_list &args); -	int intf_pcmUpdateEnvelopeGenerator(va_list &args); - -	int intf_notImpl(va_list &args); - -	void fmReset(); -	int fmKeyOn(int chan, int note, int velo); -	int fmKeyOff(int chan); -	int fmChanOff(int chan); -	int fmSetPanPos(int chan, int mode); -	int fmSetInstrument(int chan, int instrId); -	int fmLoadInstrument(int instrId, const uint8 *data); -	int fmSetPitch(int chan, int pitch); -	int fmSetLevel(int chan, int lvl); - -	void bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value); - -	uint8 _fmChanPlaying; -	uint8 _fmChanNote[6]; -	int16 _fmChanPitch[6]; - -	uint8 *_fmSaveReg[2]; -	uint8 *_fmInstruments; - -	void pcmReset(); -	int pcmKeyOn(int chan, int note, int velo); -	int pcmKeyOff(int chan); -	int pcmChanOff(int chan); -	int pcmSetPanPos(int chan, int mode); -	int pcmSetInstrument(int chan, int instrId); -	int pcmLoadInstrument(int instrId, const uint8 *data); -	int pcmSetPitch(int chan, int pitch); -	int pcmSetLevel(int chan, int lvl); -	void pcmUpdateEnvelopeGenerator(int chan); - -	TownsAudio_PcmChannel *_pcmChan; -	uint8 _pcmChanOut; -	uint8 _pcmChanReserved; -	uint8 _pcmChanKeyPressed; -	uint8 _pcmChanEffectPlaying; -	uint8 _pcmChanKeyPlaying; - -	uint8 _pcmChanNote[8]; -	uint8 _pcmChanVelo[8]; -	uint8 _pcmChanLevel[8]; - -	uint8 _numReservedChannels; -	uint8 *_pcmInstruments; - -	TownsAudio_WaveTable *_waveTables; -	uint8 _numWaveTables; -	uint32 _waveTablesTotalDataSize; - -	void pcmCalcPhaseStep(TownsAudio_PcmChannel *p, TownsAudio_WaveTable *w); - -	void updateOutputVolume(); -	uint8 _outputVolumeFlags; -	uint8 _outputLevel[16]; -	uint8 _outputMuteFlags; - -	const float _baserate; -	uint32 _timerBase; -	uint32 _tickLength; -	uint32 _timer; - -	uint16 _musicVolume; -	uint16 _sfxVolume; -	int _pcmSfxChanMask; - -	TownsAudioInterfacePluginDriver *_drv; -	bool _ready; - -	static const uint8 _chanFlags[]; -	static const uint16 _frequency[]; -	static const uint8 _carrier[]; -	static const uint8 _fmDefaultInstrument[]; -	static const uint16 _pcmPhase1[]; -	static const uint16 _pcmPhase2[]; +	TownsAudioInterfaceIntern *_intf;  };  #endif diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp index cd3a348b85..bc2c88b236 100644 --- a/audio/softsynth/fmtowns_pc98/towns_euphony.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_euphony.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/softsynth/fmtowns_pc98/towns_euphony.h" @@ -31,7 +28,8 @@  TownsEuphonyDriver::TownsEuphonyDriver(Audio::Mixer *mixer) : _activeChannels(0), _sustainChannels(0),  	_assignedChannels(0), _paraCount(0), _command(0), _tEnable(0), _tMode(0), _tOrdr(0), _tLevel(0),  	_tTranspose(0), _musicPos(0), _musicStart(0), _playing(false), _eventBuffer(0), _bufferedEventsCount(0), -	_tempoControlMode(0) { +	_tempoControlMode(0), _timerSetting(0), _tempoDiff(0), _timeStampBase(0), _elapsedEvents(0), _loop(false), +	_endOfTrack(false), _suspendParsing(false), _musicTrackSize(0) {  	_para[0] = _para[1] = 0;  	_intf = new TownsAudioInterface(mixer, this);  	resetTempo(); @@ -84,7 +82,7 @@ void TownsEuphonyDriver::reset() {  	_intf->callback(0);  	_intf->callback(74); -	_intf->callback(70); +	_intf->callback(70, 0);  	_intf->callback(75, 3);  	setTimerA(true, 1); @@ -223,21 +221,21 @@ void TownsEuphonyDriver::setOutputVolume(int mode, int volLeft, int volRight) {  	_intf->callback(67, mode, volLeft, volRight);  } -int TownsEuphonyDriver::chanEnable(int tableEntry, int val) { +int TownsEuphonyDriver::configChan_enable(int tableEntry, int val) {  	if (tableEntry > 31)  		return 3;  	_tEnable[tableEntry] = val;  	return 0;  } -int TownsEuphonyDriver::chanMode(int tableEntry, int val) { +int TownsEuphonyDriver::configChan_setMode(int tableEntry, int val) {  	if (tableEntry > 31)  		return 3;  	_tMode[tableEntry] = val;  	return 0;  } -int TownsEuphonyDriver::chanOrdr(int tableEntry, int val) { +int TownsEuphonyDriver::configChan_remap(int tableEntry, int val) {  	if (tableEntry > 31)  		return 3;  	if (val < 16) @@ -245,7 +243,7 @@ int TownsEuphonyDriver::chanOrdr(int tableEntry, int val) {  	return 0;  } -int TownsEuphonyDriver::chanVolumeShift(int tableEntry, int val) { +int TownsEuphonyDriver::configChan_adjustVolume(int tableEntry, int val) {  	if (tableEntry > 31)  		return 3;  	if (val <= 40) @@ -253,7 +251,7 @@ int TownsEuphonyDriver::chanVolumeShift(int tableEntry, int val) {  	return 0;  } -int TownsEuphonyDriver::chanNoteShift(int tableEntry, int val) { +int TownsEuphonyDriver::configChan_setTranspose(int tableEntry, int val) {  	if (tableEntry > 31)  		return 3;  	if (val <= 40) @@ -675,8 +673,8 @@ bool TownsEuphonyDriver::evtSetupNote() {  	uint8 velo = _musicPos[5];  	sendEvent(mode, evt); -	sendEvent(mode, applyNoteShift(note)); -	sendEvent(mode, applyVolumeShift(velo)); +	sendEvent(mode, applyTranspose(note)); +	sendEvent(mode, applyVolumeAdjust(velo));  	jumpNextLoop();  	if (_musicPos[0] == 0xfe || _musicPos[0] == 0xfd) @@ -715,7 +713,7 @@ bool TownsEuphonyDriver::evtPolyphonicAftertouch() {  	uint8 mode = _tMode[_musicPos[1]];  	sendEvent(mode, evt); -	sendEvent(mode, applyNoteShift(_musicPos[4])); +	sendEvent(mode, applyTranspose(_musicPos[4]));  	sendEvent(mode, _musicPos[5]);  	return false; @@ -783,7 +781,7 @@ bool TownsEuphonyDriver::evtModeOrdrChange() {  	return false;  } -uint8 TownsEuphonyDriver::applyNoteShift(uint8 in) { +uint8 TownsEuphonyDriver::applyTranspose(uint8 in) {  	int out = _tTranspose[_musicPos[1]];  	if (!out)  		return in; @@ -798,7 +796,7 @@ uint8 TownsEuphonyDriver::applyNoteShift(uint8 in) {  	return out & 0xff;  } -uint8 TownsEuphonyDriver::applyVolumeShift(uint8 in) { +uint8 TownsEuphonyDriver::applyVolumeAdjust(uint8 in) {  	int out = _tLevel[_musicPos[1]];  	out += (in & 0x7f);  	out = CLIP(out, 1, 127); diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.h b/audio/softsynth/fmtowns_pc98/towns_euphony.h index dc40373913..6b30bfb7f5 100644 --- a/audio/softsynth/fmtowns_pc98/towns_euphony.h +++ b/audio/softsynth/fmtowns_pc98/towns_euphony.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef TOWNS_EUP_H @@ -58,11 +55,11 @@ public:  	void setOutputVolume(int chanType, int volLeft, int volRight); -	int chanEnable(int tableEntry, int val); -	int chanMode(int tableEntry, int val); -	int chanOrdr(int tableEntry, int val); -	int chanVolumeShift(int tableEntry, int val); -	int chanNoteShift(int tableEntry, int val); +	int configChan_enable(int tableEntry, int val); +	int configChan_setMode(int tableEntry, int val); +	int configChan_remap(int tableEntry, int val); +	int configChan_adjustVolume(int tableEntry, int val); +	int configChan_setTranspose(int tableEntry, int val);  	int assignChannel(int chan, int tableEntry); @@ -114,8 +111,8 @@ private:  		return false;  	} -	uint8 applyNoteShift(uint8 in); -	uint8 applyVolumeShift(uint8 in); +	uint8 applyTranspose(uint8 in); +	uint8 applyVolumeAdjust(uint8 in);  	void sendNoteOff();  	void sendNoteOn(); diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.cpp b/audio/softsynth/fmtowns_pc98/towns_midi.cpp new file mode 100644 index 0000000000..e67a78e9dc --- /dev/null +++ b/audio/softsynth/fmtowns_pc98/towns_midi.cpp @@ -0,0 +1,1045 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "audio/softsynth/fmtowns_pc98/towns_midi.h" +#include "audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h" +#include "common/textconsole.h" +#include "common/system.h" + +enum EnvelopeState; + +class TownsMidiOutputChannel { +friend class TownsMidiInputChannel; +public: +	TownsMidiOutputChannel(MidiDriver_TOWNS *driver, int chanId); +	~TownsMidiOutputChannel(); + +	void noteOn(uint8 msb, uint16 lsb); +	void noteOnPitchBend(uint8 msb, uint16 lsb); +	void setupProgram(const uint8 *data, uint8 mLevelPara, uint8 tLevelPara); +	void setupEffects(int index, uint8 flags, const uint8 *effectData); +	void setModWheel(uint8 value); +	 +	void connect(TownsMidiInputChannel *chan); +	void disconnect(); + +	bool update(); + +	enum CheckPriorityStatus { +		kDisconnected = -2, +		kHighPriority = -1 +	}; + +	int checkPriority(int pri); + +private: +	struct EffectEnvelope { +		uint8 state; +		int32 currentLevel; +		int32 duration; +		int32 maxLevel; +		int32 startLevel; +		uint8 loop; +		uint8 stateTargetLevels[4]; +		uint8 stateModWheelLevels[4]; +		int8 modWheelSensitivity; +		int8 modWheelState; +		int8 modWheelLast; +		uint16 numSteps; +		uint32 stepCounter; +		int32 incrPerStep; +		int8 dir; +		uint32 incrPerStepRem; +		uint32 incrCountRem; +	} *_effectEnvelopes; + +	struct EffectDef { +		int32 phase; +		uint8 type; +		uint8 useModWheel; +		uint8 loopRefresh; +		EffectEnvelope *s; +	} *_effectDefs; + +	void startEffect(EffectEnvelope *s, const uint8 *effectData); +	void updateEffectGenerator(EffectEnvelope *s, EffectDef *d); +	int advanceEffectEnvelope(EffectEnvelope *s, EffectDef *d); +	void initNextEnvelopeState(EffectEnvelope *s); +	int16 getEffectStartLevel(uint8 type); +	int getEffectModLevel(int lvl, int mod); + +	void keyOn(); +	void keyOff(); +	void keyOnSetFreq(uint16 frq); +	void out(uint8 reg, uint8 val); + +	TownsMidiInputChannel *_in; +	TownsMidiOutputChannel *_prev; +	TownsMidiOutputChannel *_next; +	uint8 _adjustModTl; +	uint8 _chan; +	uint8 _note; +	uint8 _operator2Tl; +	uint8 _operator1Tl; +	uint8 _sustainNoteOff; +	int16 _duration; +	 +	uint16 _freq; +	int16 _freqAdjust; + +	MidiDriver_TOWNS *_driver; + +	static const uint8 _chanMap[]; +	static const uint8 _chanMap2[]; +	static const uint8 _effectDefaults[]; +	static const uint16 _effectEnvStepTable[]; +	static const uint8 _freqMSB[]; +	static const uint16 _freqLSB[]; +}; + +class TownsMidiInputChannel : public MidiChannel { +friend class TownsMidiOutputChannel; +public: +	TownsMidiInputChannel(MidiDriver_TOWNS *driver, int chanIndex); +	~TownsMidiInputChannel(); + +	MidiDriver *device() { return _driver; } +	byte getNumber() { return _chanIndex; } +	bool allocate(); +	void release(); + +	void send(uint32 b); + +	void noteOff(byte note); +	void noteOn(byte note, byte velocity); +	void programChange(byte program); +	void pitchBend(int16 bend); +	void controlChange(byte control, byte value); +	void pitchBendFactor(byte value); +	void priority(byte value); +	void sysEx_customInstrument(uint32 type, const byte *instr);	 + +private: +	void controlModulationWheel(byte value); +	void controlVolume(byte value); +	void controlPanPos(byte value); +	void controlSustain(byte value); + +	void releasePedal(); + +	TownsMidiOutputChannel *_out; +	 +	uint8 *_instrument; +	uint8 _prg; +	uint8 _chanIndex; +	uint8 _effectLevel; +	uint8 _priority; +	uint8 _ctrlVolume; +	uint8 _tl; +	uint8 _pan; +	uint8 _panEff; +	uint8 _percS; +	int8 _transpose; +	uint8 _fld_1f; +	int8 _detune; +	int8 _modWheel; +	uint8 _sustain; +	uint8 _pitchBendFactor; +	int16 _pitchBend; +	uint16 _freqLSB; + +	bool _allocated; + +	MidiDriver_TOWNS *_driver; + +	static const uint8 _programAdjustLevel[]; +}; + +class TownsMidiChanState { +public: +	TownsMidiChanState(); +	~TownsMidiChanState() {}	 +	uint8 get(uint8 type); + +	uint8 unk1; +	uint8 mulAmsFms; +	uint8 tl; +	uint8 attDec; +	uint8 sus; +	uint8 fgAlg; +	uint8 unk2; +}; + +TownsMidiChanState::TownsMidiChanState() { +	unk1 = mulAmsFms = tl =	attDec = sus = fgAlg = unk2 = 0; +} + +uint8 TownsMidiChanState::get(uint8 type) { +	switch (type) { +	case 0: +		return unk1; +	case 1: +		return mulAmsFms; +	case 2: +		return tl; +	case 3: +		return attDec; +	case 4: +		return sus; +	case 5: +		return fgAlg; +	case 6: +		return unk2; +	default: +		break; +	} +	return 0; +} + +TownsMidiOutputChannel::TownsMidiOutputChannel(MidiDriver_TOWNS *driver, int chanIndex) : _driver(driver), _chan(chanIndex), +	_in(0), _prev(0), _next(0), _adjustModTl(0), _operator2Tl(0), _note(0), _operator1Tl(0), _sustainNoteOff(0), _duration(0), _freq(0), _freqAdjust(0) { +	_effectEnvelopes = new EffectEnvelope[2]; +	_effectDefs = new EffectDef[2]; + +	memset(_effectEnvelopes, 0, 2 * sizeof(EffectEnvelope)); +	memset(_effectDefs, 0, 2 * sizeof(EffectDef)); +	_effectDefs[0].s = &_effectEnvelopes[1]; +	_effectDefs[1].s = &_effectEnvelopes[0]; +} + +TownsMidiOutputChannel::~TownsMidiOutputChannel() { +	delete[] _effectEnvelopes; +	delete[] _effectDefs; +} + +void TownsMidiOutputChannel::noteOn(uint8 msb, uint16 lsb) { +	_freq = (msb << 7) + lsb; +	_freqAdjust = 0; +	keyOnSetFreq(_freq); +} + +void TownsMidiOutputChannel::noteOnPitchBend(uint8 msb, uint16 lsb) { +	_freq = (msb << 7) + lsb; +	keyOnSetFreq(_freq + _freqAdjust); +} + +void TownsMidiOutputChannel::setupProgram(const uint8 *data, uint8 mLevelPara, uint8 tLevelPara) { +	// This driver uses only 2 operators and 2 algorithms (algorithm 5 and 7), +	// since it is just a modified AdLib driver. It also uses AdLib programs. +	// There are no FM-TOWNS specific programs. This is the reason for the low quality of the FM-TOWNS +	// music (unsuitable data is just forced into the wrong audio device). + +	static const uint8 mul[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 12, 12, 15, 15 }; +	uint8 chan = _chanMap[_chan];	 + +	uint8 mulAmsFms1 = _driver->_chanState[chan].mulAmsFms = data[0]; +	uint8 tl1 = _driver->_chanState[chan].tl = (data[1] | 0x3f) - mLevelPara; +	uint8 attDec1 = _driver->_chanState[chan].attDec = ~data[2]; +	uint8 sus1 = _driver->_chanState[chan].sus = ~data[3]; +	_driver->_chanState[chan].unk2 = data[4]; +	chan += 3; + +	out(0x30, mul[mulAmsFms1 & 0x0f]); +	out(0x40, (tl1 & 0x3f) + 15); +	out(0x50, ((attDec1 >> 4) << 1) | ((attDec1 >> 4) & 1)); +	out(0x60, ((attDec1 << 1) | (attDec1 & 1)) & 0x1f); +	out(0x70, (mulAmsFms1 & 0x20) ^ 0x20 ? (((sus1 & 0x0f) << 1) | 1) : 0); +	out(0x80, sus1); + +	uint8 mulAmsFms2 = _driver->_chanState[chan].mulAmsFms = data[5]; +	uint8 tl2 = _driver->_chanState[chan].tl = (data[6] | 0x3f) - tLevelPara; +	uint8 attDec2 = _driver->_chanState[chan].attDec = ~data[7]; +	uint8 sus2 = _driver->_chanState[chan].sus = ~data[8]; +	_driver->_chanState[chan].unk2 = data[9]; + +	uint8 mul2 = mul[mulAmsFms2 & 0x0f]; +	tl2 = (tl2 & 0x3f) + 15; +	uint8 ar2 = ((attDec2 >> 4) << 1) | ((attDec2 >> 4) & 1); +	uint8 dec2 = ((attDec2 << 1) | (attDec2 & 1)) & 0x1f; +	uint8 sus2r = (mulAmsFms2 & 0x20) ^ 0x20 ? (((sus2 & 0x0f) << 1) | 1) : 0; + +	for (int i = 4; i < 16; i += 4) { +		out(0x30 + i, mul2); +		out(0x40 + i, tl2); +		out(0x50 + i, ar2); +		out(0x60 + i, dec2); +		out(0x70 + i, sus2r); +		out(0x80 + i, sus2); +	} + +	_driver->_chanState[chan].fgAlg = data[10]; + +	uint8 alg = 5 + 2 * (data[10] & 1); +	uint8 fb = 4 * (data[10] & 0x0e); +	out(0xb0, fb | alg); +	uint8 t = mulAmsFms1 | mulAmsFms2; +	out(0xb4, (0xc0 | ((t & 0x80) >> 3) | ((t & 0x40) >> 5))); +} + +void TownsMidiOutputChannel::setupEffects(int index, uint8 flags, const uint8 *effectData) { +	uint16 effectMaxLevel[] = { 0x2FF, 0x1F, 0x07, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3F, 0x0F, 0x0F, 0x0F, 0x03, 0x3E, 0x1F }; +	uint8 effectType[] = { 0x1D, 0x1C, 0x1B, 0x00, 0x03, 0x04, 0x07, 0x08, 0x0D, 0x10, 0x11, 0x14, 0x15, 0x1e, 0x1f, 0x00 }; +	 +	EffectEnvelope *s = &_effectEnvelopes[index]; +	EffectDef *d = &_effectDefs[index]; + +	d->phase = 0; +	d->useModWheel = flags & 0x40; +	s->loop = flags & 0x20; +	d->loopRefresh = flags & 0x10; +	d->type = effectType[flags & 0x0f]; +	s->maxLevel = effectMaxLevel[flags & 0x0f]; +	s->modWheelSensitivity = 31; +	s->modWheelState = d->useModWheel ? _in->_modWheel >> 2 : 31; + +	switch (d->type) { +	case 0: +		s->startLevel = _operator2Tl; +		break; +	case 13: +		s->startLevel = _operator1Tl; +		break; +	case 30: +		s->startLevel = 31; +		d->s->modWheelState = 0; +		break; +	case 31: +		s->startLevel = 0; +		d->s->modWheelSensitivity = 0; +		break; +	default: +		s->startLevel = getEffectStartLevel(d->type); +		break; +	} + +	startEffect(s, effectData); +} + +void TownsMidiOutputChannel::setModWheel(uint8 value) { +	if (_effectEnvelopes[0].state != kEnvReady && _effectDefs[0].type) +		_effectEnvelopes[0].modWheelState = value >> 2; + +	if (_effectEnvelopes[1].state != kEnvReady && _effectDefs[1].type) +		_effectEnvelopes[1].modWheelState = value >> 2; +} + +void TownsMidiOutputChannel::connect(TownsMidiInputChannel *chan) { +	if (!chan) +		return; + +	_in = chan; +	_next = chan->_out; +	_prev = 0; +	chan->_out = this; +	if (_next) +		_next->_prev = this; +} + +void TownsMidiOutputChannel::disconnect() { +	keyOff(); +	 +	TownsMidiOutputChannel *p = _prev; +	TownsMidiOutputChannel *n = _next; + +	if (n) +		n->_prev = p; +	if (p) +		p->_next = n; +	else +		_in->_out = n; +	_in = 0; +} + +bool TownsMidiOutputChannel::update() { +	if (!_in) +		return false; + +	if (_duration) { +		_duration -= 17; +		if (_duration <= 0) { +			disconnect(); +			return true; +		} +	} + +	for (int i = 0; i < 2; i++) { +		if (_effectEnvelopes[i].state != kEnvReady) +			updateEffectGenerator(&_effectEnvelopes[i], &_effectDefs[i]); +	} + +	return false; +} + +int TownsMidiOutputChannel::checkPriority(int pri) { +	if (!_in) +		return kDisconnected; + +	if (!_next && pri >= _in->_priority) +		return _in->_priority; + +	return kHighPriority; +} + +void TownsMidiOutputChannel::startEffect(EffectEnvelope *s, const uint8 *effectData) { +	s->state = kEnvAttacking; +	s->currentLevel = 0; +	s->modWheelLast = 31; +	s->duration = effectData[0] * 63; +	s->stateTargetLevels[0] = effectData[1]; +	s->stateTargetLevels[1] = effectData[3]; +	s->stateTargetLevels[2] = effectData[5]; +	s->stateTargetLevels[3] = effectData[6]; +	s->stateModWheelLevels[0] = effectData[2]; +	s->stateModWheelLevels[1] = effectData[4]; +	s->stateModWheelLevels[2] = 0; +	s->stateModWheelLevels[3] = effectData[7]; +	initNextEnvelopeState(s); +} + +void TownsMidiOutputChannel::updateEffectGenerator(EffectEnvelope *s, EffectDef *d) { +	uint8 f = advanceEffectEnvelope(s, d); + +	if (f & 1) { +		switch (d->type) { +		case 0: +			_operator2Tl = s->startLevel + d->phase; +			break; +		case 13: +			_operator1Tl = s->startLevel + d->phase; +			break; +		case 30: +			d->s->modWheelState = d->phase; +			break; +		case 31: +			d->s->modWheelSensitivity = d->phase; +			break; +		default: +			break; +		} +	} + +	if (f & 2) { +		if (d->loopRefresh) +			keyOn(); +	} +} + +int TownsMidiOutputChannel::advanceEffectEnvelope(EffectEnvelope *s, EffectDef *d) { +	if (s->duration) { +		s->duration -= 17; +		if (s->duration <= 0) { +			s->state = kEnvReady; +			return 0; +		} +	}  + +	int32 t = s->currentLevel + s->incrPerStep; +	 +	s->incrCountRem += s->incrPerStepRem; +	if (s->incrCountRem >= s->numSteps) { +		s->incrCountRem -= s->numSteps; +		t += s->dir; +	} + +	int retFlags = 0; + +	if (t != s->currentLevel || (s->modWheelState != s->modWheelLast)) { +		s->currentLevel = t; +		s->modWheelLast = s->modWheelState; +		t = getEffectModLevel(t, s->modWheelState); +		if (t != d->phase) +			d->phase = t; +		retFlags |= 1; +	} + +	if (--s->stepCounter) +		return retFlags; + +	if (++s->state > kEnvReleasing) { +		if (!s->loop) { +			s->state = kEnvReady; +			return retFlags; +		} +		s->state = kEnvAttacking; +		retFlags |= 2; +	} + +	initNextEnvelopeState(s); + +	return retFlags; +} + +void TownsMidiOutputChannel::initNextEnvelopeState(EffectEnvelope *s) { +	uint8 v = s->stateTargetLevels[s->state - 1]; +	int32 e = _effectEnvStepTable[_driver->_operatorLevelTable[((v & 0x7f) << 5) + s->modWheelSensitivity]]; + +	if (v & 0x80) +		e = _driver->randomValue(e); +	 +	if (!e) +		e = 1; + +	s->numSteps = s->stepCounter = e; +	int32 d = 0; + +	if (s->state != kEnvSustaining) { +		v = s->stateModWheelLevels[s->state - 1]; +		e = getEffectModLevel(s->maxLevel, (v & 0x7f) - 31); + +		if (v & 0x80) +			e = _driver->randomValue(e); + +		if (e + s->startLevel > s->maxLevel) { +			e = s->maxLevel - s->startLevel; +		} else { +			if (e + s->startLevel < 0) +				e = -s->startLevel; +		} + +		d = e - s->currentLevel; +	} + +	s->incrPerStep = d / s->numSteps; +	s->dir = (d < 0) ? -1 : 1; +	d *= s->dir; +	s->incrPerStepRem = d % s->numSteps; +	s->incrCountRem = 0; +} + +int16 TownsMidiOutputChannel::getEffectStartLevel(uint8 type) { +	uint8 chan = (type < 13) ? _chanMap2[_chan] : ((type < 26) ? _chanMap[_chan] : _chan); +	 +	if (type == 28) +		return 15; +	else if (type == 29) +		return 383; +	else if (type > 29) +		return 0; +	else if (type > 12) +		type -= 13; + +	const uint8 *def = &_effectDefaults[type << 2]; +	uint8 res = (_driver->_chanState[chan].get(def[0] >> 5) & def[2]) >> def[1]; +	if (def[3]) +		res = def[3] - res; +	 +	return res;	 +} + +int TownsMidiOutputChannel::getEffectModLevel(int lvl, int mod) { +	if (mod == 0) +		return 0; + +	if (mod == 31) +		return lvl; + +	if (lvl > 63 || lvl < -63) +		return ((lvl + 1) * mod) >> 5; + +	if (mod < 0) { +		if (lvl < 0)			 +			return _driver->_operatorLevelTable[((-lvl) << 5) - mod]; +		else +			return -_driver->_operatorLevelTable[(lvl << 5) - mod]; +	} else { +		if (lvl < 0)			 +			return -_driver->_operatorLevelTable[((-lvl) << 5) + mod]; +		else +			return _driver->_operatorLevelTable[((-lvl) << 5) + mod]; +	} + +	return 0; +} + +void TownsMidiOutputChannel::keyOn() { +	out(0x28, 0x30); +} + +void TownsMidiOutputChannel::keyOff() { +	out(0x28, 0); +} + +void TownsMidiOutputChannel::keyOnSetFreq(uint16 frq) { +	uint16 note = (frq << 1) >> 8;	 +	frq = (_freqMSB[note] << 11) | _freqLSB[note] ; +	out(0xa4, frq >> 8); +	out(0xa0, frq & 0xff); +	//out(0x28, 0x00); +	out(0x28, 0x30); +} + +void TownsMidiOutputChannel::out(uint8 reg, uint8 val) { +	static const uint8 chanRegOffs[] = { 0, 1, 2, 0, 1, 2 }; +	static const uint8 keyValOffs[] = { 0, 1, 2, 4, 5, 6 }; + +	if (reg == 0x28) +		val = (val & 0xf0) | keyValOffs[_chan]; +	if (reg < 0x30) +		_driver->_intf->callback(17, 0, reg, val); +	else +		_driver->_intf->callback(17, _chan / 3, (reg & ~3) | chanRegOffs[_chan], val); +} + +const uint8 TownsMidiOutputChannel::_chanMap[] = { +	0, 1, 2, 8, 9, 10 +}; + +const uint8 TownsMidiOutputChannel::_chanMap2[] = { +	3, 4, 5, 11, 12, 13 +}; + +const uint8 TownsMidiOutputChannel::_effectDefaults[] = { +	0x40, 0x00, 0x3F, 0x3F, 0xE0, 0x02, 0x00, 0x00, 0x40, 0x06, 0xC0, 0x00, +	0x20, 0x00, 0x0F, 0x00, 0x60, 0x04, 0xF0, 0x0F, 0x60, 0x00, 0x0F, 0x0F, +	0x80, 0x04, 0xF0, 0x0F, 0x80, 0x00, 0x0F, 0x0F, 0xE0, 0x00, 0x03, 0x00, +	0x20, 0x07, 0x80, 0x00, 0x20, 0x06, 0x40, 0x00, 0x20, 0x05, 0x20, 0x00, +	0x20, 0x04, 0x10, 0x00, 0xC0, 0x00, 0x01, 0x00, 0xC0, 0x01, 0x0E, 0x00 +}; + +const uint16 TownsMidiOutputChannel::_effectEnvStepTable[] = { +	0x0001, 0x0002, 0x0004, 0x0005, 0x0006, 0x0007,	0x0008, 0x0009, +	0x000A, 0x000C, 0x000E, 0x0010,	0x0012, 0x0015, 0x0018, 0x001E, +	0x0024, 0x0032,	0x0040, 0x0052, 0x0064, 0x0088, 0x00A0, 0x00C0, +	0x00F0, 0x0114, 0x0154, 0x01CC, 0x0258, 0x035C,	0x04B0, 0x0640 +}; + +const uint8 TownsMidiOutputChannel::_freqMSB[] = { +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +	0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +	0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +	0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +	0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +	0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +	0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +	0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x80, 0x81, 0x83, 0x85, +	0x87, 0x88, 0x8A, 0x8C, 0x8E, 0x8F, 0x91, 0x93, 0x95, 0x96, 0x98, 0x9A, +	0x9C, 0x9E, 0x9F, 0xA1, 0xA3, 0xA5, 0xA6, 0xA8, 0xAA, 0xAC, 0xAD, 0xAF, +	0xB1, 0xB3, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0xBD, 0xBF, 0xC1, 0xC3, 0xC4, +	0xC6, 0xC8, 0xCA, 0xCB, 0xCD, 0xCF, 0xD1, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, +	0xDB, 0xDD, 0xDF, 0xE1, 0xE2, 0xE4, 0xE6, 0xE8, 0xE9, 0xEB, 0xED, 0xEF +}; + +const uint16 TownsMidiOutputChannel::_freqLSB[] = { +	0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6, +	0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x02D6, 0x0301, 0x032F, +	0x0360, 0x0393, 0x03C9, 0x0403, 0x0440, 0x0481, 0x04C6, 0x050E, +	0x055B, 0x02D6, 0x0301, 0x032F, 0x0360, 0x0393, 0x03C9, 0x0403, +	0x0440, 0x0481, 0x04C6, 0x050E, 0x055B, 0x02D6, 0x0301, 0x032F, +	0x0360, 0x0393, 0x03C9, 0x0403, 0x0440, 0x0481, 0x04C6, 0x050E, +	0x055B, 0x02D6, 0x0301, 0x032F, 0x0360, 0x0393, 0x03C9, 0x0403, +	0x0440, 0x0481, 0x04C6, 0x050E, 0x055B, 0x02D6, 0x0301, 0x032F, +	0x0360, 0x0393, 0x03C9, 0x0403, 0x0440, 0x0481, 0x04C6, 0x050E, +	0x055B, 0x02D6, 0x0301, 0x032F, 0x0360, 0x0393, 0x03C9, 0x0403, +	0x0440, 0x0481, 0x04C6, 0x050E, 0x055B, 0x02D6, 0x0301, 0x032F, +	0x0360, 0x0393, 0x03C9, 0x0403, 0x0440, 0x0481, 0x04C6, 0x050E, +	0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, +	0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, +	0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, +	0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B, 0x055B +}; + +TownsMidiInputChannel::TownsMidiInputChannel(MidiDriver_TOWNS *driver, int chanIndex) : MidiChannel(), _driver(driver), _out(0), _prg(0), _chanIndex(chanIndex), +	_effectLevel(0), _priority(0), _ctrlVolume(0), _tl(0), _pan(0), _panEff(0), _transpose(0), _percS(0), _pitchBendFactor(0), _pitchBend(0), _sustain(0), _freqLSB(0), +	_fld_1f(0), _detune(0), _modWheel(0), _allocated(false) { +	_instrument = new uint8[30]; +	memset(_instrument, 0, 30); +} + +TownsMidiInputChannel::~TownsMidiInputChannel() { +	delete[] _instrument; +} + +bool TownsMidiInputChannel::allocate() { +	if (_allocated) +		return false; +	_allocated = true; +	return true; +} + +void TownsMidiInputChannel::release() { +	_allocated = false; +} + +void TownsMidiInputChannel::send(uint32 b) { +	_driver->send(b | _chanIndex); +} + +void TownsMidiInputChannel::noteOff(byte note) { +	if (!_out) +		return; + +	for (TownsMidiOutputChannel *oc = _out; oc; oc = oc->_next) { +		if (oc->_note != note) +			continue; + +		if (_sustain) +			oc->_sustainNoteOff = 1; +		else +			oc->disconnect(); +	} +} + +void TownsMidiInputChannel::noteOn(byte note, byte velocity) { +	TownsMidiOutputChannel *oc = _driver->allocateOutputChannel(_priority); +	 +	if (!oc) +		return; + +	oc->connect(this); + +	oc->_adjustModTl = _instrument[10] & 1; +	oc->_note = note; +	oc->_sustainNoteOff = 0; +	oc->_duration = _instrument[29] * 63; +	 +	oc->_operator1Tl = (_instrument[1] & 0x3f) + _driver->_operatorLevelTable[((velocity >> 1) << 5) + (_instrument[4] >> 2)]; +	if (oc->_operator1Tl > 63) +		oc->_operator1Tl = 63; + +	oc->_operator2Tl = (_instrument[6] & 0x3f) + _driver->_operatorLevelTable[((velocity >> 1) << 5) + (_instrument[9] >> 2)]; +	if (oc->_operator2Tl > 63) +		oc->_operator2Tl = 63; + +	oc->setupProgram(_instrument, oc->_adjustModTl == 1 ? _programAdjustLevel[_driver->_operatorLevelTable[(_tl >> 2) + (oc->_operator1Tl << 5)]] : oc->_operator1Tl, _programAdjustLevel[_driver->_operatorLevelTable[(_tl >> 2) + (oc->_operator2Tl << 5)]]); +	oc->noteOn(note + _transpose, _freqLSB); + +	if (_instrument[11] & 0x80) +		oc->setupEffects(0, _instrument[11], &_instrument[12]); +	else +		oc->_effectEnvelopes[0].state = kEnvReady; + +	if (_instrument[20] & 0x80) +		oc->setupEffects(1, _instrument[20], &_instrument[21]); +	else +		oc->_effectEnvelopes[1].state = kEnvReady; +} + +void TownsMidiInputChannel::programChange(byte program) { +	// Not implemented (The loading and assignment of programs +	// is handled externally by the SCUMM engine. The programs +	// get sent via sysEx_customInstrument.) +} + +void TownsMidiInputChannel::pitchBend(int16 bend) { +	_pitchBend = bend; +	_freqLSB = ((_pitchBend * _pitchBendFactor) >> 6) + _detune; +	for (TownsMidiOutputChannel *oc = _out; oc; oc = oc->_next) +		oc->noteOnPitchBend(oc->_note + oc->_in->_transpose, _freqLSB); +} + +void TownsMidiInputChannel::controlChange(byte control, byte value) { +	switch (control) { +	case 1: +		controlModulationWheel(value); +		break; +	case 7: +		controlVolume(value); +		break; +	case 10: +		controlPanPos(value); +		break; +	case 64: +		controlSustain(value); +		break; +	case 123: +		while (_out) +			_out->disconnect(); +		break; +	default: +		break; +	} +} + +void TownsMidiInputChannel::pitchBendFactor(byte value) { +	_pitchBendFactor = value; +	_freqLSB = ((_pitchBend * _pitchBendFactor) >> 6) + _detune; +	for (TownsMidiOutputChannel *oc = _out; oc; oc = oc->_next) +		oc->noteOnPitchBend(oc->_note + oc->_in->_transpose, _freqLSB); +} + +void TownsMidiInputChannel::priority(byte value) { +	_priority = value; +} + +void TownsMidiInputChannel::sysEx_customInstrument(uint32 type, const byte *instr) { +	memcpy(_instrument, instr, 30); +} + +void TownsMidiInputChannel::controlModulationWheel(byte value) { +	_modWheel = value; +	for (TownsMidiOutputChannel *oc = _out; oc; oc = oc->_next) +		oc->setModWheel(value); +} + +void TownsMidiInputChannel::controlVolume(byte value) { +	/* This is all done inside the imuse code +	uint16 v1 = _ctrlVolume + 1; +	uint16 v2 = value; +	if (_chanIndex != 16) { +		_ctrlVolume = value; +		v2 = _player->getEffectiveVolume(); +	} +	_tl = (v1 * v2) >> 7;*/ + +	_tl = value; +} + +void TownsMidiInputChannel::controlPanPos(byte value) { +	// not implemented +} + +void TownsMidiInputChannel::controlSustain(byte value) { +	_sustain = value; +	if (!value) +		releasePedal(); +} + +void TownsMidiInputChannel::releasePedal() { +	for (TownsMidiOutputChannel *oc = _out; oc; oc = oc->_next) { +		if (oc->_sustainNoteOff) +			oc->disconnect(); +	} +} + +const uint8 TownsMidiInputChannel::_programAdjustLevel[] = { +	0x00, 0x04, 0x07, 0x0B, 0x0D, 0x10, 0x12, 0x14, +	0x16, 0x18, 0x1A, 0x1B, 0x1D, 0x1E, 0x1F, 0x21, +	0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, +	0x2A, 0x2B, 0x2C, 0x2C, 0x2D, 0x2E, 0x2F, 0x2F, +	0x30, 0x31, 0x31, 0x32, 0x33, 0x33, 0x34, 0x35, +	0x35, 0x36, 0x36, 0x37, 0x37, 0x38, 0x38, 0x39, +	0x39, 0x3A, 0x3A, 0x3B, 0x3B, 0x3C, 0x3C, 0x3C, +	0x3D, 0x3D, 0x3E, 0x3E, 0x3E, 0x3F, 0x3F, 0x3F +}; + +MidiDriver_TOWNS::MidiDriver_TOWNS(Audio::Mixer *mixer) : _timerProc(0), _timerProcPara(0), _channels(0), _out(0), +	_chanState(0), _operatorLevelTable(0), _tickCounter1(0), _tickCounter2(0), _rand(1), _allocCurPos(0), _isOpen(false) { +	_intf = new TownsAudioInterface(mixer, this); +} + +MidiDriver_TOWNS::~MidiDriver_TOWNS() { +	close(); +	delete _intf; +} + +int MidiDriver_TOWNS::open() { +	if (_isOpen) +		return MERR_ALREADY_OPEN; + +	if (!_intf->init()) +		return MERR_CANNOT_CONNECT; + +	_channels = new TownsMidiInputChannel*[32]; +	for (int i = 0; i < 32; i++) +		_channels[i] = new TownsMidiInputChannel(this, i > 8 ? (i + 1) : i); +	 +	_out = new TownsMidiOutputChannel*[6]; +	for (int i = 0; i < 6; i++) +		_out[i] = new TownsMidiOutputChannel(this, i); + +	_chanState = new TownsMidiChanState[32]; + +	_operatorLevelTable = new uint8[2048]; +	for (int i = 0; i < 64; i++) { +		for (int ii = 0; ii < 32; ii++) +			_operatorLevelTable[(i << 5) + ii] = ((i * (ii + 1)) >> 5) & 0xff; +	} +	for (int i = 0; i < 64; i++) +		_operatorLevelTable[i << 5] = 0; + +	_intf->callback(0); + +	_intf->callback(21, 255, 1); +	_intf->callback(21, 0, 1); +	_intf->callback(22, 255, 221); + +	_intf->callback(33, 8); +	_intf->setSoundEffectChanMask(~0x3f); + +	 _tickCounter1 = _tickCounter2 = 0; +	 _allocCurPos = 0; +	 _rand = 1; + +	_isOpen = true; + +	return 0; +} + +void MidiDriver_TOWNS::close() { +	if (!_isOpen) +		return; + +	_isOpen = false; + +	setTimerCallback(0, 0); +	g_system->delayMillis(20); +	 +	if (_channels) { +		for (int i = 0; i < 32; i++) +			delete _channels[i]; +		delete[] _channels; +	} +	_channels = 0; + +	if (_out) { +		for (int i = 0; i < 6; i++) +			delete _out[i]; +		delete[] _out; +	} +	_out = 0; + +	delete[] _chanState; +	_chanState = 0; +	delete[] _operatorLevelTable; +	_operatorLevelTable = 0; +} + +void MidiDriver_TOWNS::send(uint32 b) { +	if (!_isOpen) +		return; + +	byte param2 = (b >> 16) & 0xFF; +	byte param1 = (b >> 8) & 0xFF; +	byte cmd = b & 0xF0; + +	TownsMidiInputChannel *c = _channels[b & 0x0F]; + +	switch (cmd) { +	case 0x80: +		c->noteOff(param1); +		break; +	case 0x90: +		if (param2) +			c->noteOn(param1, param2); +		else +			c->noteOff(param1); +		break; +	case 0xB0: +		c->controlChange(param1, param2); +		break; +	case 0xC0: +		c->programChange(param1); +		break; +	case 0xE0: +		c->pitchBend((param1 | (param2 << 7)) - 0x2000); +		break; +	case 0xF0: +		warning("MidiDriver_TOWNS: Receiving SysEx command on a send() call"); +		break; + +	default: +		break; +	} +} + +void MidiDriver_TOWNS::setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) { +	_timerProc = timer_proc; +	_timerProcPara = timer_param; +} + +uint32 MidiDriver_TOWNS::getBaseTempo() { +	return 10080; +} + +MidiChannel *MidiDriver_TOWNS::allocateChannel() { +	if (!_isOpen) +		return 0; + +	for (int i = 0; i < 32; ++i) {		 +		TownsMidiInputChannel *chan = _channels[i]; +		if (chan->allocate()) +			return chan; +	} + +	return 0; +} + +MidiChannel *MidiDriver_TOWNS::getPercussionChannel() { +	return 0; +} + +void MidiDriver_TOWNS::timerCallback(int timerId) { +	if (!_isOpen) +		return; + +	switch (timerId) { +	case 1: +		updateParser(); +		updateOutputChannels(); + +		/*_tickCounter1 += 10000; +		while (_tickCounter1 >= 4167) { +			_tickCounter1 -= 4167; +			unkUpdate(); +		}*/ +		break; +	default: +		break; +	} +} + +void MidiDriver_TOWNS::updateParser() { +	if (_timerProc) +		_timerProc(_timerProcPara); +} + +void MidiDriver_TOWNS::updateOutputChannels() { +	_tickCounter2 += 10000; +	while (_tickCounter2 >= 16667) { +		_tickCounter2 -= 16667; +		for (int i = 0; i < 6; i++) { +			if (_out[i]->update()) +				return; +		} +	} +} + +TownsMidiOutputChannel *MidiDriver_TOWNS::allocateOutputChannel(uint8 pri) { +	TownsMidiOutputChannel *res = 0; + +	for (int i = 0; i < 6; i++) { +		if (++_allocCurPos == 6) +			_allocCurPos = 0; + +		int s = _out[_allocCurPos]->checkPriority(pri); +		if (s == TownsMidiOutputChannel::kDisconnected) +			return _out[_allocCurPos]; + +		if (s != TownsMidiOutputChannel::kHighPriority) { +			pri = s; +			res = _out[_allocCurPos]; +		} +	} +	 +	if (res) +		res->disconnect(); + +	return res; +} + +int MidiDriver_TOWNS::randomValue(int para) { +	_rand = (_rand & 1) ? (_rand >> 1) ^ 0xb8 : (_rand >> 1); +	return (_rand * para) >> 8; +} diff --git a/audio/softsynth/fmtowns_pc98/towns_midi.h b/audio/softsynth/fmtowns_pc98/towns_midi.h new file mode 100644 index 0000000000..a98bb1b59c --- /dev/null +++ b/audio/softsynth/fmtowns_pc98/towns_midi.h @@ -0,0 +1,83 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TOWNS_MIDI_H +#define TOWNS_MIDI_H + +#include "audio/softsynth/fmtowns_pc98/towns_audio.h" +#include "audio/mididrv.h" + + +class TownsMidiOutputChannel; +class TownsMidiInputChannel; +class TownsMidiChanState; + +class MidiDriver_TOWNS : public MidiDriver, public TownsAudioInterfacePluginDriver { +friend class TownsMidiInputChannel; +friend class TownsMidiOutputChannel; +public: +	MidiDriver_TOWNS(Audio::Mixer *mixer); +	~MidiDriver_TOWNS(); + +	int open(); +	bool isOpen() const { return _isOpen; } +	void close(); + +	void send(uint32 b); + +	void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc); + +	uint32 getBaseTempo(); +	MidiChannel *allocateChannel(); +	MidiChannel *getPercussionChannel(); + +	void timerCallback(int timerId); + +private: +	void updateParser(); +	void updateOutputChannels(); + +	TownsMidiOutputChannel *allocateOutputChannel(uint8 pri); +		 +	int randomValue(int para); + +	TownsMidiInputChannel **_channels; +	TownsMidiOutputChannel **_out; +	TownsMidiChanState *_chanState; + +	Common::TimerManager::TimerProc _timerProc; +	void *_timerProcPara; + +	TownsAudioInterface *_intf; + +	uint32 _tickCounter1; +	uint32 _tickCounter2; +	uint8 _allocCurPos; +	uint8 _rand; +	 +	bool _isOpen; + +	uint8 *_operatorLevelTable; +}; + +#endif + diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp index a551276ab1..e35da91cbb 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/softsynth/fmtowns_pc98/towns_pc98_driver.h" @@ -1148,7 +1145,7 @@ void TownsPC98_AudioDriver::loadMusicData(uint8 *data, bool loadPaused) {  	reset(); -	Common::StackLock lock(_mutex); +	lock();  	uint8 *src_a = _trackPtr = _musicBuffer = data;  	for (uint8 i = 0; i < 3; i++) { @@ -1179,6 +1176,7 @@ void TownsPC98_AudioDriver::loadMusicData(uint8 *data, bool loadPaused) {  	_finishedChannelsFlag = _finishedSSGFlag = _finishedRhythmFlag = 0;  	_musicPlaying = (loadPaused ? false : true); +	unlock();  }  void TownsPC98_AudioDriver::loadSoundEffectData(uint8 *data, uint8 trackNum) { @@ -1197,16 +1195,17 @@ void TownsPC98_AudioDriver::loadSoundEffectData(uint8 *data, uint8 trackNum) {  		return;  	} -	Common::StackLock lock(_mutex); +	lock();  	_sfxData = _sfxBuffer = data;  	_sfxOffsets[0] = READ_LE_UINT16(&_sfxData[(trackNum << 2)]);  	_sfxOffsets[1] = READ_LE_UINT16(&_sfxData[(trackNum << 2) + 2]);  	_sfxPlaying = true;  	_finishedSfxFlag = 0; +	unlock();  }  void TownsPC98_AudioDriver::reset() { -	Common::StackLock lock(_mutex); +	lock();  	_musicPlaying = false;  	_sfxPlaying = false; @@ -1233,13 +1232,13 @@ void TownsPC98_AudioDriver::reset() {  	if (_rhythmChannel)  		_rhythmChannel->reset();  #endif +	unlock();  }  void TownsPC98_AudioDriver::fadeStep() {  	if (!_musicPlaying)  		return; -	Common::StackLock lock(_mutex);  	for (int j = 0; j < _numChan; j++) {  		if (_updateChannelsFlag & _channels[j]->_idFlag)  			_channels[j]->fadeStep(); diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.h b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.h index 1227e2626a..46ee23895b 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_driver.h +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_driver.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef TOWNS_PC98_AUDIODRIVER_H diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp index 9d3751a0cc..bc5aa32823 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h" @@ -42,45 +39,22 @@ public:  	void recalculateRates();  	void generateOutput(int32 phasebuf, int32 *feedbuf, int32 &out); -	void feedbackLevel(int32 level) { -		_feedbackLevel = level ? level + 6 : 0; -	} -	void detune(int value) { -		_detn = &_detnTbl[value << 5]; -	} -	void multiple(uint32 value) { -		_multiple = value ? (value << 1) : 1; -	} -	void attackRate(uint32 value) { -		_specifiedAttackRate = value; -	} +	void feedbackLevel(int32 level); +	void detune(int value); +	void multiple(uint32 value); +	void attackRate(uint32 value);  	bool scaleRate(uint8 value); -	void decayRate(uint32 value) { -		_specifiedDecayRate = value; -		recalculateRates(); -	} -	void sustainRate(uint32 value) { -		_specifiedSustainRate = value; -		recalculateRates(); -	} -	void sustainLevel(uint32 value) { -		_sustainLevel = (value == 0x0f) ? 0x3e0 : value << 5; -	} -	void releaseRate(uint32 value) { -		_specifiedReleaseRate = value; -		recalculateRates(); -	} -	void totalLevel(uint32 value) { -		_totalLevel = value << 3; -	} -	void ampModulation(bool enable) { -		_ampMod = enable; -	} +	void decayRate(uint32 value); +	void sustainRate(uint32 value); +	void sustainLevel(uint32 value); +	void releaseRate(uint32 value); +	void totalLevel(uint32 value); +	void ampModulation(bool enable);  	void reset();  protected:  	EnvelopeState _state; -	bool _playing; +	bool _holdKey;  	uint32 _feedbackLevel;  	uint32 _multiple;  	uint32 _totalLevel; @@ -125,7 +99,7 @@ TownsPC98_FmSynthOperator::TownsPC98_FmSynthOperator(const uint32 timerbase, con  	_rtt(rtt), _rateTbl(rateTable), _rshiftTbl(shiftTable), _adTbl(attackDecayTable), _fTbl(frqTable),  	_sinTbl(sineTable), _tLvlTbl(tlevelOut), _detnTbl(detuneTable), _tickLength(timerbase * 2),  	_specifiedAttackRate(0), _specifiedDecayRate(0), _specifiedReleaseRate(0), _specifiedSustainRate(0), -	_phase(0), _state(kEnvReady), _playing(false), _timer(0), _keyScale1(0), +	_sustainLevel(0), _phase(0), _state(kEnvReady), _holdKey(false), _timer(0), _keyScale1(0),  	_keyScale2(0), _currentLevel(1023), _ampMod(false), _tickCount(0) {  	fs_a.rate = fs_a.shift = fs_d.rate = fs_d.shift = fs_s.rate = fs_s.shift = fs_r.rate = fs_r.shift = 0; @@ -134,19 +108,19 @@ TownsPC98_FmSynthOperator::TownsPC98_FmSynthOperator(const uint32 timerbase, con  }  void TownsPC98_FmSynthOperator::keyOn() { -	if (_playing) +	if (_holdKey)  		return; -	_playing = true; +	_holdKey = true;  	_state = kEnvAttacking;  	_phase = 0;  }  void TownsPC98_FmSynthOperator::keyOff() { -	if (!_playing) +	if (!_holdKey)  		return; -	_playing = false; +	_holdKey = false;  	if (_state != kEnvReady)  		_state = kEnvReleasing;  } @@ -202,39 +176,42 @@ void TownsPC98_FmSynthOperator::generateOutput(int32 phasebuf, int32 *feed, int3  		int32 targetLevel = 0;  		EnvelopeState nextState = kEnvReady; -		switch (_state) { -		case kEnvReady: -			return; -		case kEnvAttacking: -			targetLevel = 0; -			nextState = kEnvDecaying; -			if ((_specifiedAttackRate << 1) + _keyScale2 < 64) { -				targetTime = (1 << fs_a.shift) - 1; -				levelIncrement = (~_currentLevel * _adTbl[fs_a.rate + ((_tickCount >> fs_a.shift) & 7)]) >> 4; +		for (bool loop = true; loop;) { +			switch (_state) { +			case kEnvReady: +				return; +			case kEnvAttacking: +				targetLevel = 0; +				nextState = _sustainLevel ? kEnvDecaying : kEnvSustaining; +				if ((_specifiedAttackRate << 1) + _keyScale2 < 62) { +					targetTime = (1 << fs_a.shift) - 1; +					levelIncrement = (~_currentLevel * _adTbl[fs_a.rate + ((_tickCount >> fs_a.shift) & 7)]) >> 4; +				} else { +					_currentLevel = targetLevel; +					_state = nextState; +					continue; +				} +				break; +			case kEnvDecaying: +				targetTime = (1 << fs_d.shift) - 1; +				nextState = kEnvSustaining; +				targetLevel = _sustainLevel; +				levelIncrement = _adTbl[fs_d.rate + ((_tickCount >> fs_d.shift) & 7)]; +				break; +			case kEnvSustaining: +				targetTime = (1 << fs_s.shift) - 1; +				nextState = kEnvSustaining; +				targetLevel = 1023; +				levelIncrement = _adTbl[fs_s.rate + ((_tickCount >> fs_s.shift) & 7)]; +				break; +			case kEnvReleasing: +				targetTime = (1 << fs_r.shift) - 1; +				nextState = kEnvReady; +				targetLevel = 1023; +				levelIncrement = _adTbl[fs_r.rate + ((_tickCount >> fs_r.shift) & 7)];  				break; -			} else { -				_currentLevel = targetLevel; -				_state = nextState;  			} -			// Fall through -		case kEnvDecaying: -			targetTime = (1 << fs_d.shift) - 1; -			nextState = kEnvSustaining; -			targetLevel = _sustainLevel; -			levelIncrement = _adTbl[fs_d.rate + ((_tickCount >> fs_d.shift) & 7)]; -			break; -		case kEnvSustaining: -			targetTime = (1 << fs_s.shift) - 1; -			nextState = kEnvSustaining; -			targetLevel = 1023; -			levelIncrement = _adTbl[fs_s.rate + ((_tickCount >> fs_s.shift) & 7)]; -			break; -		case kEnvReleasing: -			targetTime = (1 << fs_r.shift) - 1; -			nextState = kEnvReady; -			targetLevel = 1023; -			levelIncrement = _adTbl[fs_r.rate + ((_tickCount >> fs_r.shift) & 7)]; -			break; +			loop = false;  		}  		if (!(_tickCount & targetTime)) { @@ -275,6 +252,63 @@ void TownsPC98_FmSynthOperator::generateOutput(int32 phasebuf, int32 *feed, int3  	out += *o;  } +void TownsPC98_FmSynthOperator::feedbackLevel(int32 level) { +	_feedbackLevel = level ? level + 6 : 0; +} + +void TownsPC98_FmSynthOperator::detune(int value) { +	_detn = &_detnTbl[value << 5]; +} + +void TownsPC98_FmSynthOperator::multiple(uint32 value) { +	_multiple = value ? (value << 1) : 1; +} + +void TownsPC98_FmSynthOperator::attackRate(uint32 value) { +	_specifiedAttackRate = value; +} + +bool TownsPC98_FmSynthOperator::scaleRate(uint8 value) { +	value = 3 - value; +	if (_keyScale1 != value) { +		_keyScale1 = value; +		return true; +	} + +	int k = _keyScale2; +	int r = _specifiedAttackRate ? (_specifiedAttackRate << 1) + 0x20 : 0; +	fs_a.rate = ((r + k) < 94) ? _rateTbl[r + k] : 136; +	fs_a.shift = ((r + k) < 94) ? _rshiftTbl[r + k] : 0; +	return false; +} + +void TownsPC98_FmSynthOperator::decayRate(uint32 value) { +	_specifiedDecayRate = value; +	recalculateRates(); +} + +void TownsPC98_FmSynthOperator::sustainRate(uint32 value) { +		_specifiedSustainRate = value; +		recalculateRates(); +	} + +void TownsPC98_FmSynthOperator::sustainLevel(uint32 value) { +	_sustainLevel = (value == 0x0f) ? 0x3e0 : value << 5; +} + +void TownsPC98_FmSynthOperator::releaseRate(uint32 value) { +	_specifiedReleaseRate = value; +	recalculateRates(); +} + +void TownsPC98_FmSynthOperator::totalLevel(uint32 value) { +	_totalLevel = value << 3; +} + +void TownsPC98_FmSynthOperator::ampModulation(bool enable) { +	_ampMod = enable; +} +  void TownsPC98_FmSynthOperator::reset() {  	keyOff();  	_timer = 0; @@ -295,20 +329,6 @@ void TownsPC98_FmSynthOperator::reset() {  	ampModulation(false);  } -bool TownsPC98_FmSynthOperator::scaleRate(uint8 value) { -	value = 3 - value; -	if (_keyScale1 != value) { -		_keyScale1 = value; -		return true; -	} - -	int k = _keyScale2; -	int r = _specifiedAttackRate ? (_specifiedAttackRate << 1) + 0x20 : 0; -	fs_a.rate = ((r + k) < 94) ? _rateTbl[r + k] : 136; -	fs_a.shift = ((r + k) < 94) ? _rshiftTbl[r + k] : 0; -	return false; -} -  class TownsPC98_FmSynthSquareSineSource {  public:  	TownsPC98_FmSynthSquareSineSource(const uint32 timerbase, const uint32 rtt); @@ -633,7 +653,8 @@ void TownsPC98_FmSynthSquareSineSource::updateRegs() {  #ifndef DISABLE_PC98_RHYTHM_CHANNEL  TownsPC98_FmSynthPercussionSource::TownsPC98_FmSynthPercussionSource(const uint32 timerbase, const uint32 rtt) : -	_rtt(rtt), _tickLength(timerbase * 2), _timer(0), _ready(false), _volMaskA(0), _volMaskB(0), _volumeA(Audio::Mixer::kMaxMixerVolume), _volumeB(Audio::Mixer::kMaxMixerVolume) { +	_rtt(rtt), _tickLength(timerbase * 2), _timer(0), _totalLevel(0), _volMaskA(0), _volMaskB(0), +	_volumeA(Audio::Mixer::kMaxMixerVolume), _volumeB(Audio::Mixer::kMaxMixerVolume), _ready(false) {  	memset(_rhChan, 0, sizeof(RhtChannel) * 6);  	_reg = new uint8 *[40]; @@ -840,8 +861,7 @@ TownsPC98_FmSynth::TownsPC98_FmSynth(Audio::Mixer *mixer, EmuType type) :  	_hasPercussion(type == kType86 ? true : false),  	_oprRates(0), _oprRateshift(0), _oprAttackDecay(0), _oprFrq(0), _oprSinTbl(0), _oprLevelOut(0), _oprDetune(0),  	 _rtt(type == kTypeTowns ? 0x514767 : 0x5B8D80), _baserate(55125.0f / (float)mixer->getOutputRate()), -	_volMaskA(0), _volMaskB(0), _volumeA(255), _volumeB(255), -	_regProtectionFlag(false), _ready(false) { +	_volMaskA(0), _volMaskB(0), _volumeA(255), _volumeB(255), _regProtectionFlag(false), _lock(0), _ready(false) {  	memset(&_timers[0], 0, sizeof(ChipTimer));  	memset(&_timers[1], 0, sizeof(ChipTimer)); @@ -908,7 +928,7 @@ bool TownsPC98_FmSynth::init() {  }  void TownsPC98_FmSynth::reset() { -	Common::StackLock lock(_mutex); +	lock();  	for (int i = 0; i < _numChan; i++) {  		for (int ii = 0; ii < 4; ii++)  			_chanInternal[i].opr[ii]->reset(); @@ -928,15 +948,16 @@ void TownsPC98_FmSynth::reset() {  	if (_prc)  		_prc->reset();  #endif +	unlock();  }  void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {  	if (_regProtectionFlag || !_ready)  		return; -	static const uint8 oprOrdr[] = { 0, 2, 1, 3 }; +	lock(); -	Common::StackLock lock(_mutex); +	static const uint8 oprOrdr[] = { 0, 2, 1, 3 };  	uint8 h = regAddress & 0xf0;  	uint8 l = (regAddress & 0x0f); @@ -1084,6 +1105,7 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {  		if (l == 0) {  			c->frqTemp = (c->frqTemp & 0xff00) | value;  			c->updateEnvelopeParameters = true; +			c->fmIndex = (c->frqTemp >> 4 & 0x7f);  			for (int i = 0; i < 4; i++)  				co[i]->frequency(c->frqTemp);  		} else if (l == 4) { @@ -1115,18 +1137,18 @@ void TownsPC98_FmSynth::writeReg(uint8 part, uint8 regAddress, uint8 value) {  	default:  		warning("TownsPC98_FmSynth: UNKNOWN ADDRESS %d", regAddress);  	} +	unlock();  }  int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) { -	Common::StackLock lock(_mutex); -  	memset(buffer, 0, sizeof(int16) * numSamples);  	int32 *tmp = new int32[numSamples];  	int32 *tmpStart = tmp;  	memset(tmp, 0, sizeof(int32) * numSamples);  	int32 samplesLeft = numSamples >> 1; +	_lock |= 0x10000; -	while (_ready && samplesLeft) { +	while (_ready && !(_lock & 0xffff) && samplesLeft) {  		int32 render = samplesLeft;  		for (int i = 0; i < 2; i++) { @@ -1175,12 +1197,16 @@ int TownsPC98_FmSynth::readBuffer(int16 *buffer, const int numSamples) {  		tmp += (render << 1);  	} +	_lock &= ~0x10000;  	delete[] tmpStart; +  	return numSamples;  }  void TownsPC98_FmSynth::deinit() {  	_ready = false; +	while (_lock) +		g_system->delayMillis(20);  	_mixer->stopHandle(_soundHandle);  	_timers[0].cb = _timers[1].cb = &TownsPC98_FmSynth::idleTimerCallback;  } @@ -1190,7 +1216,7 @@ uint8 TownsPC98_FmSynth::readSSGStatus() {  }  void TownsPC98_FmSynth::setVolumeIntern(int volA, int volB) { -	Common::StackLock lock(_mutex); +	lock();  	_volumeA = CLIP<uint16>(volA, 0, Audio::Mixer::kMaxMixerVolume);  	_volumeB = CLIP<uint16>(volB, 0, Audio::Mixer::kMaxMixerVolume);  	if (_ssg) @@ -1199,10 +1225,11 @@ void TownsPC98_FmSynth::setVolumeIntern(int volA, int volB) {  	if (_prc)  		_prc->setVolumeIntern(_volumeA, _volumeB);  #endif +	unlock();  }  void TownsPC98_FmSynth::setVolumeChannelMasks(int channelMaskA, int channelMaskB) { -	Common::StackLock lock(_mutex); +	lock();  	_volMaskA = channelMaskA;  	_volMaskB = channelMaskB;  	if (_ssg) @@ -1211,6 +1238,17 @@ void TownsPC98_FmSynth::setVolumeChannelMasks(int channelMaskA, int channelMaskB  	if (_prc)  		_prc->setVolumeChannelMasks(_volMaskA >> (_numChan + _numSSG), _volMaskB >> (_numChan + _numSSG));  #endif +	unlock(); +} + +void TownsPC98_FmSynth::lock() { +	_mutex.lock(); +	_lock++; +} + +void  TownsPC98_FmSynth::unlock() { +	_mutex.unlock(); +	_lock--;  }  void TownsPC98_FmSynth::generateTables() { @@ -1220,7 +1258,7 @@ void TownsPC98_FmSynth::generateTables() {  	WRITE_BE_UINT32(_oprRates + 32, _numChan == 6 ? 0x90900000 : 0x00081018);  	WRITE_BE_UINT32(_oprRates + 36, _numChan == 6 ? 0x00001010 : 0x00081018);  	memset(_oprRates, 0x90, 32); -	memset(_oprRates + 96, 0x80, 32); +	memset(&_oprRates[96], 0x80, 32);  	uint8 *dst = (uint8 *)_oprRates + 40;  	for (int i = 0; i < 40; i += 4)  		WRITE_BE_UINT32(dst + i, 0x00081018); @@ -1277,8 +1315,8 @@ void TownsPC98_FmSynth::generateTables() {  	uint8 *dtt = new uint8[128];  	memset(dtt, 0, 36); -	memset(dtt + 36, 1, 8); -	memcpy(dtt + 44, _detSrc, 84); +	memset(&dtt[36], 1, 8); +	memcpy(&dtt[44], _detSrc, 84);  	delete[] _oprDetune;  	_oprDetune = new int32[256]; diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h index 2b916b2cdc..f7bcc90585 100644 --- a/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef TOWNS_PC98_FMSYNTH_H @@ -47,7 +44,7 @@ class TownsPC98_FmSynthPercussionSource;  #endif  enum EnvelopeState { -	kEnvReady, +	kEnvReady = 0,  	kEnvAttacking,  	kEnvDecaying,  	kEnvSustaining, @@ -105,11 +102,13 @@ protected:  	void setVolumeIntern(int volA, int volB);  	void setVolumeChannelMasks(int channelMaskA, int channelMaskB); +	void lock(); +	void unlock(); +  	const int _numChan;  	const int _numSSG;  	const bool _hasPercussion; -	Common::Mutex _mutex;  private:  	void generateTables();  	void nextTick(int32 *buffer, uint32 bufferSize); @@ -127,6 +126,7 @@ private:  		}  		uint16 frqTemp; +		uint8 fmIndex;  		bool enableLeft;  		bool enableRight;  		bool updateEnvelopeParameters; @@ -182,6 +182,9 @@ private:  	Audio::Mixer *_mixer;  	Audio::SoundHandle _soundHandle; +	int _lock; +	Common::Mutex _mutex; +  #ifndef DISABLE_PC98_RHYTHM_CHANNEL  	static const uint8 _percussionData[];  #endif diff --git a/audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp b/audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp new file mode 100644 index 0000000000..194bfc41f9 --- /dev/null +++ b/audio/softsynth/fmtowns_pc98/towns_pc98_plugins.cpp @@ -0,0 +1,86 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "audio/softsynth/fmtowns_pc98/towns_midi.h" +#include "audio/musicplugin.h" +#include "common/translation.h" +#include "common/error.h" +#include "common/system.h" + + +class TownsEmuMusicPlugin : public MusicPluginObject { +public: +	const char *getName() const { +		return _s("FM-Towns Audio"); +	} + +	const char *getId() const { +		return "towns"; +	} + +	MusicDevices getDevices() const; +	Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; +}; + +MusicDevices TownsEmuMusicPlugin::getDevices() const { +	MusicDevices devices; +	devices.push_back(MusicDevice(this, "", MT_TOWNS)); +	return devices; +} + +Common::Error TownsEmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { +	*mididriver = new MidiDriver_TOWNS(g_system->getMixer()); +	return Common::kNoError; +} + +class PC98EmuMusicPlugin : public MusicPluginObject { +public: +	const char *getName() const { +		return _s("PC-98 Audio"); +	} + +	const char *getId() const { +		return "pc98"; +	} + +	MusicDevices getDevices() const; +	Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; +}; + +MusicDevices PC98EmuMusicPlugin::getDevices() const { +	MusicDevices devices; +	devices.push_back(MusicDevice(this, "", MT_PC98)); +	return devices; +} + +Common::Error PC98EmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { +	//*mididriver = /**/ +	return Common::kNoError; +} + +//#if PLUGIN_ENABLED_DYNAMIC(TOWNS) +	//REGISTER_PLUGIN_DYNAMIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin); +	//REGISTER_PLUGIN_DYNAMIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin); +//#else +	REGISTER_PLUGIN_STATIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin); +	REGISTER_PLUGIN_STATIC(PC98, PLUGIN_TYPE_MUSIC, PC98EmuMusicPlugin); +//#endif diff --git a/audio/softsynth/mt32.cpp b/audio/softsynth/mt32.cpp index 5371be60b3..a9a612f410 100644 --- a/audio/softsynth/mt32.cpp +++ b/audio/softsynth/mt32.cpp @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #include "common/scummsys.h" diff --git a/audio/softsynth/mt32/freeverb.cpp b/audio/softsynth/mt32/freeverb.cpp index c62d4f2cf3..67f065c20e 100644 --- a/audio/softsynth/mt32/freeverb.cpp +++ b/audio/softsynth/mt32/freeverb.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  // Comb filter implementation diff --git a/audio/softsynth/mt32/freeverb.h b/audio/softsynth/mt32/freeverb.h index 8310aca3e3..39ae463970 100644 --- a/audio/softsynth/mt32/freeverb.h +++ b/audio/softsynth/mt32/freeverb.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  // Macro for killing denormalled numbers diff --git a/audio/softsynth/mt32/partial.cpp b/audio/softsynth/mt32/partial.cpp index 5ba9ef6145..d06634dc91 100644 --- a/audio/softsynth/mt32/partial.cpp +++ b/audio/softsynth/mt32/partial.cpp @@ -28,7 +28,7 @@  #if defined(MACOSX) || defined(SOLARIS) || defined(__MINGW32__)  // Older versions of Mac OS X didn't supply a powf function, so using it  // will cause a binary incompatibility when trying to run a binary built -// on a newer OS X release on an olderr one. And Solaris 8 doesn't provide +// on a newer OS X release on an older one. And Solaris 8 doesn't provide  // powf, floorf, fabsf etc. at all.  // Cross-compiled MinGW32 toolchains suffer from a cross-compile bug in  // libstdc++. math/stubs.o should be empty, but it comes with a symbol for diff --git a/audio/softsynth/mt32/synth.cpp b/audio/softsynth/mt32/synth.cpp index 112527cc71..5e74b262ae 100644 --- a/audio/softsynth/mt32/synth.cpp +++ b/audio/softsynth/mt32/synth.cpp @@ -34,7 +34,7 @@  #if defined(MACOSX) || defined(SOLARIS) || defined(__MINGW32__)  // Older versions of Mac OS X didn't supply a powf function, so using it  // will cause a binary incompatibility when trying to run a binary built -// on a newer OS X release on an olderr one. And Solaris 8 doesn't provide +// on a newer OS X release on an older one. And Solaris 8 doesn't provide  // powf, floorf, fabsf etc. at all.  // Cross-compiled MinGW32 toolchains suffer from a cross-compile bug in  // libstdc++. math/stubs.o should be empty, but it comes with a symbol for diff --git a/audio/softsynth/mt32/tables.cpp b/audio/softsynth/mt32/tables.cpp index eba4d2a520..25ee0436db 100644 --- a/audio/softsynth/mt32/tables.cpp +++ b/audio/softsynth/mt32/tables.cpp @@ -19,6 +19,10 @@   * IN THE SOFTWARE.   */ + +// FIXME: Avoid using rand +#define FORBIDDEN_SYMBOL_EXCEPTION_rand +  #include <stdlib.h>  #include <string.h>  #include <math.h> @@ -28,7 +32,7 @@  #if defined(MACOSX) || defined(SOLARIS) || defined(__MINGW32__)  // Older versions of Mac OS X didn't supply a powf function, so using it  // will cause a binary incompatibility when trying to run a binary built -// on a newer OS X release on an olderr one. And Solaris 8 doesn't provide +// on a newer OS X release on an older one. And Solaris 8 doesn't provide  // powf, floorf, fabsf etc. at all.  // Cross-compiled MinGW32 toolchains suffer from a cross-compile bug in  // libstdc++. math/stubs.o should be empty, but it comes with a symbol for diff --git a/audio/softsynth/opl/dosbox.cpp b/audio/softsynth/opl/dosbox.cpp index 7a494d70ec..e039845b8f 100644 --- a/audio/softsynth/opl/dosbox.cpp +++ b/audio/softsynth/opl/dosbox.cpp @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  /* diff --git a/audio/softsynth/opl/dosbox.h b/audio/softsynth/opl/dosbox.h index 1e92c7f7c9..125dde8aec 100644 --- a/audio/softsynth/opl/dosbox.h +++ b/audio/softsynth/opl/dosbox.h @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  /* diff --git a/audio/softsynth/opl/mame.cpp b/audio/softsynth/opl/mame.cpp index 5d790f924f..b380a15345 100644 --- a/audio/softsynth/opl/mame.cpp +++ b/audio/softsynth/opl/mame.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   * LGPL licensed version of MAMEs fmopl (V0.37a modified) by   * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.   */ diff --git a/audio/softsynth/opl/mame.h b/audio/softsynth/opl/mame.h index 4314aa6dba..4c40949483 100644 --- a/audio/softsynth/opl/mame.h +++ b/audio/softsynth/opl/mame.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   * LGPL licensed version of MAMEs fmopl (V0.37a modified) by   * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.   */ diff --git a/audio/softsynth/pcspk.cpp b/audio/softsynth/pcspk.cpp index 947c142b73..66af968463 100644 --- a/audio/softsynth/pcspk.cpp +++ b/audio/softsynth/pcspk.cpp @@ -18,9 +18,6 @@  * along with this program; if not, write to the Free Software  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  * -* $URL$ -* $Id$ -*  */  #include "audio/softsynth/pcspk.h" diff --git a/audio/softsynth/pcspk.h b/audio/softsynth/pcspk.h index 8f01fa852b..3641400b1f 100644 --- a/audio/softsynth/pcspk.h +++ b/audio/softsynth/pcspk.h @@ -17,9 +17,6 @@   * You should have received a copy of the GNU General Public License   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$   */  #ifndef SOUND_SOFTSYNTH_PCSPK_H diff --git a/audio/softsynth/sid.cpp b/audio/softsynth/sid.cpp index 40dc50e972..4b8f783ef4 100644 --- a/audio/softsynth/sid.cpp +++ b/audio/softsynth/sid.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /* diff --git a/audio/softsynth/sid.h b/audio/softsynth/sid.h index d6e402dc3b..a015242844 100644 --- a/audio/softsynth/sid.h +++ b/audio/softsynth/sid.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /* diff --git a/audio/softsynth/wave6581.cpp b/audio/softsynth/wave6581.cpp index d1ddad1623..63e08fb113 100644 --- a/audio/softsynth/wave6581.cpp +++ b/audio/softsynth/wave6581.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  /* diff --git a/audio/softsynth/ym2612.cpp b/audio/softsynth/ym2612.cpp deleted file mode 100644 index 162c92f05a..0000000000 --- a/audio/softsynth/ym2612.cpp +++ /dev/null @@ -1,793 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#include <math.h> - -#include "audio/softsynth/ym2612.h" -#include "common/util.h" -#include "audio/musicplugin.h" -#include "common/error.h" -#include "common/system.h" -#include "common/textconsole.h" -#include "common/translation.h" -#include "common/types.h" - -//////////////////////////////////////// -// -// Miscellaneous -// -//////////////////////////////////////// - -static int *sintbl = 0; -static int *powtbl = 0; -static int *frequencyTable = 0; -static int *keycodeTable = 0; -static int *keyscaleTable = 0; -static int *attackOut = 0; - - -//////////////////////////////////////// -// -// Operator2612 implementation -// -//////////////////////////////////////// - -Operator2612::Operator2612 (Voice2612 *owner) : -	_owner (owner), -	_state (_s_ready), -	_currentLevel ((int32)0x7f << 15), -	_phase (0), -	_lastOutput (0), -	_feedbackLevel (0), -	_detune (0), -	_multiple (1), -	_keyScale (0), -	_specifiedTotalLevel (127), -	_specifiedAttackRate (0), -	_specifiedDecayRate (0), -	_specifiedSustainRate (0), -	_specifiedReleaseRate (15) { -		velocity(0); -} - -Operator2612::~Operator2612() -{ } - -void Operator2612::velocity(int velo) { -	_velocity = velo; -	_totalLevel = ((int32)_specifiedTotalLevel << 15) + -					((int32)(127-_velocity) << 13); -	_sustainLevel = ((int32)_specifiedSustainLevel << 17); -} - -void Operator2612::feedbackLevel(int level) { -	_feedbackLevel = level; -} - -void Operator2612::setInstrument(byte const *instrument) { -	_detune = (instrument[8] >> 4) & 7; -	_multiple = instrument[8] & 15; -	_specifiedTotalLevel = instrument[12] & 127; -	_keyScale = (instrument[16] >> 6) & 3; -	_specifiedAttackRate = instrument[16] & 31; -	_specifiedDecayRate = instrument[20] & 31; -	_specifiedSustainRate = instrument[24] & 31; -	_specifiedSustainLevel = (instrument[28] >> 4) & 15; -	_specifiedReleaseRate = instrument[28] & 15; -	_state = _s_ready; -	velocity(_velocity); -} - -void Operator2612::keyOn() { -	_state = _s_attacking; -	_tickCount = 0; -	_phase = 0; -	_currentLevel = ((int32)0x7f << 15); -} - -void Operator2612::keyOff() { -	if (_state != _s_ready) -		_state = _s_releasing; -} - -void Operator2612::frequency(int freq) { -	double value; // Use for intermediate computations to avoid int64 arithmetic -	int r; - -	_frequency = freq / _owner->_rate; - -	r = _specifiedAttackRate; -	if (r != 0) { -		r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale)); -		if (r >= 64) -		r = 63; -	} - -	r = 63 - r; -	if (_specifiedTotalLevel >= 128) -		value = 0; -	else { -		value = powtbl[(r&3) << 7]; -		value *= 1 << (r >> 2); -		value *= 41; -		value /= 1 << (15 + 5); -		value *= 127 - _specifiedTotalLevel; -		value /= 127; -	} -	_attackTime = (int32) value; // 1 ?? == (1 << 12) -	if (_attackTime > 0) -		_attackTime = (1 << (12+10)) / (_owner->_rate * _attackTime); - -	r = _specifiedDecayRate; -	if (r != 0) { -		r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale)); -		if (r >= 64) -			r = 63; -	} -	value = (double) powtbl[(r&3) << 7] * (0x10 << (r>>2)) / 31; -	_decayRate = (int32) value / _owner->_rate; - -	r = _specifiedSustainRate; -	if (r != 0) { -		r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale)); -		if (r >= 64) -			r = 63; -	} -	value = (double) powtbl[(r&3) << 7] * (0x10 << (r>>2)) / 31; -	_sustainRate = (int32) value / _owner->_rate; - -	r = _specifiedReleaseRate; -	if (r != 0) { -		r = r * 2 + 1;		// (Translated) I cannot know whether the timing is a good choice or not -		r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale)); -		// KS -		if (r >= 64) -			r = 63; -	} -	value = (double) powtbl[(r&3) << 7] * (0x10 << (r>>2)) / 31; -	_releaseRate = (int32) value / _owner->_rate; -} - -void Operator2612::nextTick(const int *phasebuf, int *outbuf, int buflen) { -	if (_state == _s_ready) -		return; -	if (_state == _s_attacking && _attackTime <= 0) { -		_currentLevel = 0; -		_state = _s_decaying; -	} - -	int32 levelIncrement = 0; -	int32 target = 0; -	State next_state = _s_ready; -	const int32 zero_level = ((int32)0x7f << 15); -	const int phaseIncrement = (_multiple > 0) ? (_frequency * _multiple) : (_frequency / 2); - -	int32 output = _lastOutput; -	int32 level = _currentLevel + _totalLevel; - -	while (buflen) { -		switch (_state) { -		case _s_ready: -			return; -		case _s_attacking: -			next_state = _s_attacking; -			break; -		case _s_decaying: -			levelIncrement = _decayRate; -			target = _sustainLevel + _totalLevel; -			next_state = _s_sustaining; -			break; -		case _s_sustaining: -			levelIncrement = _sustainRate; -			target = zero_level + _totalLevel; -			next_state = _s_ready; -			break; -		case _s_releasing: -			levelIncrement = _releaseRate; -			target = zero_level + _totalLevel; -			next_state = _s_ready; -			break; -		} - -		bool switching = false; -		do { -			if (next_state == _s_attacking) { -				// Attack phase -				++_tickCount; -				int i = (int) (_tickCount * _attackTime); -				if (i >= 1024) { -					level = _totalLevel; -					_state = _s_decaying; -					switching = true; -				} else { -					level = (attackOut[i] << (31 - 8 - 16)) + _totalLevel; -				} -			} else { -				// Decay, Sustain and Release phases -				level += levelIncrement; -				if (level >= target) { -					level = target; -					_state = next_state; -					switching = true; -				} -			} - -			if (level < zero_level) { -				int phaseShift = *phasebuf >> 2; -				if (_feedbackLevel) -					phaseShift += (output << (_feedbackLevel - 1)) / 1024; -				output = sintbl[((_phase >> 7) + phaseShift) & 0x7ff]; -				output >>= (level >> 18); -				// Here is the original code, which requires 64-bit ints -//				output *= powtbl[511 - ((level>>25)&511)]; -//				output >>= 16; -//				output >>= 1; -				// And here's our 32-bit trick for doing it. (Props to Fingolfin!) -				// Result varies from original code by max of 1. -//				int powVal = powtbl[511 - ((level>>9)&511)]; -//				int outputHI = output / 256; -//				int powHI = powVal / 256; -//				output = (outputHI * powHI) / 2 + (outputHI * (powVal % 256) + powHI * (output % 256)) / 512; -				// And here's the even faster code. -				// Result varies from original code by max of 8. -				output = ((output >> 4) * (powtbl[511-((level>>9)&511)] >> 3)) / 1024; - -				_phase += phaseIncrement; -				_phase &= 0x3ffff; -			} else -				output = 0; - -			*outbuf += output; -			 --buflen; -			 ++phasebuf; -			 ++outbuf; -		} while (buflen && !switching); -	} -	_lastOutput = output; -	_currentLevel = level - _totalLevel; -} - -//////////////////////////////////////// -// -// Voice2612 implementation -// -//////////////////////////////////////// - -Voice2612::Voice2612() { -	next = 0; -	_control7 = 127; -	_note = 40; -	_frequency = 440; -	_frequencyOffs = 0x2000; -	_algorithm = 7; - -	_buffer = 0; -	_buflen = 0; - -	int i; -	for (i = 0; i < ARRAYSIZE(_opr); ++i) -		_opr[i] = new Operator2612 (this); -	velocity(0); -} - -Voice2612::~Voice2612() { -	int i; -	for (i = 0; i < ARRAYSIZE(_opr); ++i) -		delete _opr[i]; -	free(_buffer); -} - -void Voice2612::velocity(int velo) { -	_velocity = velo; -#if 0 -	int v = (velo * _control7) >> 7; -#else -	int v = velo + (_control7 - 127) * 4; -#endif -	bool iscarrier[8][4] = { -		{ false, false, false,  true, }, //0 -		{ false, false, false,  true, }, //1 -		{ false, false, false,  true, }, //2 -		{ false, false, false,  true, }, //3 -		{ false,  true, false,  true, }, //4 -		{ false,  true,  true,  true, }, //5 -		{ false,  true,  true,  true, }, //6 -		{  true,  true,  true,  true, }, //7 -	}; -	int opr; -	for (opr = 0; opr < 4; opr++) -		if (iscarrier[_algorithm][opr]) -			_opr[opr]->velocity(v); -		else -			_opr[opr]->velocity(127); -} - -void Voice2612::setControlParameter(int control, int value) { -	switch (control) { -	case 7: -		_control7 = value; -		velocity(_velocity); -		break; -	case 123: -		// All notes off -		noteOff(_note); -	}; -} - -void Voice2612::setInstrument(byte const *instrument) { -	if (instrument == NULL) -		return; - -	_algorithm = instrument[32] & 7; -	_opr[0]->feedbackLevel((instrument[32] >> 3) & 7); -	_opr[1]->feedbackLevel(0); -	_opr[2]->feedbackLevel(0); -	_opr[3]->feedbackLevel(0); -	_opr[0]->setInstrument(instrument + 0); -	_opr[1]->setInstrument(instrument + 2); -	_opr[2]->setInstrument(instrument + 1); -	_opr[3]->setInstrument(instrument + 3); -} - -void Voice2612::nextTick(int *outbuf, int buflen) { -	if (_velocity == 0) -		return; - -	if (_buflen < buflen) { -		free(_buffer); -		_buflen = buflen; -		_buffer = (int *) malloc(sizeof(int) * buflen * 2); -	} - -	int *buf1 = _buffer; -	int *buf2 = _buffer + buflen; -	memset(_buffer, 0, sizeof(int) * buflen * 2); - -	switch (_algorithm) { -	case 0: -		_opr[0]->nextTick(buf1, buf2, buflen); -		_opr[1]->nextTick(buf2, buf1, buflen); -		memset (buf2, 0, sizeof (int) * buflen); -		_opr[2]->nextTick(buf1, buf2, buflen); -		_opr[3]->nextTick(buf2, outbuf, buflen); -		break; -	case 1: -		_opr[0]->nextTick(buf1, buf2, buflen); -		_opr[1]->nextTick(buf1, buf2, buflen); -		_opr[2]->nextTick(buf2, buf1, buflen); -		_opr[3]->nextTick(buf1, outbuf, buflen); -		break; -	case 2: -		_opr[1]->nextTick(buf1, buf2, buflen); -		_opr[2]->nextTick(buf2, buf1, buflen); -		memset(buf2, 0, sizeof(int) * buflen); -		_opr[0]->nextTick(buf2, buf1, buflen); -		_opr[3]->nextTick(buf1, outbuf, buflen); -		break; -	case 3: -		_opr[0]->nextTick(buf1, buf2, buflen); -		_opr[1]->nextTick(buf2, buf1, buflen); -		memset(buf2, 0, sizeof(int) * buflen); -		_opr[2]->nextTick(buf2, buf1, buflen); -		_opr[3]->nextTick(buf1, outbuf, buflen); -		break; -	case 4: -		_opr[0]->nextTick(buf1, buf2, buflen); -		_opr[1]->nextTick(buf2, outbuf, buflen); -		_opr[2]->nextTick(buf1, buf1, buflen); -		_opr[3]->nextTick(buf1, outbuf, buflen); -		break; -	case 5: -		_opr[0]->nextTick(buf1, buf2, buflen); -		_opr[1]->nextTick(buf2, outbuf, buflen); -		_opr[2]->nextTick(buf2, outbuf, buflen); -		_opr[3]->nextTick(buf2, outbuf, buflen); -		break; -	case 6: -		_opr[0]->nextTick(buf1, buf2, buflen); -		_opr[1]->nextTick(buf2, outbuf, buflen); -		_opr[2]->nextTick(buf1, outbuf, buflen); -		_opr[3]->nextTick(buf1, outbuf, buflen); -		break; -	case 7: -		_opr[0]->nextTick(buf1, outbuf, buflen); -		_opr[1]->nextTick(buf1, outbuf, buflen); -		_opr[2]->nextTick(buf1, outbuf, buflen); -		_opr[3]->nextTick(buf1, outbuf, buflen); -		break; -	}; -} - -void Voice2612::noteOn(int n, int onVelo) { -	_note = n; -	velocity(onVelo); -	recalculateFrequency(); -	int i; -	for (i = 0; i < ARRAYSIZE(_opr); i++) -		_opr[i]->keyOn(); -} - -bool Voice2612::noteOff(int note) { -	if (_note != note) -		return false; -	int i; -	for (i = 0; i < ARRAYSIZE(_opr); i++) -		_opr[i]->keyOff(); -	return true; -} - -void Voice2612::pitchBend(int value) { -	_frequencyOffs = value; -	recalculateFrequency(); -} - -void Voice2612::recalculateFrequency() { -	// -	// -	// -	int32 basefreq = frequencyTable[_note]; -	int cfreq = frequencyTable[_note - (_note % 12)]; -	int oct = _note / 12; -	int fnum = (int) (((double)basefreq * (1 << 13)) / cfreq); -	fnum += _frequencyOffs - 0x2000; -	if (fnum < 0x2000) { -		fnum += 0x2000; -		oct--; -	} -	if (fnum >= 0x4000) { -		fnum -= 0x2000; -		oct++; -	} - -	// -	_frequency = (int) ((frequencyTable[oct*12] * (double)fnum) / 8); - -	int i; -	for (i = 0; i < ARRAYSIZE(_opr); i++) -		_opr[i]->frequency(_frequency); -} - -//////////////////////////////////////// -// -// MidiChannel_YM2612 -// -//////////////////////////////////////// - -MidiChannel_YM2612::MidiChannel_YM2612() { -	_voices = 0; -	_next_voice = 0; -} - -MidiChannel_YM2612::~MidiChannel_YM2612() { -	removeAllVoices(); -} - -void MidiChannel_YM2612::removeAllVoices() { -	if (!_voices) -		return; -	Voice2612 *last, *voice = _voices; -	for (; voice; voice = last) { -		last = voice->next; -		delete voice; -	} -	_voices = _next_voice = 0; -} - -void MidiChannel_YM2612::noteOn(byte note, byte onVelo) { -	if (!_voices) -		return; -	_next_voice = _next_voice ? _next_voice : _voices; -	_next_voice->noteOn(note, onVelo); -	_next_voice = _next_voice->next; -} - -void MidiChannel_YM2612::noteOff(byte note) { -	if (!_voices) -		return; -	if (_next_voice == _voices) -		_next_voice = 0; -	Voice2612 *voice = _next_voice; -	do { -		if (!voice) -			voice = _voices; -		if (voice->noteOff(note)) { -			_next_voice = voice; -			break; -		} -		voice = voice->next; -	} while (voice != _next_voice); -} - -void MidiChannel_YM2612::controlChange(byte control, byte value) { -	// -	if (control == 121) { -		// Reset controller -		removeAllVoices(); -	} else { -		Voice2612 *voice = _voices; -		for (; voice; voice = voice->next) -			voice->setControlParameter(control, value); -	} -} - -void MidiChannel_YM2612::sysEx_customInstrument(uint32 type, const byte *fmInst) { -	if (type != 'EUP ') -		return; -	Voice2612 *voice = new Voice2612; -	voice->next = _voices; -	_voices = voice; -	voice->_rate = _rate; -	voice->setInstrument(fmInst); -} - -void MidiChannel_YM2612::pitchBend(int16 value) { -  // -	Voice2612 *voice = _voices; -	for (; voice; voice = voice->next) -		voice->pitchBend(value); -} - -void MidiChannel_YM2612::nextTick(int *outbuf, int buflen) { -	Voice2612 *voice = _voices; -	for (; voice; voice = voice->next) -		voice->nextTick(outbuf, buflen); -} - -void MidiChannel_YM2612::rate(uint16 r) { -	_rate = r; -	Voice2612 *voice = _voices; -	for (; voice; voice = voice->next) -		voice->_rate = r; -} - -//////////////////////////////////////// -// -// MidiDriver_YM2612 -// -//////////////////////////////////////// - -MidiDriver_YM2612::MidiDriver_YM2612(Audio::Mixer *mixer) -	: MidiDriver_Emulated(mixer) { -	_next_voice = 0; - -	createLookupTables(); -	_volume = 256; -	int i; -	for (i = 0; i < ARRAYSIZE(_channel); i++) -		_channel[i] = new MidiChannel_YM2612; -	rate(getRate()); -} - -MidiDriver_YM2612::~MidiDriver_YM2612() { -	int i; -	for (i = 0; i < ARRAYSIZE(_channel); i++) -		delete _channel[i]; -	removeLookupTables(); -} - -int MidiDriver_YM2612::open() { -	if (_isOpen) -		return MERR_ALREADY_OPEN; - -	MidiDriver_Emulated::open(); - -	_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); -	return 0; -} - -void MidiDriver_YM2612::close() { -	if (!_isOpen) -		return; -	_isOpen = false; - -	_mixer->stopHandle(_mixerSoundHandle); -} - -void MidiDriver_YM2612::send(uint32 b) { -	send(b & 0xF, b & 0xFFFFFFF0); -} - -void MidiDriver_YM2612::send(byte chan, uint32 b) { -	//byte param3 = (byte) ((b >> 24) & 0xFF); -	byte param2 = (byte) ((b >> 16) & 0xFF); -	byte param1 = (byte) ((b >>  8) & 0xFF); -	byte cmd    = (byte) (b & 0xF0); -	if (chan > ARRAYSIZE(_channel)) -		return; - -	switch (cmd) { -	case 0x80:// Note Off -		_channel[chan]->noteOff(param1); -		break; -	case 0x90: // Note On -		_channel[chan]->noteOn(param1, param2); -		break; -	case 0xA0: // Aftertouch -		break; // Not supported. -	case 0xB0: // Control Change -		_channel[chan]->controlChange(param1, param2); -		break; -	case 0xC0: // Program Change -		_channel[chan]->programChange(param1); -		break; -	case 0xD0: // Channel Pressure -		break; // Not supported. -	case 0xE0: // Pitch Bend -		_channel[chan]->pitchBend((param1 | (param2 << 7)) - 0x2000); -		break; -	case 0xF0: // SysEx -		// We should never get here! SysEx information has to be -		// sent via high-level semantic methods. -		warning("MidiDriver_YM2612: Receiving SysEx command on a send() call"); -		break; - -	default: -		warning("MidiDriver_YM2612: Unknown send() command 0x%02X", cmd); -	} -} - -void MidiDriver_YM2612::sysEx(const byte *msg, uint16 length) { -	if (msg[0] != 0x7C || msg[1] >= ARRAYSIZE(_channel)) -		return; -	_channel[msg[1]]->sysEx_customInstrument('EUP ', &msg[2]); -} - -void MidiDriver_YM2612::generateSamples(int16 *data, int len) { -	memset(data, 0, 2 * sizeof(int16) * len); -	nextTick(data, len); -} - -void MidiDriver_YM2612::nextTick(int16 *buf1, int buflen) { -	int *buf0 = (int *)buf1; - -	int i; -	for (i = 0; i < ARRAYSIZE(_channel); i++) -		_channel[i]->nextTick(buf0, buflen); - -	for (i = 0; i < buflen; ++i) -		buf1[i*2+1] = buf1[i*2] = ((buf0[i] * volume()) >> 10) & 0xffff; -} - -void MidiDriver_YM2612::rate(uint16 r) -{ -	int i; -	for (i = 0; i < ARRAYSIZE(_channel); i++) -		_channel[i]->rate(r); -} - -void MidiDriver_YM2612::createLookupTables() { -	{ -		int i; -		sintbl = new int [2048]; -		for (i = 0; i < 2048; i++) -			sintbl[i] = (int)(0xffff * sin(i/2048.0 * 2.0 * M_PI)); -	} - -	{ -		int i; -		powtbl = new int [1025]; -		for (i = 0; i <= 1024; i++) -			powtbl[i] = (int)(0x10000 * pow(2.0, (i - 512) / 512.0)); -	} - -	{ -		int i; -		int block; - -		static int fnum[] = { -			0x026a, 0x028f, 0x02b6, 0x02df, -			0x030b, 0x0339, 0x036a, 0x039e, -			0x03d5, 0x0410, 0x044e, 0x048f, -		}; - -		// (int)(880.0 * 256.0 * pow(2.0, (note-0x51)/12.0)) -		// -		frequencyTable = new int [120]; -		for (block = -1; block < 9; block++) { -			for (i = 0; i < 12; i++) { -				double freq = fnum[i] * (166400.0 / 3) * pow(2.0, block-21); -				frequencyTable[(block+1)*12+i] = (int)(256.0 * freq); -			} -		} - -		keycodeTable = new int [120]; -		// detune -		for (block = -1; block < 9; block++) { -			for (i = 0; i < 12; i++) { -				// see p.204 -				int  f8 = (fnum[i] >>  7) & 1; -				int  f9 = (fnum[i] >>  8) & 1; -				int f10 = (fnum[i] >>  9) & 1; -				int f11 = (fnum[i] >> 10) & 1; -				int  n4 = f11; -				int  n3 = (f11&(f10|f9|f8)) | (~f11&f10&f9&f8); -				int note = n4*2 + n3; -				// see p.207 -				keycodeTable[(block+1)*12+i] = block*4 + note; -			} -		} -	} - -	{ -		int freq; -		keyscaleTable = new int [8192]; -		keyscaleTable[0] = 0; -		for (freq = 1; freq < 8192; freq++) { -			keyscaleTable[freq] = (int)(log((double)freq) / 9.03 * 32.0) - 1; -			// 8368[Hz] (o9c) -		} -	} - -	{ -		int i; -		attackOut = new int [1024]; -		for (i = 0; i < 1024; i++) -			attackOut[i] = (int)(((0x7fff+0x03a5)*30.0) / (30.0+i)) - 0x03a5; -	} -} - -void MidiDriver_YM2612::removeLookupTables() { -	delete[] sintbl; -	delete[] powtbl; -	delete[] frequencyTable; -	delete[] keycodeTable; -	delete[] keyscaleTable; -	delete[] attackOut; -	sintbl = powtbl = frequencyTable = keycodeTable = keyscaleTable = attackOut = 0; -} - - -// Plugin interface - -class TownsEmuMusicPlugin : public MusicPluginObject { -public: -	const char *getName() const { -		return _s("FM Towns Emulator"); -	} - -	const char *getId() const { -		return "towns"; -	} - -	MusicDevices getDevices() const; -	Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; -}; - -MusicDevices TownsEmuMusicPlugin::getDevices() const { -	MusicDevices devices; -	devices.push_back(MusicDevice(this, "", MT_TOWNS)); -	return devices; -} - -Common::Error TownsEmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { -	*mididriver = new MidiDriver_YM2612(g_system->getMixer()); - -	return Common::kNoError; -} - -//#if PLUGIN_ENABLED_DYNAMIC(TOWNS) -	//REGISTER_PLUGIN_DYNAMIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin); -//#else -	REGISTER_PLUGIN_STATIC(TOWNS, PLUGIN_TYPE_MUSIC, TownsEmuMusicPlugin); -//#endif diff --git a/audio/softsynth/ym2612.h b/audio/softsynth/ym2612.h deleted file mode 100644 index f652b2d9e4..0000000000 --- a/audio/softsynth/ym2612.h +++ /dev/null @@ -1,179 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#ifndef SOUND_SOFTSYNTH_Y2612_H -#define SOUND_SOFTSYNTH_Y2612_H - -#include "common/scummsys.h" - -#include "audio/softsynth/emumidi.h" - -//////////////////////////////////////// -// -// Class declarations -// -//////////////////////////////////////// - -class Voice2612; -class Operator2612 { -protected: -	Voice2612 *_owner; -	enum State { _s_ready, _s_attacking, _s_decaying, _s_sustaining, _s_releasing }; -	State _state; -	int32 _currentLevel; -	int _frequency; -	uint32 _phase; -	int _lastOutput; -	int _feedbackLevel; -	int _detune; -	int _multiple; -	int32 _totalLevel; -	int _keyScale; -	int _velocity; -	int _specifiedTotalLevel; -	int _specifiedAttackRate; -	int _specifiedDecayRate; -	int _specifiedSustainLevel; -	int _specifiedSustainRate; -	int _specifiedReleaseRate; -	int _tickCount; -	int _attackTime; -	int32 _decayRate; -	int32 _sustainLevel; -	int32 _sustainRate; -	int32 _releaseRate; - -public: -	Operator2612 (Voice2612 *owner); -	~Operator2612(); -	void feedbackLevel(int level); -	void setInstrument(byte const *instrument); -	void velocity(int velo); -	void keyOn(); -	void keyOff(); -	void frequency(int freq); -	void nextTick(const int *phaseShift, int *outbuf, int buflen); -	bool inUse() { return (_state != _s_ready); } -}; - -class Voice2612 { -public: -	Voice2612 *next; -	uint16 _rate; - -protected: -	Operator2612 *_opr[4]; -	int _velocity; -	int _control7; -	int _note; -	int _frequencyOffs; -	int _frequency; -	int _algorithm; - -	int *_buffer; -	int _buflen; - -public: -	Voice2612(); -	~Voice2612(); -	void setControlParameter(int control, int value); -	void setInstrument(byte const *instrument); -	void velocity(int velo); -	void nextTick(int *outbuf, int buflen); -	void noteOn(int n, int onVelo); -	bool noteOff(int note); -	void pitchBend(int value); -	void recalculateFrequency(); -}; - -class MidiChannel_YM2612 : public MidiChannel { -protected: -	uint16 _rate; -	Voice2612 *_voices; -	Voice2612 *_next_voice; - -public: -	void removeAllVoices(); -	void nextTick(int *outbuf, int buflen); -	void rate(uint16 r); - -public: -	MidiChannel_YM2612(); -	virtual ~MidiChannel_YM2612(); - -	// MidiChannel interface -	MidiDriver *device() { return 0; } -	byte getNumber() { return 0; } -	void release() { } -	void send(uint32 b) { } -	void noteOff(byte note); -	void noteOn(byte note, byte onVelo); -	void programChange(byte program) { } -	void pitchBend(int16 value); -	void controlChange(byte control, byte value); -	void pitchBendFactor(byte value) { } -	void sysEx_customInstrument(uint32 type, const byte *instr); -}; - -class MidiDriver_YM2612 : public MidiDriver_Emulated { -protected: -	MidiChannel_YM2612 *_channel[16]; - -	int _next_voice; -	int _volume; - -protected: -	void nextTick(int16 *buf1, int buflen); -	int volume(int val = -1) { if (val >= 0) _volume = val; return _volume; } -	void rate(uint16 r); - -	void generateSamples(int16 *buf, int len); - -public: -	MidiDriver_YM2612(Audio::Mixer *mixer); -	virtual ~MidiDriver_YM2612(); - -	static void createLookupTables(); -	static void removeLookupTables(); - -	int open(); -	void close(); -	void send(uint32 b); -	void send(byte channel, uint32 b); // Supports higher than channel 15 -	uint32 property(int prop, uint32 param) { return 0; } - -	void setPitchBendRange(byte channel, uint range) { } -	void sysEx(const byte *msg, uint16 length); - -	MidiChannel *allocateChannel() { return 0; } -	MidiChannel *getPercussionChannel() { return 0; } - - -	// AudioStream API -	bool isStereo() const { return true; } -	int getRate() const { return _mixer->getOutputRate(); } -}; - -#endif - diff --git a/audio/timestamp.cpp b/audio/timestamp.cpp index cdc5bc3a02..69b47d1628 100644 --- a/audio/timestamp.cpp +++ b/audio/timestamp.cpp @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #include "audio/timestamp.h" diff --git a/audio/timestamp.h b/audio/timestamp.h index 4130793fc8..ef095a2106 100644 --- a/audio/timestamp.h +++ b/audio/timestamp.h @@ -18,9 +18,6 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.   * - * $URL$ - * $Id$ - *   */  #ifndef SOUND_TIMESTAMP_H  | 
