[Scummvm-devel] [Scummvm-cvs-logs] SF.net SVN: scummvm:[52198] scummvm/trunk

yotam barnoy yotambarnoy at gmail.com
Sun Aug 22 13:32:03 CEST 2010


MI1 CD w/MP3: intro no longer plays for me after this revision. I get
only a static image of the LucasArts logo. Pressing escape moves to
the next section though.

Yotam


On Thu, Aug 19, 2010 at 12:38 AM,  <athrxx at users.sourceforge.net> wrote:
> Revision: 52198
>          http://scummvm.svn.sourceforge.net/scummvm/?rev=52198&view=rev
> Author:   athrxx
> Date:     2010-08-18 21:38:43 +0000 (Wed, 18 Aug 2010)
>
> Log Message:
> -----------
> SCUMM/FM-TOWNS: start rewriting audio code
>
> - Start rewriting audio code for FM-TOWNS versions of Loom, Indy3 and Monkey Island 1 using the recently added code in towns_audio.cpp (Zak should work the same way, but I can't test, since I don't own that one).
> - All sound types (pcm, euphony and cd audio) now support volume and balance control (e.g. try walking into/out of the kitchen and opening/closing the door in the Scumm Bar in Monkey Island 1 or walking into/out of the circus tent).
> - Pcm sounds now support proper loop start/end and note offsets (e.g. try out the hammer sound in the forge in LOOM for example).
> - some other minor improvements
> - The FM-Towns versions of Indy 4 and Monkey Island 2 are not affected. I don't have Monkey Island 2, but I presume that it will work like Indy 4. Adding support for these will be a separate task, since they work quite differently.
>
> Modified Paths:
> --------------
>    scummvm/trunk/engines/scumm/detection_tables.h
>    scummvm/trunk/engines/scumm/imuse/imuse_player.cpp
>    scummvm/trunk/engines/scumm/module.mk
>    scummvm/trunk/engines/scumm/saveload.cpp
>    scummvm/trunk/engines/scumm/saveload.h
>    scummvm/trunk/engines/scumm/script_v5.cpp
>    scummvm/trunk/engines/scumm/scumm.cpp
>    scummvm/trunk/engines/scumm/scumm.h
>    scummvm/trunk/engines/scumm/sound.cpp
>    scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.cpp
>    scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.h
>    scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
>    scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
>    scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
>
> Added Paths:
> -----------
>    scummvm/trunk/engines/scumm/player_towns.cpp
>    scummvm/trunk/engines/scumm/player_towns.h
>
> Removed Paths:
> -------------
>    scummvm/trunk/engines/scumm/midiparser_eup.cpp
>
> Modified: scummvm/trunk/engines/scumm/detection_tables.h
> ===================================================================
> --- scummvm/trunk/engines/scumm/detection_tables.h      2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/engines/scumm/detection_tables.h      2010-08-18 21:38:43 UTC (rev 52198)
> @@ -186,6 +186,7 @@
>  using Common::GUIO_NOLAUNCHLOAD;
>  using Common::GUIO_NOMIDI;
>  using Common::GUIO_NOSPEECH;
> +using Common::GUIO_MIDITOWNS;
>
>  // The following table contains information about variants of our various
>  // games. We index into it with help of md5table (from scumm-md5.h), to find
> @@ -217,19 +218,19 @@
>
>        {"zak", "V1",       "v1", GID_ZAK, 1, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO_NOSPEECH | GUIO_NOMIDI},
>        {"zak", "V2",       "v2", GID_ZAK, 2, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO_NOSPEECH | GUIO_NOMIDI},
> -       {"zak", "FM-TOWNS",    0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI},
> +       {"zak", "FM-TOWNS",    0, GID_ZAK, 3, 0, MDT_TOWNS, GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI | GUIO_MIDITOWNS},
>
>        {"indy3", "EGA",      "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, 0, UNK, GUIO_NOSPEECH | GUIO_NOMIDI},
>        {"indy3", "No AdLib", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR,             0, UNK, GUIO_NOSPEECH | GUIO_NOMIDI},
>        {"indy3", "VGA",      "vga", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_ADLIB, GF_OLD256 | GF_FEW_LOCALS,                  Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI},
> -       {"indy3", "FM-TOWNS",     0, GID_INDY3, 3, 0, MDT_TOWNS,             GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI},
> +       {"indy3", "FM-TOWNS",     0, GID_INDY3, 3, 0, MDT_TOWNS,             GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI | GUIO_MIDITOWNS},
>
>        {"loom", "EGA",      "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH},
>        {"loom", "No AdLib", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS,                        0, UNK, GUIO_NOSPEECH | GUIO_NOMIDI},
>  #ifdef USE_RGB_COLOR
>        {"loom", "PC-Engine",    0, GID_LOOM, 3, 0, MDT_NONE,                         GF_AUDIOTRACKS | GF_OLD256 | GF_16BIT_COLOR, Common::kPlatformPCEngine, GUIO_NOSPEECH | GUIO_NOMIDI},
>  #endif
> -       {"loom", "FM-TOWNS",     0, GID_LOOM, 3, 0, MDT_TOWNS,                        GF_AUDIOTRACKS | GF_OLD256, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI},
> +       {"loom", "FM-TOWNS",     0, GID_LOOM, 3, 0, MDT_TOWNS,                        GF_AUDIOTRACKS | GF_OLD256, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI | GUIO_MIDITOWNS},
>        {"loom", "VGA",      "vga", GID_LOOM, 4, 0, MDT_NONE,                         GF_AUDIOTRACKS,             Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI},
>
>        {"pass", 0, 0, GID_PASS, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_ADLIB, GF_16COLOR, Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI},
> @@ -239,7 +240,7 @@
>        {"monkey", "No AdLib", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR,                        GF_16COLOR,     Common::kPlatformAtariST, GUIO_NOSPEECH | GUIO_NOMIDI},
>        {"monkey", "Demo",     "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_ADLIB,            GF_16COLOR,     Common::kPlatformPC, GUIO_NOSPEECH | GUIO_NOMIDI},
>        {"monkey", "CD",           0, GID_MONKEY,     5, 0, MDT_ADLIB,                        GF_AUDIOTRACKS, UNK, GUIO_NOSPEECH | GUIO_NOMIDI},
> -       {"monkey", "FM-TOWNS",     0, GID_MONKEY,     5, 0, MDT_ADLIB,                        GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI},
> +       {"monkey", "FM-TOWNS",     0, GID_MONKEY,     5, 0, MDT_TOWNS,                        GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO_NOSPEECH | GUIO_NOMIDI | GUIO_MIDITOWNS},
>        {"monkey", "SEGA",         0, GID_MONKEY,     5, 0, MDT_NONE,                         GF_AUDIOTRACKS, Common::kPlatformSegaCD, GUIO_NOSPEECH | GUIO_NOMIDI},
>
>        {"monkey2",  0, 0, GID_MONKEY2,  5, 0, MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO_NOSPEECH},
>
> Modified: scummvm/trunk/engines/scumm/imuse/imuse_player.cpp
> ===================================================================
> --- scummvm/trunk/engines/scumm/imuse/imuse_player.cpp  2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/engines/scumm/imuse/imuse_player.cpp  2010-08-18 21:38:43 UTC (rev 52198)
> @@ -47,7 +47,6 @@
>  #define PERCUSSION_CHANNEL 9
>
>  extern MidiParser *MidiParser_createRO();
> -extern MidiParser *MidiParser_createEUP();
>
>  uint16 Player::_active_notes[128];
>
> @@ -195,7 +194,11 @@
>                _parser = MidiParser_createRO();
>        } else if (!memcmp(ptr, "SO", 2)) {
>                // Euphony (FM-TOWNS) resource
> -               _parser = MidiParser_createEUP();
> +
> +               //////////// REMOVE
> +               //_parser = MidiParser_createEUP();
> +               ///////////
> +
>        } else if (!memcmp(ptr, "FORM", 4)) {
>                // Humongous Games XMIDI resource
>                _parser = MidiParser::createParser_XMIDI();
>
> Deleted: scummvm/trunk/engines/scumm/midiparser_eup.cpp
> ===================================================================
> --- scummvm/trunk/engines/scumm/midiparser_eup.cpp      2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/engines/scumm/midiparser_eup.cpp      2010-08-18 21:38:43 UTC (rev 52198)
> @@ -1,222 +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 "sound/midiparser.h"
> -#include "sound/mididrv.h"
> -#include "common/util.h"
> -
> -namespace Scumm {
> -
> -/**
> - * The FM-TOWNS Euphony version of MidiParser.
> - */
> -class MidiParser_EUP : public MidiParser {
> -protected:
> -       byte _instruments[6][50]; // Two extra bytes for SysEx ID and channel #
> -       byte *_instr_to_channel;
> -       struct {
> -               byte *enable;
> -               int8 *channel;
> -               int8 *volume;
> -               int8 *transpose;
> -       } _presets;
> -       bool _loop;
> -       byte _presend;     // Tracks which startup implied events have been sent.
> -       uint32 _base_tick; // Events times are relative to this base.
> -
> -protected:
> -       void parseNextEvent (EventInfo &info);
> -       void resetTracking();
> -
> -public:
> -       bool loadMusic (byte *data, uint32 size);
> -};
> -
> -
> -
> -//////////////////////////////////////////////////
> -//
> -// MidiParser_EUP implementation
> -//
> -//////////////////////////////////////////////////
> -
> -void MidiParser_EUP::parseNextEvent (EventInfo &info) {
> -       byte *pos = _position._play_pos;
> -
> -       // FIXME: The presend is for sending init events
> -       // that aren't actually in the stream. This would
> -       // be for, e.g., instrument setup. Right now, we
> -       // don't actually use the instruments specified
> -       // in the music header. We're sending fixed GM
> -       // program changes to get a reasonable "one-size-
> -       // fits-all" sound until we actually support the
> -       // FM synthesis capabilities of FM-TOWNS.
> -       for (; _presend < 12; ++_presend) {
> -               if (_instr_to_channel[_presend >> 1] >= 16)
> -                       continue;
> -               info.start = pos;
> -               info.delta = 0;
> -               if (_presend & 1) {
> -                       byte *data = &_instruments[_presend >> 1][0];
> -                       data[1] = _instr_to_channel[_presend >> 1];
> -                       info.event = 0xF0;
> -                       info.ext.data = data;
> -                       info.length = 48;
> -               } else {
> -                       info.event = 0xB0 | (_presend >> 1);
> -                       info.basic.param1 = 121;
> -                       info.basic.param2 = 0;
> -               }
> -               ++_presend;
> -               return;
> -       }
> -
> -       while (true) {
> -               byte cmd = *pos;
> -               if ((cmd & 0xF0) == 0x90) {
> -                       byte preset = pos[1];
> -                       byte channel = _presets.channel[preset];
> -                       if (channel >= 16)
> -                               channel = cmd & 0x0F;
> -                       uint16 tick = (pos[2] | ((uint16) pos[3] << 7)) + _base_tick;
> -                       int note = (int) pos[4] + _presets.transpose[preset];
> -                       int volume = (int) pos[5];
> -                       // HACK: Loom-Towns distaff tracks seem to
> -                       // contain zero-volume note events, so change
> -                       // those to full volume.
> -                       if (!volume)
> -                               volume = 127;
> -                       volume += _presets.volume[preset];
> -                       if (volume > 127)
> -                               volume = 127;
> -                       else if (volume < 0)
> -                               volume = 0;
> -                       pos += 6;
> -                       if (_presets.enable[preset]) {
> -                               uint16 duration = pos[1] | (pos[2] << 4);
> -                               info.start = pos;
> -                               uint32 last = _position._last_event_tick;
> -                               info.delta = (tick < last) ? 0 : (tick - last);
> -                               info.event = 0x90 | channel;
> -                               info.length = duration;
> -                               info.basic.param1 = note;
> -                               info.basic.param2 = volume;
> -                               pos += 6;
> -                               break;
> -                       }
> -                       pos += 6;
> -               } else if (cmd == 0xF2) {
> -                       // This is a "measure marker" of sorts.
> -                       // It advances the "base time", to which
> -                       // all event times are relative.
> -                       _base_tick += (pos[3] << 7) | pos[2];
> -                       pos += 6;
> -               } else if (cmd == 0xF8) {
> -                       // TODO: Implement this.
> -                       pos += 6;
> -               } else if (cmd == 0xFD || cmd == 0xFE) {
> -                       // End of track.
> -                       if (_loop && false) {
> -                               // TODO: Implement this.
> -                       } else {
> -                               info.start = pos;
> -                               uint32 last = _position._last_event_tick;
> -                               info.delta = (_base_tick < last) ? 0 : (_base_tick - last);
> -                               info.event = 0xFF;
> -                               info.length = 0;
> -                               info.ext.type = 0x2F;
> -                               info.ext.data = pos;
> -                               break;
> -                       }
> -               } else {
> -                       error("Unknown Euphony music event 0x%02X", (int) cmd);
> -                       memset(&info, 0, sizeof(info));
> -                       pos = 0;
> -                       break;
> -               }
> -       }
> -       _position._play_pos = pos;
> -}
> -
> -bool MidiParser_EUP::loadMusic (byte *data, uint32 size) {
> -       unloadMusic();
> -       byte *pos = data;
> -       int i;
> -
> -       if (memcmp(pos, "SO", 2)) {
> -               error("'SO' header expected but found '%c%c' instead.", pos[0], pos[1]);
> -               return false;
> -       }
> -
> -       byte numInstruments = pos[16];
> -       pos += 16 + 2;
> -       for (i = 0; i < numInstruments; ++i) {
> -               _instruments[i][0] = 0x7C;
> -               memcpy (&_instruments[i][2], pos, 48);
> -               pos += 48;
> -       }
> -
> -       // Load the prest pointers
> -       _presets.enable = pos;
> -       pos += 32;
> -       _presets.channel = (int8 *) pos;
> -       pos += 32;
> -       _presets.volume = (int8 *) pos;
> -       pos += 32;
> -       _presets.transpose = (int8 *) pos;
> -       pos += 32;
> -
> -       pos += 8; // Unknown bytes
> -       _instr_to_channel = pos; // Instrument-to-channel mapping
> -       pos += 6;
> -       pos += 4; // Skip the music size for now.
> -       pos++;    // Unknown byte
> -       byte tempo = *pos++;
> -       _loop = (*pos++ != 1);
> -       pos++;    // Unknown byte
> -
> -       _num_tracks = 1;
> -       _ppqn = 120;
> -       _tracks[0] = pos;
> -
> -       // Note that we assume the original data passed in
> -       // will persist beyond this call, i.e. we do NOT
> -       // copy the data to our own buffer. Take warning....
> -       resetTracking();
> -       setTempo (1000000 * 60 / tempo);
> -       setTrack (0);
> -       return true;
> -}
> -
> -void MidiParser_EUP::resetTracking() {
> -       MidiParser::resetTracking();
> -       _presend = 0;
> -       _base_tick = 0;
> -}
> -
> -MidiParser *MidiParser_createEUP() { return new MidiParser_EUP; }
> -
> -} // End of namespace Scumm
>
> Modified: scummvm/trunk/engines/scumm/module.mk
> ===================================================================
> --- scummvm/trunk/engines/scumm/module.mk       2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/engines/scumm/module.mk       2010-08-18 21:38:43 UTC (rev 52198)
> @@ -29,7 +29,6 @@
>        imuse/sysex_samnmax.o \
>        imuse/sysex_scumm.o \
>        input.o \
> -       midiparser_eup.o \
>        midiparser_ro.o \
>        object.o \
>        palette.o \
> @@ -37,6 +36,7 @@
>        player_nes.o \
>        player_pce.o \
>        player_sid.o \
> +       player_towns.o \
>        player_v1.o \
>        player_v2.o \
>        player_v2a.o \
>
> Added: scummvm/trunk/engines/scumm/player_towns.cpp
> ===================================================================
> --- scummvm/trunk/engines/scumm/player_towns.cpp                                (rev 0)
> +++ scummvm/trunk/engines/scumm/player_towns.cpp        2010-08-18 21:38:43 UTC (rev 52198)
> @@ -0,0 +1,557 @@
> +/* 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 "scumm/sound.h"
> +#include "scumm/player_towns.h"
> +
> +namespace Scumm {
> +
> +Player_Towns::Player_Towns(ScummEngine *vm, Audio::Mixer *mixer) : _vm(vm) {
> +       _cdaCurrentSound = _eupCurrentSound = _cdaNumLoops = 0;
> +       _cdaForceRestart = 0;
> +       memset(_pcmCurrentSound, 0, sizeof(_pcmCurrentSound));
> +       _cdaVolLeft = _cdaVolRight = 0;
> +
> +       _eupVolLeft = _eupVolRight = 0;
> +       memset(&_ovrCur, 0, sizeof(SoundOvrParameters));
> +       _soundOverride = 0;
> +
> +       if (_vm->_game.version == 3) {
> +               _soundOverride = new SoundOvrParameters[200];
> +               memset(_soundOverride, 0, 200 * sizeof(SoundOvrParameters));
> +       }
> +
> +       _eupLooping = false;
> +       _unkFlags = 0x33;
> +
> +       _driver = new TownsEuphonyDriver(mixer);
> +}
> +
> +Player_Towns::~Player_Towns() {
> +       delete[] _soundOverride;
> +       delete _driver;
> +}
> +
> +bool Player_Towns::init() {
> +       if (!_driver)
> +               return false;
> +
> +       if (!_driver->init())
> +               return false;
> +
> +       _driver->reserveSoundEffectChannels(8);
> +
> +       // Treat all 6 fm channels and all 8 pcm channels as sound effect channels
> +       // since music seems to exist as CD audio only in the games which use this
> +       // MusicEngine implementation.
> +       _driver->intf()->setSoundEffectChanMask(-1);
> +
> +       setVolumeCD(255, 255);
> +
> +       return true;
> +}
> +
> +void Player_Towns::setMusicVolume(int vol) {
> +       _driver->setMusicVolume(vol);
> +}
> +
> +void Player_Towns::setSfxVolume(int vol) {
> +       _driver->setSoundEffectVolume(vol);
> +}
> +
> +void Player_Towns::startSound(int sound) {
> +       uint8 *ptr = _vm->getResourceAddress(rtSound, sound);
> +       if (_vm->_game.version != 3) {
> +               ptr += 2;
> +       } else if (_soundOverride && sound > 0 && sound < 200) {
> +               memcpy(&_ovrCur, &_soundOverride[sound], sizeof(SoundOvrParameters));
> +               memset(&_soundOverride[sound], 0, sizeof(SoundOvrParameters));
> +       }
> +
> +       int type = ptr[13];
> +
> +       if (type == 0) {
> +               playPcmTrack(sound, ptr + 6);
> +       } else if (type == 1) {
> +               playEuphonyTrack(sound, ptr + 6);
> +       } else if (type == 2) {
> +               playCdaTrack(sound, ptr + 6);
> +       }
> +       memset(&_ovrCur, 0, sizeof(SoundOvrParameters));
> +}
> +
> +void Player_Towns::stopSound(int sound) {
> +       if (sound != 0 && sound == _cdaCurrentSound) {
> +               _cdaCurrentSound = 0;
> +               _vm->_sound->stopCD();
> +               _vm->_sound->stopCDTimer();
> +       }
> +
> +       if (sound != 0 && sound == _eupCurrentSound) {
> +               _eupCurrentSound = 0;
> +               _eupLooping = false;
> +               _driver->stopParser();
> +       }
> +
> +       stopPcmTrack(sound);
> +}
> +
> +void Player_Towns::stopAllSounds() {
> +       _cdaCurrentSound = 0;
> +       _vm->_sound->stopCD();
> +       _vm->_sound->stopCDTimer();
> +
> +       // Loom disasm seems to stop only CD audio and PCM sounds here
> +       /*_eupCurrentSound = 0;
> +       _eupLooping = false;
> +       _driver->stopParser();*/
> +
> +       stopPcmTrack(0);
> +}
> +
> +int Player_Towns::getSoundStatus(int sound) const {
> +       if (sound == _cdaCurrentSound)
> +               return _vm->_sound->pollCD();
> +       if (sound == _eupCurrentSound)
> +               return _driver->parserIsPlaying() ? 1 : 0;
> +       for (int i = 1; i < 9; i++) {
> +               if (_pcmCurrentSound[i].index == sound)
> +                       return _driver->soundEffectIsPlaying(i + 0x3f) ? 1 : 0;
> +       }
> +       return 0;
> +}
> +
> +int32 Player_Towns::doCommand(int numargs, int args[]) {
> +       int32 res = 0;
> +
> +       switch (args[0]) {
> +       case 2:
> +               _driver->intf()->callback(73, 0);
> +               break;
> +
> +       case 3:
> +               restartLoopingSounds();
> +               break;
> +
> +       case 8:
> +               startSound(args[1]);
> +               break;
> +
> +       case 9:
> +               _vm->_sound->stopSound(args[1]);
> +               break;
> +
> +       case 11:
> +               stopPcmTrack(0);
> +               break;
> +
> +       case 14:
> +               startSoundEx(args[1], args[2], args[3], args[4]);
> +               break;
> +
> +       case 15:
> +               stopSoundSuspendLooping(args[1]);
> +               break;
> +
> +       default:
> +               warning("Player_Towns::doCommand: Unknown command %d", args[0]);
> +               break;
> +       }
> +
> +       return res;
> +}
> +
> +void Player_Towns::setVolumeCD(int left, int right) {
> +       _cdaVolLeft = left & 0xff;
> +       _cdaVolRight = right & 0xff;
> +       _driver->setOutputVolume(1, left >> 1, right >> 1);
> +}
> +
> +void Player_Towns::setSoundVolume(int sound, int left, int right) {
> +       if (_soundOverride && sound > 0 && sound < 200) {
> +               _soundOverride[sound].vLeft = left;
> +               _soundOverride[sound].vRight = right;
> +       }
> +}
> +
> +void Player_Towns::setSoundNote(int sound, int note) {
> +       if (_soundOverride && sound > 0 && sound < 200)
> +               _soundOverride[sound].note = note;
> +}
> +
> +void Player_Towns::saveLoadWithSerializer(Serializer *ser) {
> +       _cdaCurrentSoundTemp = (_vm->_sound->pollCD() && _cdaNumLoops > 1) ? _cdaCurrentSound & 0xff : 0;
> +       _cdaNumLoopsTemp = _cdaNumLoops & 0xff;
> +
> +       static const SaveLoadEntry cdEntries[] = {
> +               MKLINE(Player_Towns, _cdaCurrentSoundTemp, sleUint8, VER(81)),
> +               MKLINE(Player_Towns, _cdaNumLoopsTemp, sleUint8, VER(81)),
> +               MKLINE(Player_Towns, _cdaVolLeft, sleUint8, VER(81)),
> +               MKLINE(Player_Towns, _cdaVolRight, sleUint8, VER(81)),
> +               MKEND()
> +       };
> +
> +       ser->saveLoadEntries(this, cdEntries);
> +
> +       if (!_eupLooping && !_driver->parserIsPlaying())
> +               _eupCurrentSound = 0;
> +
> +       static const SaveLoadEntry eupEntries[] = {
> +               MKLINE(Player_Towns, _eupCurrentSound, sleUint8, VER(81)),
> +               MKLINE(Player_Towns, _eupLooping, sleUint8, VER(81)),
> +               MKLINE(Player_Towns, _eupVolLeft, sleUint8, VER(81)),
> +               MKLINE(Player_Towns, _eupVolRight, sleUint8, VER(81)),
> +               MKEND()
> +       };
> +
> +       ser->saveLoadEntries(this, eupEntries);
> +
> +       static const SaveLoadEntry pcmEntries[] = {
> +               MKLINE(PcmCurrentSound, index, sleInt16, VER(81)),
> +               MKLINE(PcmCurrentSound, chan, sleInt16, VER(81)),
> +               MKLINE(PcmCurrentSound, note, sleUint8, VER(81)),
> +               MKLINE(PcmCurrentSound, velo, sleUint8, VER(81)),
> +               MKLINE(PcmCurrentSound, pan, sleUint8, VER(81)),
> +               MKLINE(PcmCurrentSound, paused, sleUint8, VER(81)),
> +               MKLINE(PcmCurrentSound, looping, sleUint8, VER(81)),
> +               MKLINE(PcmCurrentSound, priority, sleUint32, VER(81)),
> +               MKEND()
> +       };
> +
> +       for (int i = 1; i < 9; i++) {
> +               if (!_pcmCurrentSound[i].index)
> +                       continue;
> +
> +               if (_driver->soundEffectIsPlaying(i + 0x3f))
> +                       continue;
> +
> +               _driver->stopSoundEffect(i + 0x3f);
> +
> +               _pcmCurrentSound[i].index = 0;
> +       }
> +
> +       ser->saveLoadArrayOf(_pcmCurrentSound, 9, sizeof(PcmCurrentSound), pcmEntries);
> +}
> +
> +void Player_Towns::restoreAfterLoad() {
> +       setVolumeCD(_cdaVolLeft, _cdaVolRight);
> +
> +       if (_cdaCurrentSoundTemp) {
> +               uint8 *ptr = _vm->getResourceAddress(rtSound, _cdaCurrentSoundTemp) + 6;
> +               if (_vm->_game.version != 3)
> +                       ptr += 2;
> +
> +               if (ptr[7] == 2) {
> +                       playCdaTrack(_cdaCurrentSoundTemp, ptr, true);
> +                       _cdaCurrentSound = _cdaCurrentSoundTemp;
> +                       _cdaNumLoops = _cdaNumLoopsTemp;
> +               }
> +       }
> +
> +       if (_eupCurrentSound) {
> +               uint8 *ptr = _vm->getResourceAddress(rtSound, _eupCurrentSound) + 6;
> +               if (_vm->_game.version != 3)
> +                       ptr += 2;
> +
> +               if (ptr[7] == 1) {
> +                       setSoundVolume(_eupCurrentSound, _eupVolLeft, _eupVolRight);
> +                       playEuphonyTrack(_eupCurrentSound, ptr);
> +               }
> +       }
> +
> +       for (int i = 1; i < 9; i++) {
> +               if (!_pcmCurrentSound[i].index)
> +                       continue;
> +
> +               uint8 *ptr = _vm->getResourceAddress(rtSound, _pcmCurrentSound[i].index);
> +               if (!ptr)
> +                       continue;
> +
> +               if (_vm->_game.version != 3)
> +                       ptr += 2;
> +
> +               if (ptr[13])
> +                       continue;
> +
> +               playPcmTrack(_pcmCurrentSound[i].index, ptr + 6, _pcmCurrentSound[i].velo, _pcmCurrentSound[i].pan, _pcmCurrentSound[i].note);
> +       }
> +}
> +
> +int Player_Towns::getNextFreePcmChannel(int sound, int sfxChanRelIndex) {
> +       int chan = 0;
> +       for (int i = 8; i; i--) {
> +               if (!_pcmCurrentSound[i].index) {
> +                       chan = i;
> +                       continue;
> +               }
> +
> +               if (_driver->soundEffectIsPlaying(i + 0x3f))
> +                       continue;
> +
> +               chan = i;
> +               _vm->_sound->stopSound(_pcmCurrentSound[chan].index);
> +       }
> +
> +       if (!chan) {
> +               uint16 l = 0xffff;
> +               uint8 *ptr = 0;
> +               for (int i = 8; i; i--) {
> +                       ptr = _vm->getResourceAddress(rtSound, _pcmCurrentSound[i].index) + 6;
> +                       uint16 a = READ_LE_UINT16(ptr + 10);
> +                       if (a <= l) {
> +                               chan = i;
> +                               l = a;
> +                       }
> +               }
> +
> +               ptr = _vm->getResourceAddress(rtSound, sound) + 6;
> +               if (l <= READ_LE_UINT16(ptr + 10))
> +                       _vm->_sound->stopSound(_pcmCurrentSound[chan].index);
> +               else
> +                       chan = 0;
> +       }
> +
> +       if (chan) {
> +               _pcmCurrentSound[chan].index = sound;
> +               _pcmCurrentSound[chan].chan = sfxChanRelIndex;
> +       }
> +
> +       return chan;
> +}
> +
> +void Player_Towns::restartLoopingSounds() {
> +       if (_cdaNumLoops && !_cdaForceRestart)
> +               _cdaForceRestart = 1;
> +
> +       for (int i = 1; i < 9; i++) {
> +               if (!_pcmCurrentSound[i].paused)
> +                       continue;
> +
> +               _pcmCurrentSound[i].paused = 0;
> +
> +               uint8 *ptr = _vm->getResourceAddress(rtSound, _pcmCurrentSound[i].index);
> +               if (!ptr)
> +                       continue;
> +               ptr += 24;
> +
> +               int c = 1;
> +               while (_pcmCurrentSound[i].chan != c) {
> +                       ptr = ptr + READ_LE_UINT32(&ptr[12]) + 32;
> +                       c++;
> +               }
> +
> +               _driver->playSoundEffect(i + 0x3f, _pcmCurrentSound[i].note, _pcmCurrentSound[i].velo, ptr);
> +       }
> +
> +       _driver->intf()->callback(73, 1);
> +}
> +
> +void Player_Towns::startSoundEx(int sound, int velo, int pan, int note) {
> +       uint8 *ptr = _vm->getResourceAddress(rtSound, sound) + 2;
> +
> +       if (pan > 99)
> +               pan = 99;
> +
> +       velo = velo ? (velo * ptr[14] + 50) / 100 : ptr[14];
> +       velo = CLIP(velo, 1, 255);
> +
> +       if (ptr[13] == 0) {
> +               velo >>= 1;
> +
> +               if (!velo)
> +                       velo = 1;
> +
> +               pan = pan ? (((pan << 7) - pan) + 50) / 100 : 64;
> +
> +               playPcmTrack(sound, ptr + 6, velo, pan, note);
> +
> +       } else if (ptr[13] == 2) {
> +               int volLeft = velo;
> +               int volRight = velo;
> +
> +               if (pan < 50)
> +                       volRight = ((pan * 2 + 1) * velo + 50) / 100;
> +               else if (pan > 50)
> +                       volLeft = (((99 - pan) * 2 + 1) * velo + 50) / 100;
> +
> +               setVolumeCD(volLeft, volRight);
> +
> +               if (!_cdaForceRestart && sound == _cdaCurrentSound)
> +                       return;
> +
> +               playCdaTrack(sound, ptr + 6, true);
> +       }
> +}
> +
> +void Player_Towns::stopSoundSuspendLooping(int sound) {
> +       if (!sound) {
> +               return;
> +       } else if (sound == _cdaCurrentSound) {
> +               if (_cdaNumLoops && _cdaForceRestart)
> +                       _cdaForceRestart = 1;
> +       } else {
> +               for (int i = 1; i < 9; i++) {
> +                       if (sound == _pcmCurrentSound[i].index) {
> +                               if (!_driver->soundEffectIsPlaying(i + 0x3f))
> +                                       continue;
> +                               _driver->stopSoundEffect(i + 0x3f);
> +                               if (_pcmCurrentSound[i].looping)
> +                                       _pcmCurrentSound[i].paused = 1;
> +                               else
> +                                       _pcmCurrentSound[i].index = 0;
> +                       }
> +               }
> +       }
> +}
> +
> +void Player_Towns::playEuphonyTrack(int sound, const uint8 *data) {
> +       const uint8 *pos = data + 16;
> +       const uint8 *src = pos + data[14] * 48;
> +       const uint8 *trackData = src + 150;
> +
> +       for (int i = 0; i < 32; i++)
> +               _driver->chanEnable(i, *src++);
> +       for (int i = 0; i < 32; i++)
> +               _driver->chanMode(i, 0xff);
> +       for (int i = 0; i < 32; i++)
> +               _driver->chanOrdr(i, *src++);
> +       for (int i = 0; i < 32; i++)
> +               _driver->chanVolumeShift(i, *src++);
> +       for (int i = 0; i < 32; i++)
> +               _driver->chanNoteShift(i, *src++);
> +
> +       src += 8;
> +       for (int i = 0; i < 6; i++)
> +               _driver->assignChannel(i, *src++);
> +
> +       for (int i = 0; i < data[14]; i++) {
> +               _driver->loadInstrument(i, i, pos + i * 48);
> +               _driver->intf()->callback(4, i, i);
> +       }
> +
> +       _eupVolLeft = _ovrCur.vLeft;
> +       _eupVolRight = _ovrCur.vRight;
> +       int lvl = _ovrCur.vLeft + _ovrCur.vRight;
> +       if (!lvl)
> +               lvl = data[8] + data[9];
> +       lvl >>= 2;
> +
> +       for (int i = 0; i < 6; i++)
> +               _driver->chanVolume(i, lvl);
> +
> +       uint32 trackSize = READ_LE_UINT32(src);
> +       src += 4;
> +       uint8 startTick = *src++;
> +
> +       _driver->setMusicTempo(*src++);
> +       _driver->startMusicTrack(trackData, trackSize, startTick);
> +
> +       _eupLooping = (*src != 1) ? 1 : 0;
> +       _driver->setMusicLoop(_eupLooping != 0);
> +       _driver->continueParsing();
> +       _eupCurrentSound = sound;
> +}
> +
> +void Player_Towns::playPcmTrack(int sound, const uint8 *data, int velo, int pan, int note) {
> +       const uint8 *ptr = data;
> +       const uint8 *sfxData = ptr + 16;
> +
> +       int note2, velocity;
> +
> +       if (velo)
> +               velocity = velo;
> +       else if (_ovrCur.vLeft + _ovrCur.vRight)
> +               velocity = (_ovrCur.vLeft + _ovrCur.vRight) >> 2;
> +       else
> +               velocity = ptr[8] >> 1;
> +
> +       int numChan = ptr[14];
> +       for (int i = 0; i < numChan; i++) {
> +               int chan = getNextFreePcmChannel(sound, i);
> +               if (!chan)
> +                       return;
> +
> +               _driver->intf()->callback(70, _unkFlags);
> +               _driver->chanPanPos(chan + 0x3f, pan);
> +
> +               if (note)
> +                       note2 = note;
> +               else if (_ovrCur.note)
> +                       note2 = _ovrCur.note;
> +               else
> +                       note2 = sfxData[28];
> +
> +               _driver->playSoundEffect(chan + 0x3f, note2, velocity, sfxData);
> +
> +               _pcmCurrentSound[chan].note = note2;
> +               _pcmCurrentSound[chan].velo = velocity;
> +               _pcmCurrentSound[chan].pan = pan;
> +               _pcmCurrentSound[chan].paused = 0;
> +               _pcmCurrentSound[chan].looping = READ_LE_UINT32(&sfxData[20]) ? 1 : 0;
> +
> +               sfxData += (READ_LE_UINT32(&sfxData[12]) + 32);
> +       }
> +}
> +
> +void Player_Towns::playCdaTrack(int sound, const uint8 *data, bool skipTrackVelo) {
> +       const uint8 *ptr = data;
> +
> +       if (!sound)
> +               return;
> +
> +       if (!skipTrackVelo) {
> +               if (_ovrCur.vLeft + _ovrCur.vRight)
> +                       setVolumeCD(_ovrCur.vLeft, _ovrCur.vRight);
> +               else
> +                       setVolumeCD(ptr[8], ptr[9]);
> +       }
> +
> +       if (sound == _cdaCurrentSound && _vm->_sound->pollCD() == 1)
> +               return;
> +
> +       ptr += 16;
> +
> +       int track = ptr[0];
> +       _cdaNumLoops = ptr[1];
> +       int start = (ptr[2] * 60 + ptr[3]) * 75 + ptr[4];
> +       int end = (ptr[5] * 60 + ptr[6]) * 75 + ptr[7];
> +
> +       _vm->_sound->playCDTrack(track, _cdaNumLoops == 0xff ? -1 : _cdaNumLoops, start, end <= start ? 0 : end - start);
> +       _cdaForceRestart = 0;
> +       _cdaCurrentSound = sound;
> +}
> +
> +void Player_Towns::stopPcmTrack(int sound) {
> +       for (int i = 1; i < 9; i++) {
> +               if (sound == _pcmCurrentSound[i].index || !sound) {
> +                       _driver->stopSoundEffect(i + 0x3f);
> +                       _pcmCurrentSound[i].index = 0;
> +               }
> +       }
> +}
> +
> +} // End of namespace Scumm
> +
>
>
> Property changes on: scummvm/trunk/engines/scumm/player_towns.cpp
> ___________________________________________________________________
> Added: svn:mime-type
>   + text/plain
> Added: svn:keywords
>   + Date Rev Author URL Id
> Added: svn:eol-style
>   + native
>
> Added: scummvm/trunk/engines/scumm/player_towns.h
> ===================================================================
> --- scummvm/trunk/engines/scumm/player_towns.h                          (rev 0)
> +++ scummvm/trunk/engines/scumm/player_towns.h  2010-08-18 21:38:43 UTC (rev 52198)
> @@ -0,0 +1,120 @@
> +/* 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 SCUMM_PLAYER_TOWNS_H
> +#define SCUMM_PLAYER_TOWNS_H
> +
> +#include "scumm/scumm.h"
> +#include "scumm/music.h"
> +#include "sound/softsynth/fmtowns_pc98/towns_euphony.h"
> +
> +namespace Scumm {
> +
> +class Player_Towns : public MusicEngine {
> +public:
> +       Player_Towns(ScummEngine *vm, Audio::Mixer *mixer);
> +       virtual ~Player_Towns();
> +
> +       bool init();
> +
> +       void setMusicVolume(int vol);
> +       void setSfxVolume(int vol);
> +       void startSound(int sound);
> +       void stopSound(int sound);
> +       void stopAllSounds();
> +
> +       int getSoundStatus(int sound) const;
> +       int getCurrentCdaSound() { return _cdaCurrentSound; }
> +       int getCurrentCdaVolume() { return (_cdaVolLeft + _cdaVolRight + 1) >> 1; }
> +
> +       virtual int32 doCommand(int numargs, int args[]);
> +
> +       void setVolumeCD(int left, int right);
> +       void setSoundVolume(int sound, int left, int right);
> +       void setSoundNote(int sound, int note);
> +
> +       void saveLoadWithSerializer(Serializer *ser);
> +       void restoreAfterLoad();
> +
> +       TownsEuphonyDriver *driver() { return _driver; }
> +
> +protected:
> +       virtual int getNextFreePcmChannel(int sound, int sfxChanRelIndex);
> +
> +private:
> +       void restartLoopingSounds();
> +       void startSoundEx(int sound, int velo, int pan, int note);
> +       void stopSoundSuspendLooping(int sound);
> +
> +       void playEuphonyTrack(int sound, const uint8 *data);
> +       void playPcmTrack(int sound, const uint8 *data, int velo = 0, int pan = 64, int note = 0);
> +       void playCdaTrack(int sound, const uint8 *data, bool skipTrackVelo = false);
> +
> +       void stopPcmTrack(int sound);
> +
> +       uint8 _cdaVolLeft;
> +       uint8 _cdaVolRight;
> +
> +       struct SoundOvrParameters {
> +               uint8 vLeft;
> +               uint8 vRight;
> +               uint8 note;
> +       };
> +
> +       SoundOvrParameters *_soundOverride;
> +       SoundOvrParameters _ovrCur;
> +
> +       uint8 _unkFlags;
> +
> +       struct PcmCurrentSound {
> +               uint16 index;
> +               uint16 chan;
> +               uint8 note;
> +               uint8 velo;
> +               uint8 pan;
> +               uint8 paused;
> +               uint8 looping;
> +               uint32 priority;
> +       } _pcmCurrentSound[9];
> +
> +       uint8 _eupCurrentSound;
> +       uint8 _eupLooping;
> +       uint8 _eupVolLeft;
> +       uint8 _eupVolRight;
> +
> +       uint8 _cdaCurrentSound;
> +       uint8 _cdaNumLoops;
> +       uint8 _cdaForceRestart;
> +
> +       uint8 _cdaCurrentSoundTemp;
> +       uint8 _cdaNumLoopsTemp;
> +
> +       TownsEuphonyDriver *_driver;
> +       ScummEngine *_vm;
> +};
> +
> +} // End of namespace Scumm
> +
> +#endif
>
>
> Property changes on: scummvm/trunk/engines/scumm/player_towns.h
> ___________________________________________________________________
> Added: svn:mime-type
>   + text/plain
> Added: svn:keywords
>   + Date Rev Author URL Id
> Added: svn:eol-style
>   + native
>
> Modified: scummvm/trunk/engines/scumm/saveload.cpp
> ===================================================================
> --- scummvm/trunk/engines/scumm/saveload.cpp    2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/engines/scumm/saveload.cpp    2010-08-18 21:38:43 UTC (rev 52198)
> @@ -32,6 +32,7 @@
>  #include "scumm/charset.h"
>  #include "scumm/imuse_digi/dimuse.h"
>  #include "scumm/imuse/imuse.h"
> +#include "player_towns.h"
>  #include "scumm/he/intern_he.h"
>  #include "scumm/object.h"
>  #include "scumm/resource.h"
> @@ -447,6 +448,9 @@
>        // Update volume settings
>        syncSoundSettings();
>
> +       if (_townsPlayer && (hdr.ver >= VER(81)))
> +               _townsPlayer->restoreAfterLoad();
> +
>        // Init NES costume data
>        if (_game.platform == Common::kPlatformNES) {
>                if (hdr.ver < VER(47))
> @@ -1394,6 +1398,11 @@
>                _imuse->save_or_load(s, this);
>        }
>
> +
> +       // Save/load FM-Towns audio status
> +       if (_townsPlayer)
> +               _townsPlayer->saveLoadWithSerializer(s);
> +
>        //
>        // Save/load the charset renderer state
>        //
>
> Modified: scummvm/trunk/engines/scumm/saveload.h
> ===================================================================
> --- scummvm/trunk/engines/scumm/saveload.h      2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/engines/scumm/saveload.h      2010-08-18 21:38:43 UTC (rev 52198)
> @@ -50,7 +50,7 @@
>  * only saves/loads those which are valid for the version of the savegame
>  * which is being loaded/saved currently.
>  */
> -#define CURRENT_VER 80
> +#define CURRENT_VER 81
>
>  /**
>  * An auxillary macro, used to specify savegame versions. We use this instead
>
> Modified: scummvm/trunk/engines/scumm/script_v5.cpp
> ===================================================================
> --- scummvm/trunk/engines/scumm/script_v5.cpp   2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/engines/scumm/script_v5.cpp   2010-08-18 21:38:43 UTC (rev 52198)
> @@ -29,6 +29,7 @@
>  #include "scumm/scumm_v3.h"
>  #include "scumm/scumm_v5.h"
>  #include "scumm/sound.h"
> +#include "scumm/player_towns.h"
>  #include "scumm/util.h"
>  #include "scumm/verbs.h"
>
> @@ -1595,21 +1596,18 @@
>                debug(0, "o5_resourceRoutines %d not yet handled (script %d)", op, vm.slot[_currentScript].number);
>                break;
>        case 35:
> -               // TODO: Might be used to set CD volume in FM-TOWNS Loom
> -               foo = getVarOrDirectByte(PARAM_2);
> -               debug(0, "o5_resourceRoutines %d not yet handled (script %d)", op, vm.slot[_currentScript].number);
> +               if (_townsPlayer)
> +                       _townsPlayer->setVolumeCD(getVarOrDirectByte(PARAM_2), resid);
>                break;
>        case 36:
> -               // TODO: Sets the loudness of a sound resource. Used in Indy3 and Zak.
>                foo = getVarOrDirectByte(PARAM_2);
>                bar = fetchScriptByte();
> -               debug(0, "o5_resourceRoutines %d not yet handled (script %d)", op, vm.slot[_currentScript].number);
> +               if (_townsPlayer)
> +                       _townsPlayer->setSoundVolume(resid, foo, bar);
>                break;
>        case 37:
> -               // TODO: Sets the pitch of a sound resource (pitch = foo - center semitones.
> -               // "center" is at 0x32 in the sfx resource (always 0x3C in zak256, but sometimes different in Indy3).
> -               foo = getVarOrDirectByte(PARAM_2);
> -               debug(0, "o5_resourceRoutines %d not yet handled (script %d)", op, vm.slot[_currentScript].number);
> +               if (_townsPlayer)
> +                       _townsPlayer->setSoundNote(resid, getVarOrDirectByte(PARAM_2));
>                break;
>
>        default:
> @@ -1981,6 +1979,7 @@
>                        break;
>                case 0xFF:
>                        // TODO: Might return current CD volume in FM-TOWNS Loom. See also bug #805691.
> +                       result = _townsPlayer->getCurrentCdaVolume();
>                        break;
>                default:
>                        // TODO: return track length in seconds. We'll have to extend Sound and OSystem for this.
>
> Modified: scummvm/trunk/engines/scumm/scumm.cpp
> ===================================================================
> --- scummvm/trunk/engines/scumm/scumm.cpp       2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/engines/scumm/scumm.cpp       2010-08-18 21:38:43 UTC (rev 52198)
> @@ -48,6 +48,7 @@
>  #include "scumm/imuse_digi/dimuse.h"
>  #include "scumm/smush/smush_mixer.h"
>  #include "scumm/smush/smush_player.h"
> +#include "scumm/player_towns.h"
>  #include "scumm/insane/insane.h"
>  #include "scumm/he/animation_he.h"
>  #include "scumm/he/intern_he.h"
> @@ -146,6 +147,7 @@
>        _imuse = NULL;
>        _imuseDigital = NULL;
>        _musicEngine = NULL;
> +       _townsPlayer = NULL;
>        _verbs = NULL;
>        _objs = NULL;
>        _sound = NULL;
> @@ -1757,6 +1759,10 @@
>                _musicEngine = new Player_V2CMS(this, _mixer);
>        } else if (_game.platform == Common::kPlatform3DO && _game.heversion <= 62) {
>                // 3DO versions use digital music and sound samples.
> +       } else if (_game.platform == Common::kPlatformFMTowns && (_game.version == 3 || _game.id == GID_MONKEY)) {
> +               _musicEngine = _townsPlayer = new Player_Towns(this, _mixer);
> +               if (!_townsPlayer->init())
> +                       error("Failed to initialize FM-Towns audio driver.");
>        } else if (_game.version >= 3 && _game.heversion <= 62) {
>                MidiDriver *nativeMidiDriver = 0;
>                MidiDriver *adlibMidiDriver = 0;
> @@ -1806,6 +1812,10 @@
>                _musicEngine->setMusicVolume(soundVolumeMusic);
>        }
>
> +       if (_townsPlayer) {
> +               _townsPlayer->setSfxVolume(soundVolumeSfx);
> +       }
> +
>        _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, soundVolumeSfx);
>        _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, soundVolumeMusic);
>        _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, soundVolumeSpeech);
>
> Modified: scummvm/trunk/engines/scumm/scumm.h
> ===================================================================
> --- scummvm/trunk/engines/scumm/scumm.h 2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/engines/scumm/scumm.h 2010-08-18 21:38:43 UTC (rev 52198)
> @@ -70,6 +70,7 @@
>  class IMuse;
>  class IMuseDigital;
>  class MusicEngine;
> +class Player_Towns;
>  class ScummEngine;
>  class ScummDebugger;
>  class Serializer;
> @@ -426,6 +427,7 @@
>        IMuse *_imuse;
>        IMuseDigital *_imuseDigital;
>        MusicEngine *_musicEngine;
> +       Player_Towns *_townsPlayer;
>        Sound *_sound;
>
>        VerbSlot *_verbs;
>
> Modified: scummvm/trunk/engines/scumm/sound.cpp
> ===================================================================
> --- scummvm/trunk/engines/scumm/sound.cpp       2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/engines/scumm/sound.cpp       2010-08-18 21:38:43 UTC (rev 52198)
> @@ -31,6 +31,7 @@
>  #include "scumm/file.h"
>  #include "scumm/imuse/imuse.h"
>  #include "scumm/imuse_digi/dimuse.h"
> +#include "scumm/player_towns.h"
>  #include "scumm/scumm.h"
>  #include "scumm/sound.h"
>  #include "scumm/util.h"
> @@ -150,9 +151,10 @@
>                                                data[0] >> 8, data[0] & 0xFF,
>                                                data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
>
> -                       if (_vm->_imuse) {
> +                       if (_vm->_townsPlayer)
> +                               _vm->VAR(_vm->VAR_SOUNDRESULT) = (short)_vm->_townsPlayer->doCommand(num, data);
> +                       else if (_vm->_imuse)
>                                _vm->VAR(_vm->VAR_SOUNDRESULT) = (short)_vm->_imuse->doCommand(num, data);
> -                       }
>                }
>        }
>        _soundQuePos = 0;
> @@ -312,91 +314,6 @@
>                stream = Audio::makeRawStream(sound, size, rate, Audio::FLAG_UNSIGNED);
>                _mixer->playStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID);
>        }
> -       else if ((_vm->_game.platform == Common::kPlatformFMTowns && _vm->_game.version == 3) || READ_BE_UINT32(ptr) == MKID_BE('SOUN') || READ_BE_UINT32(ptr) == MKID_BE('TOWS')) {
> -
> -               bool tows = READ_BE_UINT32(ptr) == MKID_BE('TOWS');
> -               if (_vm->_game.version == 3) {
> -                       size = READ_LE_UINT32(ptr);
> -               } else {
> -                       size = READ_BE_UINT32(ptr + 4) - 2;
> -                       if (tows)
> -                               size += 8;
> -                       ptr += 2;
> -               }
> -
> -               rate = 11025;
> -               int type = *(ptr + 0x0D);
> -               int numInstruments;
> -
> -               if (tows)
> -                       type = 0;
> -
> -               switch (type) {
> -               case 0: // Sound effect
> -                       numInstruments = *(ptr + 0x14);
> -                       if (tows)
> -                               numInstruments = 1;
> -                       ptr += 0x16;
> -                       size -= 0x16;
> -
> -                       while (numInstruments--) {
> -                               int waveSize = READ_LE_UINT32(ptr + 0x0C);
> -                               int loopStart = READ_LE_UINT32(ptr + 0x10) * 2;
> -                               int loopEnd = READ_LE_UINT32(ptr + 0x14) - 1;
> -                               rate = READ_LE_UINT32(ptr + 0x18) * 1000 / 0x62;
> -                               ptr += 0x20;
> -                               size -= 0x20;
> -                               if (size < waveSize) {
> -                                       warning("Wrong wave size in sound #%i: %i", soundID, waveSize);
> -                                       waveSize = size;
> -                               }
> -                               sound = (byte *)malloc(waveSize);
> -                               for (int x = 0; x < waveSize; x++) {
> -                                       byte b = *ptr++;
> -                                       if (b < 0x80)
> -                                               sound[x] = 0x7F - b;
> -                                       else
> -                                               sound[x] = b;
> -                               }
> -                               size -= waveSize;
> -
> -                               if (loopEnd > 0) {
> -                                       Audio::SeekableAudioStream *s = Audio::makeRawStream(sound, waveSize, rate, Audio::FLAG_UNSIGNED);
> -                                       stream = new Audio::SubLoopingAudioStream(s, 0, Audio::Timestamp(0, loopStart, rate), Audio::Timestamp(0, loopEnd, rate));
> -                               } else {
> -                                       stream = Audio::makeRawStream(sound, waveSize, rate, Audio::FLAG_UNSIGNED);
> -                               }
> -                               _mixer->playStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID, 255, 0);
> -                       }
> -                       break;
> -               case 1:
> -                       // Music (Euphony format)
> -                       if (_vm->_musicEngine)
> -                               _vm->_musicEngine->startSound(soundID);
> -                       break;
> -               case 2: // CD track resource
> -                       ptr += 0x16;
> -
> -                       if (soundID == _currentCDSound && pollCD() == 1) {
> -                               return;
> -                       }
> -
> -                       {
> -                               int track = ptr[0];
> -                               int loops = ptr[1];
> -                               int start = (ptr[2] * 60 + ptr[3]) * 75 + ptr[4];
> -                               int end = (ptr[5] * 60 + ptr[6]) * 75 + ptr[7];
> -
> -                               playCDTrack(track, loops == 0xff ? -1 : loops, start, end <= start ? 0 : end - start);
> -                       }
> -
> -                       _currentCDSound = soundID;
> -                       break;
> -               default:
> -                       // All other sound types are ignored
> -                       break;
> -               }
> -       }
>        else if ((_vm->_game.id == GID_LOOM) && (_vm->_game.platform == Common::kPlatformMacintosh))  {
>                // Mac version of Loom uses yet another sound format
>                /*
> @@ -480,6 +397,9 @@
>                if (_vm->_musicEngine) {
>                        _vm->_musicEngine->startSound(soundID);
>                }
> +
> +               if (_vm->_townsPlayer)
> +                       _currentCDSound = _vm->_townsPlayer->getCurrentCdaSound();
>        }
>  }
>
>
> Modified: scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.cpp
> ===================================================================
> --- scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.cpp  2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.cpp  2010-08-18 21:38:43 UTC (rev 52198)
> @@ -200,9 +200,9 @@
>                INTCB(notImpl),
>                // 72
>                INTCB(notImpl),
> +               INTCB(cdaToggle),
>                INTCB(notImpl),
>                INTCB(notImpl),
> -               INTCB(notImpl),
>                // 76
>                INTCB(notImpl),
>                INTCB(notImpl),
> @@ -222,9 +222,19 @@
>
>        _timerBase = (uint32)(_baserate * 1000000.0f);
>        _tickLength = 2 * _timerBase;
> +
> +       setTimerCallbackA((ChipTimerProc)&TownsAudioInterface::timerCallbackA);
> +       setTimerCallbackB((ChipTimerProc)&TownsAudioInterface::timerCallbackB);
>  }
>
>  TownsAudioInterface::~TownsAudioInterface() {
> +       Common::StackLock lock(_mutex);
> +       reset();
> +       _ready = false;
> +
> +       setTimerCallbackA();
> +       setTimerCallbackB();
> +
>        delete[] _fmSaveReg[0];
>        delete[] _fmSaveReg[1];
>        delete[] _fmInstruments;
> @@ -759,6 +769,12 @@
>        return 0;
>  }
>
> +int TownsAudioInterface::intf_cdaToggle(va_list &args) {
> +       //int mode = va_arg(args, int);
> +       //_unkMask = mode ? 0x7f : 0x3f;
> +       return 0;
> +}
> +
>  int TownsAudioInterface::intf_pcmUpdateEnvelopeGenerator(va_list &args) {
>        for (int i = 0; i < 8; i++)
>                pcmUpdateEnvelopeGenerator(i);
>
> Modified: scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.h
> ===================================================================
> --- scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.h    2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_audio.h    2010-08-18 21:38:43 UTC (rev 52198)
> @@ -95,6 +95,7 @@
>        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);
>
> Modified: scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp
> ===================================================================
> --- scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp    2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_driver.cpp    2010-08-18 21:38:43 UTC (rev 52198)
> @@ -1037,11 +1037,21 @@
>        _musicPlaying(false), _sfxPlaying(false), _fading(false), _looping(0), _ready(false) {
>
>        _sfxOffsets[0] = _sfxOffsets[1] = 0;
> +
> +       setTimerCallbackA((ChipTimerProc)&TownsPC98_AudioDriver::timerCallbackA);
> +       setTimerCallbackB((ChipTimerProc)&TownsPC98_AudioDriver::timerCallbackB);
>  }
>
>  TownsPC98_AudioDriver::~TownsPC98_AudioDriver() {
> +       Common::StackLock lock(_mutex);
> +
>        reset();
>
> +       _ready = false;
> +
> +       setTimerCallbackA();
> +       setTimerCallbackB();
> +
>        if (_channels) {
>                for (int i = 0; i < _numChan; i++)
>                        delete _channels[i];
>
> Modified: scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp
> ===================================================================
> --- scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp   2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.cpp   2010-08-18 21:38:43 UTC (rev 52198)
> @@ -835,6 +835,7 @@
>
>        memset(&_timers[0], 0, sizeof(ChipTimer));
>        memset(&_timers[1], 0, sizeof(ChipTimer));
> +
>        _timers[0].cb = &TownsPC98_FmSynth::timerCallbackA;
>        _timers[1].cb = &TownsPC98_FmSynth::timerCallbackB;
>        _timerbase = (uint32)(_baserate * 1000000.0f);
> @@ -842,6 +843,9 @@
>
>  TownsPC98_FmSynth::~TownsPC98_FmSynth() {
>        Common::StackLock lock(_mutex);
> +
> +       _ready = false;
> +
>        _mixer->stopHandle(_soundHandle);
>        delete _ssg;
>        delete _prc;
> @@ -1154,6 +1158,14 @@
>        return numSamples;
>  }
>
> +void TownsPC98_FmSynth::setTimerCallbackA(ChipTimerProc proc) {
> +       _timers[0].cb = proc;
> +}
> +
> +void TownsPC98_FmSynth::setTimerCallbackB(ChipTimerProc proc) {
> +       _timers[1].cb = proc;
> +}
> +
>  uint8 TownsPC98_FmSynth::readSSGStatus() {
>        return _ssg->chanEnable();
>  }
>
> Modified: scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h
> ===================================================================
> --- scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h     2010-08-18 20:41:03 UTC (rev 52197)
> +++ scummvm/trunk/sound/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h     2010-08-18 21:38:43 UTC (rev 52198)
> @@ -71,6 +71,10 @@
>        }
>
>  protected:
> +       typedef void (TownsPC98_FmSynth::*ChipTimerProc)();
> +       void setTimerCallbackA(ChipTimerProc proc = &TownsPC98_FmSynth::timerCallbackA);
> +       void setTimerCallbackB(ChipTimerProc proc = &TownsPC98_FmSynth::timerCallbackB);
> +
>        // Implement this in your inherited class if your driver generates
>        // additional output that has to be inserted into the buffer.
>        virtual void nextTickEx(int32 *buffer, uint32 bufferSize) {}
> @@ -80,8 +84,8 @@
>        }
>        uint8 readSSGStatus();
>
> -       virtual void timerCallbackA() = 0;
> -       virtual void timerCallbackB() = 0;
> +       virtual void timerCallbackA() {}
> +       virtual void timerCallbackB() {}
>
>        // The audio driver can store and apply two different audio settings
>        // (usually for music and sound effects). The channel mask will determine
> @@ -139,8 +143,6 @@
>
>        bool _regProtectionFlag;
>
> -       typedef void (TownsPC98_FmSynth::*ChipTimerProc)();
> -
>        struct ChipTimer {
>                bool enabled;
>                uint16 value;
>
>
> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
>
> ------------------------------------------------------------------------------
> This SF.net email is sponsored by
>
> Make an app they can't live without
> Enter the BlackBerry Developer Challenge
> http://p.sf.net/sfu/RIM-dev2dev
> _______________________________________________
> Scummvm-cvs-logs mailing list
> Scummvm-cvs-logs at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/scummvm-cvs-logs
>




More information about the Scummvm-devel mailing list