diff options
-rw-r--r-- | scumm/player_v1.cpp | 18 | ||||
-rw-r--r-- | scumm/player_v1.h | 2 | ||||
-rw-r--r-- | scumm/player_v2.cpp | 23 | ||||
-rw-r--r-- | scumm/player_v2.h | 2 |
4 files changed, 28 insertions, 17 deletions
diff --git a/scumm/player_v1.cpp b/scumm/player_v1.cpp index 57288ae2a5..549742aab3 100644 --- a/scumm/player_v1.cpp +++ b/scumm/player_v1.cpp @@ -179,6 +179,7 @@ void Player_V1::parseSpeakerChunk() { _delta = (int16) READ_LE_UINT16(_next_chunk + 4); _channels[0].freq = 0; _next_chunk += 6; + _forced_level = -1; debug(6, "chunk 2: %d -> %d step %d", _start, _end, _delta); break; @@ -188,6 +189,7 @@ void Player_V1::parseSpeakerChunk() { _delta = (int16) READ_LE_UINT16(_next_chunk + 4); _channels[0].freq = 0; _next_chunk += 6; + _forced_level = -1; debug(6, "chunk 3: %d -> %d step %d", _start, _end, _delta); break; @@ -237,7 +239,7 @@ void Player_V1::nextSpeakerCmd() { return; } set_mplex(_start); - _forced_level ^= 1; + _forced_level = -_forced_level; break; case 3: _start = (_start + _delta) & 0xffff; @@ -249,7 +251,7 @@ void Player_V1::nextSpeakerCmd() { lsr = (lsr >> 3) | (lsr << 13); _random_lsr = lsr; set_mplex((_start & lsr) | 0x180); - _forced_level ^= 1; + _forced_level = -_forced_level; break; } } @@ -310,7 +312,8 @@ void Player_V1::parsePCjrChunk() { _channels[i].cmd_ptr = _current_data + tmp + 10; } break; - case 1: /* FIXME: implement! */ + + case 1: set_mplex(READ_LE_UINT16(_next_chunk)); tmp = READ_LE_UINT16(_next_chunk + 2); _channels[0].cmd_ptr = tmp != 0xffff ? _current_data + tmp : NULL; @@ -360,6 +363,7 @@ void Player_V1::parsePCjrChunk() { _delta = (int16) READ_LE_UINT16(_next_chunk + 4); _channels[0].freq = 0; _next_chunk += 6; + _forced_level = -1; debug(6, "chunk 2: %d -> %d step %d", _start, _end, _delta); break; @@ -481,7 +485,7 @@ void Player_V1::nextPCjrCmd() { } set_mplex(_start); debug(7, "chunk 2: mplex %d curve %d", _start, _forced_level); - _forced_level ^= 1; + _forced_level = -_forced_level; break; case 3: dummy = _channels[3].volume + _delta; @@ -526,8 +530,9 @@ void Player_V1::generateSpkSamples(int16 *data, uint len) { memset(data, 0, 2 * sizeof(int16) * len); if (_channels[0].freq == 0) { if (_forced_level) { + int sample = _forced_level * _volumetable[0]; for (i = 0; i < len; i++) - data[2*i] = data[2*i+1] = _volumetable[0]; + data[2*i] = data[2*i+1] = sample; debug(9, "speaker: %8x: forced one", _tick_len); } else if (!_level) { return; @@ -548,8 +553,9 @@ void Player_V1::generatePCjrSamples(int16 *data, uint len) { memset(data, 0, 2 * sizeof(int16) * len); if (_forced_level) { + int sample = _forced_level * _volumetable[0]; for (i = 0; i < len; i++) - data[2*i] = data[2*i+1] = _volumetable[0]; + data[2*i] = data[2*i+1] = sample; hasdata = true; debug(9, "channel[4]: %8x: forced one", _tick_len); } diff --git a/scumm/player_v1.h b/scumm/player_v1.h index 238e914999..2bab13a217 100644 --- a/scumm/player_v1.h +++ b/scumm/player_v1.h @@ -79,7 +79,7 @@ private: uint _mplex; uint _repeat_ctr; uint _freq_current; - uint _forced_level; + int _forced_level; uint16 _random_lsr; uint *_value_ptr; uint _time_left; diff --git a/scumm/player_v2.cpp b/scumm/player_v2.cpp index 2001087cc3..4bb7373053 100644 --- a/scumm/player_v2.cpp +++ b/scumm/player_v2.cpp @@ -433,8 +433,8 @@ void Player_V2::setMasterVolume (int vol) { /* build volume table (2dB per step) */ for (int i = 0; i < 15; i++) { /* limit volume to avoid clipping */ - if (out > 0x7fff) - _volumetable[i] = 0x7fff; + if (out > 0xffff) + _volumetable[i] = 0xffff; else _volumetable[i] = (int) out; @@ -860,8 +860,8 @@ void Player_V2::nextTick() { void Player_V2::lowPassFilter(int16 *sample, uint len) { for (uint i = 0; i < len; i++) { - _level = (_level * _decay - + (unsigned int)sample[0] * (0x10000-_decay)) >> 16; + _level = (int) (_level * _decay + + sample[0] * (0x10000-_decay)) >> 16; sample[0] = sample[1] = _level; sample += 2; } @@ -870,6 +870,7 @@ void Player_V2::lowPassFilter(int16 *sample, uint len) { void Player_V2::squareGenerator(int channel, int freq, int vol, int noiseFeedback, int16 *sample, uint len) { int period = _update_step * freq; + long nsample; if (period == 0) period = _update_step; @@ -901,11 +902,15 @@ void Player_V2::squareGenerator(int channel, int freq, int vol, if (_timer_output & (1 << channel)) duration -= _timer_count[channel]; - sample[0] += (duration * _volumetable[vol]) >> FIXP_SHIFT; - if (sample[0] < 0) { - /* overflow: clip value */ - sample[0] = 0x7fff; - } + nsample = *sample + + (((signed long) (duration - (1 << (FIXP_SHIFT-1))) + * (signed long) _volumetable[vol]) >> FIXP_SHIFT); + /* overflow: clip value */ + if (nsample > 0x7fff) + nsample = 0x7fff; + if (nsample < -0x8000) + nsample = -0x8000; + *sample = nsample; // The following write isn't necessary, because the lowPassFilter does it for us //sample[1] = sample[0]; sample += 2; diff --git a/scumm/player_v2.h b/scumm/player_v2.h index a718b50bab..55b054608d 100644 --- a/scumm/player_v2.h +++ b/scumm/player_v2.h @@ -98,7 +98,7 @@ protected: uint32 _tick_len; unsigned int _update_step; unsigned int _decay; - unsigned int _level; + int _level; unsigned int _RNG; unsigned int _volumetable[16]; |