Esempio n. 1
0
void SoundCommandParser::processDisposeSound(reg_t obj) {
	MusicEntry *musicSlot = _music->getSlot(obj);
	if (!musicSlot) {
		warning("kDoSound(dispose): Slot not found (%04x:%04x)", PRINT_REG(obj));
		return;
	}

	processStopSound(obj, false);

	_music->soundKill(musicSlot);
	writeSelectorValue(_segMan, obj, SELECTOR(handle), 0);
	if (_soundVersion >= SCI_VERSION_1_EARLY)
		writeSelector(_segMan, obj, SELECTOR(nodePtr), NULL_REG);
	else
		writeSelectorValue(_segMan, obj, SELECTOR(state), kSoundStopped);
}
Esempio n. 2
0
void SoundCommandParser::processUpdateCues(reg_t obj) {
	MusicEntry *musicSlot = _music->getSlot(obj);
	if (!musicSlot) {
		warning("kDoSound(updateCues): Slot not found (%04x:%04x)", PRINT_REG(obj));
		return;
	}

	if (musicSlot->isSample) {
#ifdef ENABLE_SCI32
		if (_soundVersion >= SCI_VERSION_2_1_EARLY) {
			const int position = g_sci->_audio32->getPosition(ResourceId(kResourceTypeAudio, musicSlot->resourceId), musicSlot->soundObj);

			if (position == -1) {
				processStopSound(musicSlot->soundObj, true);
			}

			return;
		}
#endif
		// Update digital sound effect slots
		uint currentLoopCounter = 0;

		if (musicSlot->pLoopStream)
			currentLoopCounter = musicSlot->pLoopStream->getCompleteIterations();

		if (currentLoopCounter != musicSlot->sampleLoopCounter) {
			// during last time we looped at least one time, update loop accordingly
			musicSlot->loop -= currentLoopCounter - musicSlot->sampleLoopCounter;
			musicSlot->sampleLoopCounter = currentLoopCounter;
		}
		if (musicSlot->status == kSoundPlaying) {
			if (!_music->soundIsActive(musicSlot)) {
				processStopSound(obj, true);
			} else {
				_music->updateAudioStreamTicker(musicSlot);
			}
		} else if (musicSlot->status == kSoundPaused) {
			_music->updateAudioStreamTicker(musicSlot);
		}
		// We get a flag from MusicEntry::doFade() here to set volume for the stream
		if (musicSlot->fadeSetVolume) {
			_music->soundSetSampleVolume(musicSlot, musicSlot->volume);
			musicSlot->fadeSetVolume = false;
		}
	} else if (musicSlot->pMidiParser) {
		// Update MIDI slots
		if (musicSlot->signal == 0) {
			if (musicSlot->dataInc != readSelectorValue(_segMan, obj, SELECTOR(dataInc))) {
				if (SELECTOR(dataInc) > -1)
					writeSelectorValue(_segMan, obj, SELECTOR(dataInc), musicSlot->dataInc);
				writeSelectorValue(_segMan, obj, SELECTOR(signal), musicSlot->dataInc + 127);
			}
		} else {
			// Sync the signal of the sound object
			writeSelectorValue(_segMan, obj, SELECTOR(signal), musicSlot->signal);
			// We need to do this especially because state selector needs to get updated
			if (musicSlot->signal == SIGNAL_OFFSET)
				processStopSound(obj, false);
		}
	} else {
		// The sound slot has no data for the currently selected sound card.
		// An example can be found during the mud wrestling scene in LSL5, room
		// 730: sound 744 (a splat sound heard when Lana Luscious jumps in the
		// mud) only contains MIDI channel data. If a non-MIDI sound card is
		// selected (like Adlib), then the scene freezes. We also need to stop
		// the sound at this point, otherwise KQ6 Mac breaks because the rest
		// of the object needs to be reset to avoid a continuous stream of
		// sound cues.
		processStopSound(obj, true);	// this also sets the signal selector
	}

	if (musicSlot->fadeCompleted) {
		musicSlot->fadeCompleted = false;
		// We need signal for sci0 at least in iceman as well (room 14,
		// fireworks).
		// It is also needed in other games, e.g. LSL6 when talking to the
		// receptionist (bug #3192166).
		// TODO: More thorougly check the different SCI version:
		// * SCI1late sets signal to 0xFE here. (With signal 0xFF
		//       duplicate music plays in LauraBow2CD - bug #6462)
		//   SCI1middle LSL1 1.000.510 does not have the 0xFE;
		//   SCI1late CastleDrBrain demo 1.000.005 does have the 0xFE.
		// * Other SCI1 games seem to rely on processStopSound to set the signal
		// * Need to check SCI0 behaviour.
		uint16 sig;
		if (getSciVersion() >= SCI_VERSION_1_LATE)
			sig = 0xFFFE;
		else
			sig = SIGNAL_OFFSET;
		writeSelectorValue(_segMan, obj, SELECTOR(signal), sig);
		if (_soundVersion <= SCI_VERSION_0_LATE) {
			processStopSound(obj, false);
		} else {
			if (musicSlot->stopAfterFading)
				processStopSound(obj, false);
		}
	}

	// Sync loop selector for SCI0
	if (_soundVersion <= SCI_VERSION_0_LATE)
		writeSelectorValue(_segMan, obj, SELECTOR(loop), musicSlot->loop);

	musicSlot->signal = 0;

	if (_soundVersion >= SCI_VERSION_1_EARLY) {
		writeSelectorValue(_segMan, obj, SELECTOR(min), musicSlot->ticker / 3600);
		writeSelectorValue(_segMan, obj, SELECTOR(sec), musicSlot->ticker % 3600 / 60);
		writeSelectorValue(_segMan, obj, SELECTOR(frame), musicSlot->ticker % 60 / 2);
	}
}
Esempio n. 3
0
reg_t SoundCommandParser::kDoSoundStop(EngineState *s, int argc, reg_t *argv) {
	debugC(kDebugLevelSound, "kDoSound(stop): %04x:%04x", PRINT_REG(argv[0]));
	processStopSound(argv[0], false);
	return s->r_acc;
}
Esempio n. 4
0
void SoundCommandParser::processUpdateCues(reg_t obj) {
	MusicEntry *musicSlot = _music->getSlot(obj);
	if (!musicSlot) {
		warning("kDoSound(updateCues): Slot not found (%04x:%04x)", PRINT_REG(obj));
		return;
	}

	if (musicSlot->pStreamAud) {
		// Update digital sound effect slots
		uint currentLoopCounter = 0;

		if (musicSlot->pLoopStream)
			currentLoopCounter = musicSlot->pLoopStream->getCompleteIterations();

		if (currentLoopCounter != musicSlot->sampleLoopCounter) {
			// during last time we looped at least one time, update loop accordingly
			musicSlot->loop -= currentLoopCounter - musicSlot->sampleLoopCounter;
			musicSlot->sampleLoopCounter = currentLoopCounter;
		}
		if (musicSlot->status == kSoundPlaying) {
			if (!_music->soundIsActive(musicSlot)) {
				processStopSound(obj, true);
			} else {
				_music->updateAudioStreamTicker(musicSlot);
			}
		} else if (musicSlot->status == kSoundPaused) {
			_music->updateAudioStreamTicker(musicSlot);
		}
		// We get a flag from MusicEntry::doFade() here to set volume for the stream
		if (musicSlot->fadeSetVolume) {
			_music->soundSetSampleVolume(musicSlot, musicSlot->volume);
			musicSlot->fadeSetVolume = false;
		}
	} else if (musicSlot->pMidiParser) {
		// Update MIDI slots
		if (musicSlot->signal == 0) {
			if (musicSlot->dataInc != readSelectorValue(_segMan, obj, SELECTOR(dataInc))) {
				if (SELECTOR(dataInc) > -1)
					writeSelectorValue(_segMan, obj, SELECTOR(dataInc), musicSlot->dataInc);
				writeSelectorValue(_segMan, obj, SELECTOR(signal), musicSlot->dataInc + 127);
			}
		} else {
			// Sync the signal of the sound object
			writeSelectorValue(_segMan, obj, SELECTOR(signal), musicSlot->signal);
			// We need to do this especially because state selector needs to get updated
			if (musicSlot->signal == SIGNAL_OFFSET)
				processStopSound(obj, false);
		}
	} else {
		// Slot actually has no data (which would mean that a sound-resource w/
		// unsupported data is used.
		//  (example lsl5 - sound resource 744 - it's roland exclusive
		writeSelectorValue(_segMan, obj, SELECTOR(signal), SIGNAL_OFFSET);
		// If we don't set signal here, at least the switch to the mud wrestling
		// room in lsl5 will not work.
	}

	if (musicSlot->fadeCompleted) {
		musicSlot->fadeCompleted = false;
		// We need signal for sci0 at least in iceman as well (room 14,
		// fireworks).
		// It is also needed in other games, e.g. LSL6 when talking to the
		// receptionist (bug #3192166).
		if (g_sci->getGameId() == GID_LONGBOW && g_sci->getEngineState()->currentRoomNumber() == 95) {
			// HACK: Don't set a signal here in the intro of Longbow, as that makes some dialog
			// boxes disappear too soon (bug #3044844).
		} else {
			writeSelectorValue(_segMan, obj, SELECTOR(signal), SIGNAL_OFFSET);
		}
		if (_soundVersion <= SCI_VERSION_0_LATE) {
			processStopSound(obj, false);
		} else {
			if (musicSlot->stopAfterFading)
				processStopSound(obj, false);
		}
	}

	// Sync loop selector for SCI0
	if (_soundVersion <= SCI_VERSION_0_LATE)
		writeSelectorValue(_segMan, obj, SELECTOR(loop), musicSlot->loop);

	musicSlot->signal = 0;

	if (_soundVersion >= SCI_VERSION_1_EARLY) {
		writeSelectorValue(_segMan, obj, SELECTOR(min), musicSlot->ticker / 3600);
		writeSelectorValue(_segMan, obj, SELECTOR(sec), musicSlot->ticker % 3600 / 60);
		writeSelectorValue(_segMan, obj, SELECTOR(frame), musicSlot->ticker);
	}
}
Esempio n. 5
0
reg_t SoundCommandParser::kDoSoundStop(int argc, reg_t *argv, reg_t acc) {
	debugC(kDebugLevelSound, "kDoSound(stop): %04x:%04x", PRINT_REG(argv[0]));
	processStopSound(argv[0], false);
	return acc;
}
Esempio n. 6
0
void SoundCommandParser::processUpdateCues(reg_t obj) {
	MusicEntry *musicSlot = _music->getSlot(obj);
	if (!musicSlot) {
		warning("kDoSound(updateCues): Slot not found (%04x:%04x)", PRINT_REG(obj));
		return;
	}

	if (musicSlot->pStreamAud) {
		// Update digital sound effect slots
		uint currentLoopCounter = 0;

		if (musicSlot->pLoopStream)
			currentLoopCounter = musicSlot->pLoopStream->getCompleteIterations();

		if (currentLoopCounter != musicSlot->sampleLoopCounter) {
			// during last time we looped at least one time, update loop accordingly
			musicSlot->loop -= currentLoopCounter - musicSlot->sampleLoopCounter;
			musicSlot->sampleLoopCounter = currentLoopCounter;
		}
		if (musicSlot->status == kSoundPlaying) {
			if (!_music->soundIsActive(musicSlot)) {
				processStopSound(obj, true);
			} else {
				_music->updateAudioStreamTicker(musicSlot);
			}
		} else if (musicSlot->status == kSoundPaused) {
			_music->updateAudioStreamTicker(musicSlot);
		}
		// We get a flag from MusicEntry::doFade() here to set volume for the stream
		if (musicSlot->fadeSetVolume) {
			_music->soundSetSampleVolume(musicSlot, musicSlot->volume);
			musicSlot->fadeSetVolume = false;
		}
	} else if (musicSlot->pMidiParser) {
		// Update MIDI slots
		if (musicSlot->signal == 0) {
			if (musicSlot->dataInc != readSelectorValue(_segMan, obj, SELECTOR(dataInc))) {
				if (SELECTOR(dataInc) > -1)
					writeSelectorValue(_segMan, obj, SELECTOR(dataInc), musicSlot->dataInc);
				writeSelectorValue(_segMan, obj, SELECTOR(signal), musicSlot->dataInc + 127);
			}
		} else {
			// Sync the signal of the sound object
			writeSelectorValue(_segMan, obj, SELECTOR(signal), musicSlot->signal);
			// We need to do this especially because state selector needs to get updated
			if (musicSlot->signal == SIGNAL_OFFSET)
				processStopSound(obj, false);
		}
	} else {
		// The sound slot has no data for the currently selected sound card.
		// An example can be found during the mud wrestling scene in LSL5, room
		// 730: sound 744 (a splat sound heard when Lana Luscious jumps in the
		// mud) only contains MIDI channel data. If a non-MIDI sound card is
		// selected (like Adlib), then the scene freezes. We also need to stop
		// the sound at this point, otherwise KQ6 Mac breaks because the rest
		// of the object needs to be reset to avoid a continuous stream of
		// sound cues.
		processStopSound(obj, true);	// this also sets the signal selector
	}

	if (musicSlot->fadeCompleted) {
		musicSlot->fadeCompleted = false;
		// We need signal for sci0 at least in iceman as well (room 14,
		// fireworks).
		// It is also needed in other games, e.g. LSL6 when talking to the
		// receptionist (bug #3192166).
		// CHECKME: At least kq5cd/win and kq6 set signal to 0xFE here, but
		// kq5cd/dos does not set signal at all. Needs more investigation.
		writeSelectorValue(_segMan, obj, SELECTOR(signal), SIGNAL_OFFSET);
		if (_soundVersion <= SCI_VERSION_0_LATE) {
			processStopSound(obj, false);
		} else {
			if (musicSlot->stopAfterFading)
				processStopSound(obj, false);
		}
	}

	// Sync loop selector for SCI0
	if (_soundVersion <= SCI_VERSION_0_LATE)
		writeSelectorValue(_segMan, obj, SELECTOR(loop), musicSlot->loop);

	musicSlot->signal = 0;

	if (_soundVersion >= SCI_VERSION_1_EARLY) {
		writeSelectorValue(_segMan, obj, SELECTOR(min), musicSlot->ticker / 3600);
		writeSelectorValue(_segMan, obj, SELECTOR(sec), musicSlot->ticker % 3600 / 60);
		writeSelectorValue(_segMan, obj, SELECTOR(frame), musicSlot->ticker);
	}
}