diff options
Diffstat (limited to 'scumm')
-rw-r--r-- | scumm/player_v2a.cpp | 48 | ||||
-rw-r--r-- | scumm/player_v3a.cpp | 15 | ||||
-rw-r--r-- | scumm/player_v3a.h | 4 |
3 files changed, 62 insertions, 5 deletions
diff --git a/scumm/player_v2a.cpp b/scumm/player_v2a.cpp index 708dbdcbda..3d8a5eb25b 100644 --- a/scumm/player_v2a.cpp +++ b/scumm/player_v2a.cpp @@ -986,6 +986,52 @@ private: int _ticks; }; +class V2A_Sound_Special_SteppedPitchbendAndHold : public V2A_Sound_Base<1> { +public: + V2A_Sound_Special_SteppedPitchbendAndHold(uint16 offset, uint16 size, uint16 freq1, uint16 freq2, uint8 vol) : + V2A_Sound_Base<1>(offset, size), _freq1(freq1), _freq2(freq2), _vol(vol) { } + virtual void start(Player_MOD *mod, int id, const byte *data) { + _mod = mod; + _id = id; + char *tmp_data = (char *)malloc(_size); + memcpy(tmp_data, data + _offset, _size); + _curfreq = _freq1; + _mod->startChannel(_id, tmp_data, _size, BASE_FREQUENCY / _curfreq, (_vol << 2) | (_vol >> 4), 0, _size); + _bendrate = 8; + _bendctr = 100; + _holdctr = 30; + } + virtual bool update() { + assert(_id); + if (_curfreq >= _freq2) + { + _mod->setChannelFreq(_id, BASE_FREQUENCY / _curfreq); + _curfreq -= _bendrate; + if (--_bendctr) + return true; + _bendrate--; + if (_bendrate < 2) + _bendrate = 2; + } + else + { + if (!--_holdctr) + return false; + } + return true; + } +private: + const uint16 _freq1; + const uint16 _freq2; + const uint16 _vol; + + uint16 _curfreq; + uint16 _bendrate; + uint16 _bendctr; + uint16 _holdctr; + +}; + #define CRCToSound(CRC, SOUND) \ if (crc == CRC) \ return new SOUND @@ -1078,7 +1124,7 @@ static V2A_Sound *findSound (unsigned long crc) { CRCToSound(0x5AE9D6A7, V2A_Sound_Special_SlowPitchbendThenSlowFadeout(0x00CA,0x22A4,0x0113,0x0227)); // Zak 109 CRCToSound(0xABE0D3B0, V2A_Sound_Special_SlowPitchbendThenSlowFadeout(0x00CE,0x22A4,0x0227,0x0113)); // Zak 105 CRCToSound(0x788CC749, V2A_Sound_Unsupported()); // Zak 71 - CRCToSound(0x2E2AB1FA, V2A_Sound_Unsupported()); // Zak 99 + CRCToSound(0x2E2AB1FA, V2A_Sound_Special_SteppedPitchbendAndHold(0x00D4,0x04F0,0x0FE3,0x0080,0x3F)); // Zak 99 CRCToSound(0x1304CF20, V2A_Sound_Special_SingleDurationMultiDurations(0x00DC,0x0624,0x023C,0x3C,2,(const uint8 *)"\x14\x11",false)); // Zak 79 CRCToSound(0xAE68ED91, V2A_Sound_Unsupported()); // Zak 54 CRCToSound(0xA4F40F97, V2A_Sound_Unsupported()); // Zak 61 diff --git a/scumm/player_v3a.cpp b/scumm/player_v3a.cpp index 865e676c2a..b24688977d 100644 --- a/scumm/player_v3a.cpp +++ b/scumm/player_v3a.cpp @@ -232,6 +232,11 @@ void Player_V3A::startSound(int nr) { looped = true; } int i = getSfxChan(); + if (i == -1) + { + free(sound); + return; + } _sfx[i].id = nr; _sfx[i].dur = looped ? -1 : (1 + 60 * size / rate); if ((_scumm->_gameId == GID_INDY3) && (nr == 60)) @@ -270,7 +275,7 @@ void Player_V3A::playMusic() { return; if (_songDelay && --_songDelay) return; - if (((_songData[_songPtr] & 0xF0) != 0x80) && (_songData[_songPtr] != 0xFB)) { + if (_songPtr == 0) { // at the end of the song, and it wasn't looped - kill it _curSong = 0; return; @@ -287,6 +292,7 @@ void Player_V3A::playMusic() { } if (inst == 0xFB) // it's a looped song, restart it afterwards _songPtr = 0x1C; + else _songPtr = 0; // otherwise, terminate it break; } inst &= 0xF; @@ -312,8 +318,13 @@ void Player_V3A::playMusic() { memcpy(data + _wavetable[inst]->_ilen[oct], _wavetable[inst]->_ldat[oct], _wavetable[inst]->_llen[oct]); i = getMusChan(); + if (i == -1) + { + free(data); + return; + } _mus[i].id = i + 1; - _mus[i].dur = dur; + _mus[i].dur = dur + 1; _mod->startChannel(_mus[i].id, data, _wavetable[inst]->_ilen[oct] + _wavetable[inst]->_llen[oct], rate, vol, _wavetable[inst]->_ilen[oct], _wavetable[inst]->_ilen[oct] + _wavetable[inst]->_llen[oct]); } diff --git a/scumm/player_v3a.h b/scumm/player_v3a.h index 9d47791e19..c15ec118c1 100644 --- a/scumm/player_v3a.h +++ b/scumm/player_v3a.h @@ -51,8 +51,8 @@ public: private: enum { - V3A_MAXMUS = 8, - V3A_MAXSFX = 8 + V3A_MAXMUS = 16, + V3A_MAXSFX = 16 }; struct musChan { |