diff options
author | Travis Howell | 2002-09-11 13:28:34 +0000 |
---|---|---|
committer | Travis Howell | 2002-09-11 13:28:34 +0000 |
commit | 004c6ddec95b6c6a3f1068b8f873c485a38b8911 (patch) | |
tree | a9f1dcfb2c52e41b23385ded55da5d226479baac | |
parent | f26cd0e2b2f5271249d4dab130bb5d5748f279ab (diff) | |
download | scummvm-rg350-004c6ddec95b6c6a3f1068b8f873c485a38b8911.tar.gz scummvm-rg350-004c6ddec95b6c6a3f1068b8f873c485a38b8911.tar.bz2 scummvm-rg350-004c6ddec95b6c6a3f1068b8f873c485a38b8911.zip |
Commited the following patches
[ 606595 ] Fix for Sam & Max animation glitch
[ 607175 ] Possible fix for bug #590511
[ 607677 ] Partial workaround for bug #566062
[ 607713 ] patch for bug 580350 (MI2 F5 crash)
svn-id: r4924
-rw-r--r-- | gui/gui.cpp | 2 | ||||
-rw-r--r-- | scumm/imuse.cpp | 82 | ||||
-rw-r--r-- | scumm/sound.cpp | 9 | ||||
-rw-r--r-- | scumm/sound.h | 3 | ||||
-rw-r--r-- | scumm/string.cpp | 32 |
5 files changed, 108 insertions, 20 deletions
diff --git a/gui/gui.cpp b/gui/gui.cpp index ff989812c9..8d127226e2 100644 --- a/gui/gui.cpp +++ b/gui/gui.cpp @@ -907,6 +907,8 @@ void Gui::getSavegameNames(int start) const char *Gui::queryString(int stringno, int id) { + if ((stringno == 1) && (_s->_gameId == GID_MONKEY2)) return "How may I serve you?"; // FIXME (MI2 data file is wrong) + static char namebuf[64]; char *result; int string; diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp index 586c021446..20a7e74f6e 100644 --- a/scumm/imuse.cpp +++ b/scumm/imuse.cpp @@ -170,6 +170,7 @@ struct Player { int query_param(int param); int fade_vol(byte vol, int time); + bool is_fading_out(); void sequencer_timer(); }; @@ -185,7 +186,9 @@ struct VolumeFader { void initialize() { active = false; - } void on_timer(); + } + void on_timer(bool probe); + byte fading_to(); }; struct SustainingNotes { @@ -1134,12 +1137,12 @@ void IMuseInternal::expire_volume_faders() for (i = ARRAYSIZE(_volume_fader); i != 0; i--, vf++) { if (vf->active) { _active_volume_faders = true; - vf->on_timer(); + vf->on_timer(false); } } } -void VolumeFader::on_timer() +void VolumeFader::on_timer(bool probe) { byte newvol; @@ -1152,13 +1155,15 @@ void VolumeFader::on_timer() } if (curvol != newvol) { + curvol = newvol; if (!newvol) { - player->clear(); + if (!probe) + player->clear(); active = false; return; } - curvol = newvol; - player->set_vol(newvol); + if (!probe) + player->set_vol(newvol); } if (!--num_steps) { @@ -1166,14 +1171,53 @@ void VolumeFader::on_timer() } } +byte VolumeFader::fading_to() +{ + byte newvol; + byte orig_curvol; + uint16 orig_speed_lo_counter, orig_num_steps; + + if (!active) + return 127; + + // It would be so much easier to just store the fade-to volume in a + // variable, but then we'd have to break savegame compatibility. So + // instead we do a "dry run" fade. + + orig_speed_lo_counter = speed_lo_counter; + orig_num_steps = num_steps; + orig_curvol = curvol; + + while (active) + on_timer(true); + + active = true; + newvol = curvol; + + speed_lo_counter = orig_speed_lo_counter; + num_steps = orig_num_steps; + curvol = orig_curvol; + + return newvol; +} + int IMuseInternal::get_sound_status(int sound) { int i; Player *player; for (i = ARRAYSIZE(_players), player = _players; i != 0; i--, player++) { - if (player->_active && player->_id == (uint16)sound) + if (player->_active && player->_id == (uint16)sound) { + // Assume that anyone asking for the sound status is + // really asking "is it ok if I start playing this + // sound now?" So if the sound is about to fade out, + // shut it down and pretend it wasn't playing. + if (player->is_fading_out()) { + player->clear(); + continue; + } return 1; + } } return get_queue_sound_status(sound); } @@ -1781,6 +1825,18 @@ int Player::fade_vol(byte vol, int time) return 0; } +bool Player::is_fading_out() +{ + VolumeFader *vf = _se->_volume_fader; + int i; + + for (i = 0; i < 8; i++, vf++) { + if (vf->active && vf->direction < 0 && vf->player == this && vf->fading_to() == 0) + return true; + } + return false; +} + void Player::clear() { uninit_seq(); @@ -3038,6 +3094,18 @@ void IMuseInternal::fix_players_after_load(Scumm *scumm) player->set_tempo(player->_tempo); scumm->getResourceAddress(rtSound, player->_id); player->_mt32emulate = isMT32(player->_id); + if (scumm->_use_adlib) { + // FIXME - This should make sure the right + // instruments are loaded, but it does not + // even try to move to the right position in + // the track. Using scan() gives a marginally + // better result, but not good enough. + // + // The correct fix is probably to store the + // Adlib instruments, or information on where + // to find them, in the savegame. + player->jump(player->_track_index, 0, 0); + } } } } diff --git a/scumm/sound.cpp b/scumm/sound.cpp index b685e560f5..26b3839251 100644 --- a/scumm/sound.cpp +++ b/scumm/sound.cpp @@ -407,7 +407,11 @@ void Sound::processSfxQueues() { b = isMouthSyncOff(_curSoundPos); if (_mouthSyncMode != b) { _mouthSyncMode = b; - a->startAnimActor(b ? a->talkFrame2 : a->talkFrame1); + if (_talk_sound_frame != -1) { + a->startAnimActor(_talk_sound_frame); + _talk_sound_frame = -1; + } else + a->startAnimActor(b ? a->talkFrame2 : a->talkFrame1); } } } @@ -618,10 +622,11 @@ void Sound::soundKludge(int16 * list) { error("Sound que buffer overflow"); } -void Sound::talkSound(uint32 a, uint32 b, int mode) { +void Sound::talkSound(uint32 a, uint32 b, int mode, int frame) { _talk_sound_a = a; _talk_sound_b = b; _talk_sound_mode = mode; + _talk_sound_frame = frame; } /* The sound code currently only supports General Midi. diff --git a/scumm/sound.h b/scumm/sound.h index 73dc23eeed..39aba83778 100644 --- a/scumm/sound.h +++ b/scumm/sound.h @@ -56,6 +56,7 @@ enum { File *_sfxFile; uint32 _talk_sound_a, _talk_sound_b; byte _talk_sound_mode; + int _talk_sound_frame; bool _mouthSyncMode; bool _endOfMouthSync; uint16 _mouthSyncTimes[52]; @@ -107,7 +108,7 @@ public: void stopAllSounds(); void clearSoundQue(); void soundKludge(int16 * list); - void talkSound(uint32 a, uint32 b, int mode); + void talkSound(uint32 a, uint32 b, int mode, int frame); void setupSound(); void pauseSounds(bool pause); int startSfxSound(File *file, int file_size); diff --git a/scumm/string.cpp b/scumm/string.cpp index 4bf0d75eeb..8c0a50f607 100644 --- a/scumm/string.cpp +++ b/scumm/string.cpp @@ -174,7 +174,7 @@ void Scumm::unkMessage1() a = buffer[2] | (buffer[3] << 8) | (buffer[6] << 16) | (buffer[7] << 24); b = buffer[10] | (buffer[11] << 8) | (buffer[14] << 16) | (buffer[15] << 24); // if (_saveSound != 1) - _sound->talkSound(a, b, 1); + _sound->talkSound(a, b, 1, -1); } // warning("unkMessage1(\"%s\")", buffer); } @@ -196,10 +196,14 @@ void Scumm::unkMessage2() void Scumm::CHARSET_1() { + uint32 talk_sound_a = 0; + uint32 talk_sound_b = 0; int s, i, t, c; - int frme; + int frme = -1; Actor *a; byte *buffer; + bool has_talk_sound = false; + bool has_anim = false; if (!_haveMsg) return; @@ -290,7 +294,8 @@ void Scumm::CHARSET_1() } if (a && !string[0].no_talk_anim) { - a->startAnimActor(a->talkFrame1); +// a->startAnimActor(a->talkFrame1); + has_anim = true; _useTalkAnims = true; } @@ -397,14 +402,11 @@ void Scumm::CHARSET_1() } else if (c == 9) { frme = *buffer++; frme |= *buffer++ << 8; - if (a) - a->startAnimActor(frme); + has_anim = true; } else if (c == 10) { - uint32 tmpA, tmpB; - - tmpA = buffer[0] | (buffer[1] << 8) | (buffer[4] << 16) | (buffer[5] << 24); - tmpB = buffer[8] | (buffer[9] << 8) | (buffer[12] << 16) | (buffer[13] << 24); - _sound->talkSound(tmpA, tmpB, 2); + talk_sound_a = buffer[0] | (buffer[1] << 8) | (buffer[4] << 16) | (buffer[5] << 24); + talk_sound_b = buffer[8] | (buffer[9] << 8) | (buffer[12] << 16) | (buffer[13] << 24); + has_talk_sound = true; buffer += 14; // Set flag that speech variant exist of this msg @@ -436,6 +438,16 @@ void Scumm::CHARSET_1() } } while (1); + // Even if talkSound() is called, we may still have to call + // startAnimActor() since actorTalk() may already have caused the + // wrong animation frame to be drawn, and the talkSound() won't be + // processed until after the next screen update. Bleah. + + if (has_talk_sound) + _sound->talkSound(talk_sound_a, talk_sound_b, 2, frme); + if (a && has_anim) + a->startAnimActor(frme != -1 ? frme : a->talkFrame1); + charset._bufPos = buffer - charset._buffer; gdi._mask_left = charset._strLeft; |