aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Howell2002-09-11 13:28:34 +0000
committerTravis Howell2002-09-11 13:28:34 +0000
commit004c6ddec95b6c6a3f1068b8f873c485a38b8911 (patch)
treea9f1dcfb2c52e41b23385ded55da5d226479baac
parentf26cd0e2b2f5271249d4dab130bb5d5748f279ab (diff)
downloadscummvm-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.cpp2
-rw-r--r--scumm/imuse.cpp82
-rw-r--r--scumm/sound.cpp9
-rw-r--r--scumm/sound.h3
-rw-r--r--scumm/string.cpp32
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;