Allowed IHNM to use the opSpeak opcode. Aborting that code path early meant

that the instruction wasn't fully read, so the next opcode would be wrong.
This is what caused it to crash.

To keep the game from hanging, I also allowed the engine to call the
_actors->direct() function for IHNM. This allows AM's intro speech to be
played in its entirety.

Since this includes the "hate" speech, I've removed that part from the
hard-coded intro. To get the right music playing, I've enabled the
sfPlayMusic() function for IHNM. This is pure guesswork, though. Once the
scene changes, the wrong music plays again. However, this is scene music,
i.e. not scripted.

It doesn't play the background sound. Looks like _fxTable[] isn't generated
for IHNM. More noticeably, until the scene changes it doesn't show any
graphics apart from the subtitles, which are drawn in the wrong colour and
(I believe) the wrong font.

svn-id: r18712
This commit is contained in:
Torbjörn Andersson 2005-08-26 12:07:31 +00:00
parent 41e9aa2f2c
commit d8a96c3032
4 changed files with 9 additions and 93 deletions

View File

@ -83,7 +83,6 @@ LoadSceneParams IHNM_IntroList[] = {
{0, kLoadByDescription, &IHNM_IntroMovie1Desc, Scene::SC_IHNMIntroMovieProc1, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE},
{0, kLoadByDescription, &IHNM_IntroMovie2Desc, Scene::SC_IHNMIntroMovieProc2, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE},
{0, kLoadByDescription, &IHNM_IntroMovie3Desc, Scene::SC_IHNMIntroMovieProc3, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE},
{0, kLoadByDescription, &IHNM_IntroMovie4Desc, Scene::SC_IHNMHateProc, false, kTransitionNoFade, 0, NO_CHAPTER_CHANGE}
};
int Scene::IHNMStartProc() {
@ -322,88 +321,4 @@ int Scene::IHNMIntroMovieProc3(int param) {
return 0;
}
int Scene::SC_IHNMHateProc(int param, void *refCon) {
return ((Scene *)refCon)->IHNMHateProc(param);
}
int Scene::IHNMHateProc(int param) {
Event event;
Event *q_event;
switch (param) {
case SCENE_BEGIN:
_vm->_anim->setCycles(0, -1);
// Start "hate" animation
event.type = kEvTOneshot;
event.code = kAnimEvent;
event.op = kEventPlay;
event.param = 0;
event.time = 0;
q_event = _vm->_events->queue(&event);
// More music
event.type = kEvTOneshot;
event.code = kMusicEvent;
event.param = 32;
event.param2 = MUSIC_LOOP;
event.op = kEventPlay;
event.time = 0;
q_event = _vm->_events->chain(q_event, &event);
// Background for intro scene is the first frame of the
// intro animation; display it and set the palette
event.type = kEvTOneshot;
event.code = kBgEvent;
event.op = kEventDisplay;
event.param = kEvPSetPalette;
event.time = 0;
q_event = _vm->_events->chain(q_event, &event);
// Play voice
event.type = kEvTOneshot;
event.code = kVoiceEvent;
event.op = kEventPlay;
event.param = 0;
event.time = 0;
q_event = _vm->_events->chain(q_event, &event);
// Background sound
event.type = kEvTOneshot;
event.code = kSoundEvent;
event.op = kEventPlay;
event.param = 260;
event.param2 = 255; // FIXME: Verify volume
event.param3 = SOUND_LOOP;
event.time = 0;
q_event = _vm->_events->chain(q_event, &event);
// End background sound after the voice has finished
event.type = kEvTOneshot;
event.code = kSoundEvent;
event.op = kEventStop;
event.time = _vm->_sndRes->getVoiceLength(0);
q_event = _vm->_events->chain(q_event, &event);
// End scene after the voice has finished
event.type = kEvTOneshot;
event.code = kSceneEvent;
event.op = kEventEnd;
event.time = 0;
q_event = _vm->_events->chain(q_event, &event);
break;
default:
break;
}
return 0;
}
} // End of namespace Saga

View File

@ -314,7 +314,7 @@ int SagaEngine::go() {
// Since Puzzle is actorless, we do it here
if (_puzzle->isActive()) {
_actor->handleSpeech(msec);
} else if (!_scene->isInIntro() && getGameType() == GType_ITE) {
} else if (!_scene->isInIntro()) {
if (_interface->getMode() == kPanelMain ||
_interface->getMode() == kPanelConverse ||
_interface->getMode() == kPanelNull)

View File

@ -1640,12 +1640,12 @@ void Script::sfPlayMusic(SCRIPTFUNC_PARAMS) {
_vm->_music->stop();
}
} else {
int16 param1 = thread->pop();
// TODO: Verify this
int16 param1 = thread->pop() + 32;
int16 param2 = thread->pop();
debug(0, "STUB: sfPlayMusic(%d, %d)", param1, param2);
_vm->_music->play(param1, param2 ? MUSIC_LOOP: MUSIC_NORMAL);
}
}
// Script function #64 (0x40)
@ -1738,6 +1738,10 @@ void Script::sfPlayLoopedSound(SCRIPTFUNC_PARAMS) {
int16 param = thread->pop();
int res;
// TODO: This doesn't work for IHNM yet. As a point of reference, when
// 'param' is 11, during the "hate" speech, it should probably
// play sound resource 260. Probably quite loudly.
if (param >= 0 && param < _vm->_sndRes->_fxTableLen) {
res = _vm->_sndRes->_fxTable[param].res;
if (_vm->getFeatures() & GF_CD_FX)

View File

@ -615,16 +615,13 @@ bool Script::runThread(ScriptThread *thread, uint instructionLimit) {
int16 first;
const char *strings[ACTOR_SPEECH_STRING_MAX];
if (_vm->getGameType() == GType_IHNM)
break;
if (_vm->_actor->isSpeaking()) {
thread->wait(kWaitTypeSpeech);
return false;
}
stringsCount = scriptS.readByte();
actorId = scriptS.readUint16LE();
actorId = scriptS.readUint16LE();
speechFlags = scriptS.readByte();
scriptS.readUint16LE(); // x,y skip