SCI: fix #10907, #10812 and fix music position on restore #2128
Conversation
@@ -467,6 +467,9 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) { | |||
pSnd->overridePriority = false; | |||
|
|||
pSnd->pMidiParser->loadMusic(track, pSnd, channelFilterMask, _soundVersion); | |||
|
|||
// When restoring, continue from the correct place | |||
pSnd->pMidiParser->jumpToTick(pSnd->ticker); |
bluegr
Mar 15, 2020
Member
Why? We already do this when loading. Also, all the music events need to run when restoring (like instrument changes), otherwise music will sound distorted after loading
Why? We already do this when loading. Also, all the music events need to run when restoring (like instrument changes), otherwise music will sound distorted after loading
ZvikaZ
Mar 16, 2020
Author
Contributor
Why?
Currently, when we save a game while a sound track is playing, and later restore it, the track is starting from the beginning. It's easy to see that in the scenerio of https://bugs.scummvm.org/ticket/10812 - KQ6 "wallflower dance music" - if you save the game few seconds before the music stops, and then restore, it starts from the beginning.
You're correct that sci\engine\savegame.cpp MusicEntry::saveLoadWithSerializer
has s.syncAsSint16LE(ticker)
, but it's not enough, as in sci\sound\music.cpp MusicEntry::onTimer()
there is ticker = (uint16)pMidiParser->getTick();
which overrides it, to zero, and thus the track starts from the beginning.
Therefore, calling jumpToTick(pSnd->ticker)
fixes it.
However, I changed it to be pSnd->pMidiParser->jumpToTick(pSnd->ticker, true, true, true);
, which (if I understand correctly) should acheive exactly that - fast forward to the correct place, executing all midi controllers in the way, without playing music.
I copied this line, and its comment, from music.cpp, from near the end of SciMusic::soundPlay
(line 609 in my version)
Why?
Currently, when we save a game while a sound track is playing, and later restore it, the track is starting from the beginning. It's easy to see that in the scenerio of https://bugs.scummvm.org/ticket/10812 - KQ6 "wallflower dance music" - if you save the game few seconds before the music stops, and then restore, it starts from the beginning.
You're correct that sci\engine\savegame.cpp MusicEntry::saveLoadWithSerializer
has s.syncAsSint16LE(ticker)
, but it's not enough, as in sci\sound\music.cpp MusicEntry::onTimer()
there is ticker = (uint16)pMidiParser->getTick();
which overrides it, to zero, and thus the track starts from the beginning.
Therefore, calling jumpToTick(pSnd->ticker)
fixes it.
However, I changed it to be pSnd->pMidiParser->jumpToTick(pSnd->ticker, true, true, true);
, which (if I understand correctly) should acheive exactly that - fast forward to the correct place, executing all midi controllers in the way, without playing music.
I copied this line, and its comment, from music.cpp, from near the end of SciMusic::soundPlay
(line 609 in my version)
- Reset 'ticker' when playing again an existing resource (bug #10812) - When restoring, continue from the same music position
Nice work! :) In the future, please try and create separate pull requests for different bugs, if possible |
@bluegr any update? |
The second fix has been redone in PR #2765. Closing this one, as the implementation in the other PR is less invasive. Thanks for your work once again! :) |
init
ted, but notplay
ed yet (bug #10907)