[Scummvm-git-logs] scummvm master -> 7ce98275a2ca06aa23c745a13a4aeda629d96bbc

athrxx noreply at scummvm.org
Wed Nov 17 19:08:19 UTC 2021


This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
31832b9dfa KYRA: (LoK/Mac) - minor sound driver cleanup
a41f8b1de3 KYRA: (EOB/PC98) - improve final sequence (king scene) for enabled vsync option
8a2c97233e KYRA: (LoK/Mac) - more sound driver cleanup
7ce98275a2 SCUMM: fix unused var warning


Commit: 31832b9dfae49f3624b51eb833313551d18d1055
    https://github.com/scummvm/scummvm/commit/31832b9dfae49f3624b51eb833313551d18d1055
Author: athrxx (athrxx at scummvm.org)
Date: 2021-11-17T20:07:01+01:00

Commit Message:
KYRA: (LoK/Mac) - minor sound driver cleanup

Changed paths:
    engines/kyra/sound/drivers/halestorm.cpp


diff --git a/engines/kyra/sound/drivers/halestorm.cpp b/engines/kyra/sound/drivers/halestorm.cpp
index ab8d773eae..a6911bf58d 100644
--- a/engines/kyra/sound/drivers/halestorm.cpp
+++ b/engines/kyra/sound/drivers/halestorm.cpp
@@ -161,6 +161,44 @@ public:
 	bool process(const ShStBuffer &src, uint8 *dst, uint16, uint16) override;
 };
 
+class HSSong {
+public:
+	HSSong() : _data(), _flags(0), _amplitudeScaleFlags(0), _interpolateType(0), _transpose(0), _tickLen(0), _tempo(0), _ticksPerSecond(0), _internalTempo(0),
+		_numChanMusic(0), _numChanSfx(0), _convertUnitSize(0), _midiResId(0), _fastForward(false) {}
+	void load(const ShStBuffer &data);
+	void reset();
+	void release();
+
+	void setTempo(uint32 tempo);
+	void setTicksPerSecond(uint32 tps);
+
+	uint16 tempo() const { return _internalTempo; }
+
+public:
+	int _numChanMusic;
+	int _convertUnitSize;
+	int _numChanSfx;
+
+	uint16 _midiResId;
+	uint16 _flags;
+	uint8 _amplitudeScaleFlags;
+	uint16 _interpolateType;
+	int16 _transpose;
+	uint16 _tickLen;
+
+	Common::Array<uint16> _programMappings;
+	bool _fastForward;
+
+private:
+	void updateTempo();
+
+	ShStBuffer _data;
+
+	uint32 _ticksPerSecond;
+	uint16 _tempo;
+	uint16 _internalTempo;
+};
+
 class HSLowLevelDriver {
 public:
 	HSLowLevelDriver(SoundMacRes *res, Common::Mutex &mutex);
@@ -253,15 +291,11 @@ private:
 	uint16 *_transBuffer;
 	int16 *_wtable;
 
-	int _numChanMusic;
-	int _convertUnitSize;
-	int _numChanSfx;
 	int _convertBufferNumUnits;
 	int _numChanSfxLast;
 	int _convertUnitSizeLast;
 	int _wtableCount;
 	int _wtableCount2;
-	uint8 _amplitudeScaleFlags;
 	InterpolationMode _interpolationMode;
 	uint16 _samplesPerTick;
 	uint16 _transCycleLenDef;
@@ -285,7 +319,6 @@ private:
 	bool songStart();
 	bool songInit();
 	void midiNextTick();
-	void updateTempo();
 	bool isMusicPlaying();
 
 	bool midiParseEvent(MidiTrackState *s);
@@ -297,24 +330,18 @@ private:
 	int16 noteFromTable();
 
 	bool _songLoop;
-	uint16 _songFlags;
-	ShStBuffer _songData;
+	
 	ShStBuffer _midiData;
 	Common::Array<ShStBuffer> _midiTracks;
 
 	MidiTrackState *_trackState;
 	bool _midiBusy;
-	bool _midiFastForward;
 	uint16 _midiMaxNotesPlayed;
 	uint32 _songTicker;
 	uint8 _midiCurCmd;
 
-	uint16 _sndInterpolateType;
-	int16 _song_transpose;
-	uint16 _song_tickLen;
-	uint16 _song_tempo;
-	uint32 _song_ticksPerSecond;
-	uint16 _song_internalTempo;
+	HSSong _song;
+
 	uint8 _midiPartProgram[16];
 
 private:
@@ -353,7 +380,7 @@ private:
 		uint16 _id;
 	};
 
-	Common::Array<InstrSamples> _instrumentSamples;
+	Common::Array<InstrSamples> _instrumentsSharedSamples;
 	Common::Array<HSEffectFilter*> _hsFilters;
 
 	static const uint32 _periods[156];
@@ -560,11 +587,65 @@ void HSAudioStream::runVblTasl() {
 		(*_vblCbProc)();
 }
 
+void HSSong::load(const ShStBuffer &data) {
+	_data = data;
+	assert(_data.len >= 16);
+}
+
+void HSSong::reset() {
+	_midiResId = READ_BE_UINT16(_data.ptr);
+	_interpolateType = _data.ptr[2];
+	_tickLen = READ_BE_UINT16(_data.ptr + 4);
+	if (!_tickLen)
+		_tickLen = 16667;
+
+	_tempo = (500000u / _tickLen) & 0xffff;
+	_ticksPerSecond = 60;
+	updateTempo();
+
+	_transpose = READ_BE_INT16(_data.ptr + 6);
+
+	_numChanSfx = _data.ptr[8];
+	_numChanMusic = MIN<uint8>(_data.ptr[9] + _numChanSfx, 16) - _numChanSfx;
+	_convertUnitSize = MIN<uint16>(READ_BE_UINT16(_data.ptr + 10), 16);
+
+	_flags = READ_BE_UINT16(_data.ptr + 12);
+	_amplitudeScaleFlags = _data.ptr[15];
+
+	const uint8 *pos = _data.ptr + 16;
+	uint16 cnt = READ_BE_UINT16(pos) * 2;
+	pos += 2;
+	assert(18 + cnt * 2 <= (int32)_data.len);
+	_programMappings.clear();
+
+	while (cnt--) {
+		_programMappings.push_back(READ_BE_UINT16(pos));
+		pos += 2;
+	}
+}
+
+void HSSong::release() {
+	_data = ShStBuffer();
+}
+
+void HSSong::setTempo(uint32 tempo) {
+	_tempo = (tempo / _tickLen) & 0xffff;
+	updateTempo();
+}
+
+void HSSong::setTicksPerSecond(uint32 tps) {
+	_ticksPerSecond = tps;
+	updateTempo();
+}
+
+void HSSong::updateTempo() {
+	_internalTempo = _fastForward ? 32767 : ((_ticksPerSecond << 6) / _tempo);
+}
+
 HSLowLevelDriver::HSLowLevelDriver(SoundMacRes *res, Common::Mutex &mutex) : _res(res), _vcstr(nullptr), _mutex(mutex), _sampleConvertBuffer(nullptr), _interpolationTable(nullptr), _transCycleLenDef(0),
-_interpolationTable2(nullptr), _amplitudeScaleBuffer(nullptr), _songFlags(0), _amplitudeScaleFlags(0), _interpolationMode(kNone), _numChanMusic(0), _convertUnitSize(0), _numChanSfx(0),
-_midiCurCmd(0), _convertBufferNumUnits(0), _songLoop(false), _chan(nullptr), _samplesPerTick(0), _smpTransLen(0), _transCycleLenInter(0), _updateTypeHq(0), _instruments(nullptr), _songData(),
-_midiData(), _trackState(nullptr), _sndInterpolateType(0), _song_transpose(0), _song_tickLen(0), _song_tempo(0), _song_ticksPerSecond(0), _song_internalTempo(0), _midiFastForward(false),
-_midiBusy(false), _pcmDstBufferSize(370), _midiMaxNotesPlayed(0), _songTicker(0), _transBuffer(nullptr), _wtable(nullptr), _wtableCount(0), _convertUnitSizeLast(0), _numChanSfxLast(0),
+_interpolationTable2(nullptr), _amplitudeScaleBuffer(nullptr), _interpolationMode(kNone), _midiData(), _trackState(nullptr), _wtable(nullptr), _wtableCount(0),
+_midiCurCmd(0), _convertBufferNumUnits(0), _songLoop(false), _chan(nullptr), _samplesPerTick(0), _smpTransLen(0), _transCycleLenInter(0), _updateTypeHq(0), _instruments(nullptr),
+_midiBusy(false), _pcmDstBufferSize(370), _midiMaxNotesPlayed(0), _songTicker(0), _transBuffer(nullptr), _convertUnitSizeLast(0), _numChanSfxLast(0),
 _wtableCount2(0), _pmDataTrm(0x8000) {
 #define HSOPC(x)	_hsOpcodes.push_back(new HSOpcode(this, &HSLowLevelDriver::x))
 	HSOPC(cmd_startSong);
@@ -673,7 +754,7 @@ int HSLowLevelDriver::cmd_startSong(va_list &arg) {
 		error("HSLowLevelDriver::cmd_startSong(): Error encountered while loading song.");
 
 	song->seek(0);
-	_songData = song;
+	_song.load(ShStBuffer(song));
 	delete song;
 	_midiData = midi;
 	delete midi;
@@ -681,7 +762,7 @@ int HSLowLevelDriver::cmd_startSong(va_list &arg) {
 	for (int i = 0; i < 128; ++i)
 		_instruments[i].status = InstrumentEntry::kUnusable;
 
-	_midiFastForward = true;
+	_song._fastForward = true;
 	songStopChannel(-1);
 	if (!songStart())
 		error("HSLowLevelDriver::cmd_startSong(): Error reading song data.");
@@ -694,7 +775,7 @@ int HSLowLevelDriver::cmd_startSong(va_list &arg) {
 		midiNextTick();
 
 	_songLoop = loop;
-	_midiBusy = _midiFastForward = false;
+	_midiBusy = _song._fastForward = false;
 	for (int i = 0; i < 128; ++i)
 		loadInstrument(i);
 
@@ -733,18 +814,19 @@ int HSLowLevelDriver::cmd_stopSong2(va_list &arg) {
 }
 
 int HSLowLevelDriver::smd_stopSong3(va_list &arg) {
-	for (int i = 0; i <_numChanMusic; ++i)
+	for (int i = 0; i < _song._numChanMusic; ++i)
 		_chan[i].status = -1;
 	return 0;
 }
 
 int HSLowLevelDriver::cmd_releaseSongData(va_list &arg) {
 	_midiBusy = false;
-	for (int i = 0; i <_numChanMusic; ++i)
+	for (int i = 0; i < _song._numChanMusic; ++i)
 		_chan[i].status = -1;
 
-	_songData = ShStBuffer();
+	_song.release();
 	_midiData = ShStBuffer();
+	_instrumentsSharedSamples.clear();
 
 	for (int i = 0; i < 128; ++i) {
 		_instruments[i].pmData = ShStBuffer();
@@ -789,12 +871,12 @@ int HSLowLevelDriver::cmd_setLoop(va_list &arg) {
 
 int HSLowLevelDriver::cmd_playSoundEffect(va_list &arg) {
 	const HSSoundSystem::HSSoundEffectVoice *vc = va_arg(arg, const HSSoundSystem::HSSoundEffectVoice*);
-	if (!vc || !vc->dataPtr || !_numChanSfx)
+	if (!vc || !vc->dataPtr || !_song._numChanSfx)
 		return 0;
 
-	HSSoundChannel *chan = &_chan[_numChanMusic];
+	HSSoundChannel *chan = &_chan[_song._numChanMusic];
 	int16 lowest = 32767;
-	for (int i = _numChanMusic; i < _numChanMusic + _numChanSfx; ++i) {
+	for (int i = _song._numChanMusic; i < _song._numChanMusic + _song._numChanSfx; ++i) {
 		HSSoundChannel *c = &_chan[i];
 		if (c->status < 0)
 			break;
@@ -840,7 +922,7 @@ int HSLowLevelDriver::cmd_playSoundEffect(va_list &arg) {
 
 int HSLowLevelDriver::cmd_stopSoundEffect(va_list &arg) {
 	const HSSoundSystem::HSSoundEffectVoice *vc = va_arg(arg, const HSSoundSystem::HSSoundEffectVoice*);
-	for (int i = _numChanMusic; i <_numChanMusic + _numChanSfx; ++i) {
+	for (int i = _song._numChanMusic; i < _song._numChanMusic + _song._numChanSfx; ++i) {
 		if (_chan[i].id == vc->resId)
 			_chan[i].status = -1;
 	}
@@ -849,7 +931,7 @@ int HSLowLevelDriver::cmd_stopSoundEffect(va_list &arg) {
 
 int HSLowLevelDriver::cmd_setVolume(va_list &arg) {
 	int volpara = va_arg(arg, int);
-	int len = _numChanMusic + _numChanSfx - _convertUnitSize;
+	int len = _song._numChanMusic + _song._numChanSfx - _song._convertUnitSize;
 	uint8 cur = 0x80 - ((volpara * 0x80) >> 8);
 	uint8 *dst = _sampleConvertBuffer;
 	uint16 fn = 0;
@@ -862,8 +944,8 @@ int HSLowLevelDriver::cmd_setVolume(va_list &arg) {
 	}
 
 	for (int i = 0; i < 256; ++i) {
-		memset(dst, cur, _convertUnitSize);
-		dst += _convertUnitSize;
+		memset(dst, cur, _song._convertUnitSize);
+		dst += _song._convertUnitSize;
 		fn += volpara;
 		cur += (fn >> 8);
 		fn &= 0xff;
@@ -879,7 +961,7 @@ int HSLowLevelDriver::cmd_setVolume(va_list &arg) {
 
 int HSLowLevelDriver::cmd_isSoundEffectPlaying(va_list &arg) {
 	const HSSoundSystem::HSSoundEffectVoice *vc = va_arg(arg, const HSSoundSystem::HSSoundEffectVoice*);
-	for (int i = _numChanMusic; i <_numChanMusic + _numChanSfx; ++i) {
+	for (int i = _song._numChanMusic; i < _song._numChanMusic + _song._numChanSfx; ++i) {
 		if (_chan[i].id == vc->resId)
 			return (_chan[i].status != -1) ? -1 : 0;
 	}
@@ -887,9 +969,9 @@ int HSLowLevelDriver::cmd_isSoundEffectPlaying(va_list &arg) {
 }
 
 int HSLowLevelDriver::cmd_reserveChannels(va_list &arg) {
-	_numChanMusic = va_arg(arg, int);
-	_convertUnitSize = va_arg(arg, int);
-	_numChanSfx = va_arg(arg, int);
+	_song._numChanMusic = va_arg(arg, int);
+	_song._convertUnitSize = va_arg(arg, int);
+	_song._numChanSfx = va_arg(arg, int);
 	createTables();
 
 	Common::StackLock lock(_mutex);
@@ -899,14 +981,14 @@ int HSLowLevelDriver::cmd_reserveChannels(va_list &arg) {
 }
 
 int HSLowLevelDriver::cmd_stopAllSoundEffects(va_list &arg) {
-	for (int i = _numChanMusic; i <_numChanMusic + _numChanSfx; ++i)
+	for (int i = _song._numChanMusic; i < _song._numChanMusic + _song._numChanSfx; ++i)
 		_chan[i].status = -1;
 	return 0;
 }
 
 int HSLowLevelDriver::cmd_resetSoundEffectRate(va_list &arg) {
 	const HSSoundSystem::HSSoundEffectVoice *vc = va_arg(arg, const HSSoundSystem::HSSoundEffectVoice*);
-	for (int i = _numChanMusic; i <_numChanMusic + _numChanSfx; ++i) {
+	for (int i = _song._numChanMusic; i < _song._numChanMusic + _song._numChanSfx; ++i) {
 		HSSoundChannel *chan = &_chan[i];
 		if (chan->status == -1 || chan->id != vc->resId)
 			continue;
@@ -980,19 +1062,19 @@ void HSLowLevelDriver::createTables() {
 
 	// sample convert buffer
 	if (_sampleConvertBuffer) {
-		if (_convertUnitSize != _convertUnitSizeLast || _numChanSfx != _numChanSfxLast || _convertBufferNumUnits - _numChanSfx != _numChanMusic) {
+		if (_song._convertUnitSize != _convertUnitSizeLast || _song._numChanSfx != _numChanSfxLast || _convertBufferNumUnits - _song._numChanSfx != _song._numChanMusic) {
 			delete[] _sampleConvertBuffer;
 			_sampleConvertBuffer = nullptr;
 		}
 	}
 
-	if (!_sampleConvertBuffer || _convertBufferNumUnits - _numChanSfx != _numChanMusic) {
-		_convertBufferNumUnits = _numChanMusic + _numChanSfx;
-		_convertUnitSizeLast = _convertUnitSize;
-		_numChanSfxLast = _numChanSfx;
+	if (!_sampleConvertBuffer || _convertBufferNumUnits - _song._numChanSfx != _song._numChanMusic) {
+		_convertBufferNumUnits = _song._numChanMusic + _song._numChanSfx;
+		_convertUnitSizeLast = _song._convertUnitSize;
+		_numChanSfxLast = _song._numChanSfx;
 		_sampleConvertBuffer = new uint8[(_convertBufferNumUnits << 8) + 64];
 		uint8 *dst = _sampleConvertBuffer;
-		int len = _convertBufferNumUnits - _convertUnitSize;
+		int len = _convertBufferNumUnits - _song._convertUnitSize;
 
 		if (len > 0) {
 			memset(dst, 0, len << 7);
@@ -1002,8 +1084,8 @@ void HSLowLevelDriver::createTables() {
 		}
 
 		for (int i = 0; i < 256; ++i) {
-			memset(dst, i & 0xff, _convertUnitSize);
-			dst += _convertUnitSize;
+			memset(dst, i & 0xff, _song._convertUnitSize);
+			dst += _song._convertUnitSize;
 		}
 
 		if (len > 0)
@@ -1015,7 +1097,7 @@ void HSLowLevelDriver::createTables() {
 	}
 
 	// ampitude scale buffer
-	if ((_amplitudeScaleFlags & 0x02) && !_amplitudeScaleBuffer) {
+	if ((_song._amplitudeScaleFlags & 0x02) && !_amplitudeScaleBuffer) {
 		_amplitudeScaleBuffer = new uint8[0x8000];
 		uint8 *dst = _amplitudeScaleBuffer;
 		for (uint16 i = 0; i < 128; ++i) {
@@ -1034,7 +1116,7 @@ void HSLowLevelDriver::createTables() {
 	}
 
 	// interpolation table
-	if ((_songFlags & 0x3000) && (_interpolationMode != kSimple) && !_interpolationTable) {
+	if ((_song._flags & 0x3000) && (_interpolationMode != kSimple) && !_interpolationTable) {
 		_interpolationTable = new uint8[0x20000];
 		uint8 *dst = _interpolationTable;
 		_interpolationTable2 = _interpolationTable + 0x10000;
@@ -1054,7 +1136,7 @@ void HSLowLevelDriver::createTables() {
 void HSLowLevelDriver::pcmNextTick() {
 	int16 cnt = 0;
 	uint16 val = 0;
-	for (int i = 0; i < _numChanMusic + _numChanSfx; ++i) {
+	for (int i = 0; i < _song._numChanMusic + _song._numChanSfx; ++i) {
 		++cnt;
 		if (_chan[i].status >= 0)
 			continue;
@@ -1063,7 +1145,7 @@ void HSLowLevelDriver::pcmNextTick() {
 	}
 
 	if (!cnt)
-		val = (_numChanMusic + _numChanSfx) << 7;
+		val = (_song._numChanMusic + _song._numChanSfx) << 7;
 
 	Common::fill<uint16*, uint16>(_transBuffer, &_transBuffer[_smpTransLen], val);
 
@@ -1075,7 +1157,7 @@ void HSLowLevelDriver::pcmNextTick() {
 	if (_midiMaxNotesPlayed < cnt)
 		_midiMaxNotesPlayed = cnt;
 
-	for (int i = 0; i < _numChanMusic + _numChanSfx; ++i) {
+	for (int i = 0; i < _song._numChanMusic + _song._numChanSfx; ++i) {
 		if (_chan[i].status < 0)
 			continue;
 		pcmUpdateChannel(_chan[i]);
@@ -1118,7 +1200,7 @@ void HSLowLevelDriver::pcmUpdateChannel(HSSoundChannel &chan) {
 				next = 1;
 			} else {
 				chan.status = -1;
-				if (!(_songFlags & 0x200) && ((int)chan.tickDataLen < (chan.dataEnd - chan.stateCur.dataPos))) {
+				if (!(_song._flags & 0x200) && ((int)chan.tickDataLen < (chan.dataEnd - chan.stateCur.dataPos))) {
 					chan.mode = -1;
 					chan.stateSaved = chan.stateCur;
 				}
@@ -1315,7 +1397,7 @@ template<typename T> void HSLowLevelDriver::fillBuffer(T *dst) {
 	const uint16 *src = _transBuffer;
 
 	if (sizeof(T) == 2) {
-		int16 offset = (int16)(_numChanMusic + _numChanSfx) << 7;
+		int16 offset = (int16)(_song._numChanMusic + _song._numChanSfx) << 7;
 		if (_updateTypeHq || _pcmDstBufferSize != 370) {
 			for (int i = 0; i < _pcmDstBufferSize; ++i)
 				*dst++ = (T)(*src++) - offset;
@@ -1358,7 +1440,7 @@ void HSLowLevelDriver::songStopChannel(int id) {
 			_trackState[i].status = '\0';
 	}
 
-	for (int i = 0; i <_numChanMusic; ++i)
+	for (int i = 0; i < _song._numChanMusic; ++i)
 		_chan[i].status = -1;
 }
 
@@ -1376,25 +1458,7 @@ bool HSLowLevelDriver::songInit() {
 	for (int i = 0; i < ARRAYSIZE(_midiPartProgram); ++i)
 		_midiPartProgram[i] = i;
 
-	assert(_songData.len >= 16);
-
-	uint16 midiResId = READ_BE_UINT16(_songData.ptr);
-	_sndInterpolateType = _songData.ptr[2];
-	_song_tickLen = READ_BE_UINT16(_songData.ptr + 4);
-	if (!_song_tickLen)
-		_song_tickLen = 16667;
-
-	_song_tempo = (500000u / _song_tickLen) & 0xffff;
-	_song_ticksPerSecond = 60;
-	updateTempo();
-
-	_song_transpose = READ_BE_INT16(_songData.ptr + 6);
-	_numChanSfx = _songData.ptr[8];
-	_numChanMusic = MIN<uint8>(_songData.ptr[9] + _numChanSfx, 16) - _numChanSfx;
-	_convertUnitSize = MIN<uint16>(READ_BE_UINT16(_songData.ptr + 10), 16);
-
-	_songFlags = READ_BE_UINT16(_songData.ptr + 12);
-	_amplitudeScaleFlags = _songData.ptr[15];
+	_song.reset();
 
 	const uint8 *in = _midiData.ptr;
 	const uint8 *end = &_midiData.ptr[_midiData.len];
@@ -1409,10 +1473,8 @@ bool HSLowLevelDriver::songInit() {
 		return false;
 
 	int tps = READ_BE_UINT16(in + 12);
-	if (tps >= 0) {
-		_song_ticksPerSecond = (uint32)tps;
-		updateTempo();
-	}
+	if (tps >= 0)
+		_song.setTicksPerSecond(tps);
 
 	while (in < end) {
 		if (READ_BE_UINT32(in) == 'MTrk')
@@ -1440,7 +1502,7 @@ bool HSLowLevelDriver::songInit() {
 
 		_trackState[ch].data = i;
 		_trackState[ch].curPos = i->ptr;
-		_trackState[ch].resId = midiResId;
+		_trackState[ch].resId = _song._midiResId;
 		_trackState[ch].status = 'F';
 		_trackState[ch].ticker = 0;
 		_trackState[ch].program = prg++;
@@ -1474,7 +1536,7 @@ void HSLowLevelDriver::midiNextTick() {
 			s->status = 'R';
 			checkPos = false;
 		} else {
-			s->ticker -= _song_internalTempo;
+			s->ticker -= _song.tempo();
 			if (s->ticker >= 0)
 				continue;
 		}
@@ -1512,10 +1574,6 @@ void HSLowLevelDriver::midiNextTick() {
 		songInit();
 }
 
-void HSLowLevelDriver::updateTempo() {
-	_song_internalTempo = _midiFastForward ? 32767 : ((_song_ticksPerSecond << 6) / _song_tempo);
-}
-
 bool HSLowLevelDriver::isMusicPlaying() {
 	if (!_midiBusy)
 		return false;
@@ -1542,8 +1600,7 @@ bool HSLowLevelDriver::midiParseEvent(MidiTrackState *s) {
 			s->status = '\0';
 			return false;
 		} else if (evt == 0x51) {
-			_song_tempo = (((uint32)s->curPos[1] << 16 | s->curPos[2] << 8 | s->curPos[3]) / _song_tickLen) & 0xffff;
-			updateTempo();
+			_song.setTempo(s->curPos[1] << 16 | s->curPos[2] << 8 | s->curPos[3]);
 		}
 
 		s->curPos += vlqRead(s->curPos);
@@ -1558,30 +1615,24 @@ bool HSLowLevelDriver::midiParseEvent(MidiTrackState *s) {
 
 	if (evt < 0xa0)
 		midiNoteOnOff(s, chan, arg1, evt == 0x90 ? arg2 : 0);
-	else if (evt == 0xc0 && (_songFlags & 0x400))
+	else if (evt == 0xc0 && (_song._flags & 0x400))
 		s->program = _midiPartProgram[chan] = arg1;
 
 	return true;
 }
 
 void HSLowLevelDriver::midiNoteOnOff(MidiTrackState *s, uint8 chan, uint8 note, uint8 velo) {
-	uint16 prg = (_songFlags & 0x800) ? s->program : _midiPartProgram[chan];
+	uint16 prg = (_song._flags & 0x800) ? s->program : _midiPartProgram[chan];
 
-	const uint8 *pos = _songData.ptr + 16;
-	uint16 cnt = READ_BE_UINT16(pos);
-	pos += 2;
-	assert(18 + cnt * 4 <= (int32)_songData.len);
-
-	while (cnt--) {
-		if (READ_BE_UINT16(pos) == prg) {
-			prg = READ_BE_UINT16(pos + 2);
+	for (Common::Array<uint16>::const_iterator i = _song._programMappings.begin(); i != _song._programMappings.end(); i += 2) {
+		if (prg == i[0]) {
+			prg = i[1];
 			break;
 		}
-		pos += 4;
 	}
 
-	if (note + _song_transpose > 0)
-		note += _song_transpose;
+	if (note + _song._transpose > 0)
+		note += _song._transpose;
 
 	if (velo)
 		noteOn(chan, prg, note, velo, 10000, s);
@@ -1590,7 +1641,7 @@ void HSLowLevelDriver::midiNoteOnOff(MidiTrackState *s, uint8 chan, uint8 note,
 }
 
 void HSLowLevelDriver::noteOn(uint8 part, uint8 prg, uint8 note, uint8 velo, uint16 ticker, const void *handle) {
-	if (_midiFastForward) {
+	if (_song._fastForward) {
 		_instruments[prg].status = InstrumentEntry::kRequestLoad;
 		return;
 	}
@@ -1661,16 +1712,16 @@ void HSLowLevelDriver::noteOn(uint8 part, uint8 prg, uint8 note, uint8 velo, uin
 	if (!snd)
 		return;
 
-	if (!(_amplitudeScaleFlags & 2) || (!(_amplitudeScaleFlags & 4) && !(flags2 & 0x40)))
+	if (!(_song._amplitudeScaleFlags & 2) || (!(_song._amplitudeScaleFlags & 4) && !(flags2 & 0x40)))
 		velo = 0;
 
-	if (!_numChanMusic)
+	if (!_song._numChanMusic)
 		return;
 
 	int busy = 0;
 	HSSoundChannel *chan = nullptr;
 
-	for (int i = 0; i < _numChanMusic && !chan; ++i) {
+	for (int i = 0; i < _song._numChanMusic && !chan; ++i) {
 		HSSoundChannel *c = &_chan[i];
 		if (c->status >= 0)
 			++busy;
@@ -1681,9 +1732,9 @@ void HSLowLevelDriver::noteOn(uint8 part, uint8 prg, uint8 note, uint8 velo, uin
 	}
 
 	if (!chan) {
-		int srchStatus = ((_songFlags & 0x4000) && (_convertUnitSize <= busy)) ? 0 : -1;
+		int srchStatus = ((_song._flags & 0x4000) && (_song._convertUnitSize <= busy)) ? 0 : -1;
 		for (int a = 0; a < 2 && !chan; ++a) {
-			for (int i = 0; i < _numChanMusic && !chan; ++i) {
+			for (int i = 0; i < _song._numChanMusic && !chan; ++i) {
 				HSSoundChannel *c = &_chan[i];
 				if (c->status == srchStatus)
 					chan = c;
@@ -1698,7 +1749,7 @@ void HSLowLevelDriver::noteOn(uint8 part, uint8 prg, uint8 note, uint8 velo, uin
 	chan->handle = handle;
 	chan->id = part;
 
-	if (!(_songFlags & 0x200)) {
+	if (!(_song._flags & 0x200)) {
 		chan->mode = 1;
 		if (chan->status >= 0 && chan->tickDataLen && (int)chan->tickDataLen < (chan->dataEnd - chan->stateCur.dataPos)) {
 			chan->mode = -1;
@@ -1729,11 +1780,11 @@ void HSLowLevelDriver::noteOn(uint8 part, uint8 prg, uint8 note, uint8 velo, uin
 	}
 
 	chan->numLoops = nullptr;
-	chan->imode = (!(flags & 0x8000) && (((_songFlags & 0x2000) || ((_songFlags & 0x1000) && (flags2 & 0x80 || _sndInterpolateType == n))))) ? _interpolationMode : kNone;
+	chan->imode = (!(flags & 0x8000) && (((_song._flags & 0x2000) || ((_song._flags & 0x1000) && (flags2 & 0x80 || _song._interpolateType == n))))) ? _interpolationMode : kNone;
 
 	chan->prg = prg;
 	chan->note = note;
-	chan->flags = _songFlags & 0x3f;
+	chan->flags = _song._flags & 0x3f;
 
 	if (flags & 0x4000) {
 		chan->stateCur.rate = 0x20000;
@@ -1747,7 +1798,7 @@ void HSLowLevelDriver::noteOn(uint8 part, uint8 prg, uint8 note, uint8 velo, uin
 
 	chan->pmRate = chan->stateCur.rate >> 10;
 
-	if ((flags & 0x200) && (_amplitudeScaleFlags & 0x10))
+	if ((flags & 0x200) && (_song._amplitudeScaleFlags & 0x10))
 		chan->stateCur.rate += ((chan->pmRate * noteFromTable()) >> 16);
 
 	chan->pmData = (const uint16*)_instruments[prg].pmData.ptr;
@@ -1763,12 +1814,12 @@ void HSLowLevelDriver::noteOn(uint8 part, uint8 prg, uint8 note, uint8 velo, uin
 }
 
 void HSLowLevelDriver::noteOff(uint8 part, uint8 note, const void *handle) {
-	for (int i = 0; i < _numChanMusic; ++i) {
+	for (int i = 0; i < _song._numChanMusic; ++i) {
 		HSSoundChannel *c = &_chan[i];
 		if (c->status < 0 || c->note != note || c->id != part || c->handle != handle)
 			continue;
 		c->status = 0;
-		c->flags = _songFlags & 0x3f;
+		c->flags = _song._flags & 0x3f;
 	}
 }
 
@@ -1813,6 +1864,7 @@ void HSLowLevelDriver::loadInstrument(int id) {
 		return;
 	}
 
+	_instruments[id]._noteRangeSubsets.clear();
 	for (int num = inst->readUint16BE(); num; --num) {
 		uint8 liml = inst->readByte();
 		uint8 limu = inst->readByte();
@@ -1842,7 +1894,7 @@ void HSLowLevelDriver::loadInstrument(int id) {
 
 ShStBuffer HSLowLevelDriver::loadInstrumentSamples(int id, bool sharedBuffer) {
 	if (sharedBuffer) {
-		for (Common::Array<InstrSamples>::const_iterator i = _instrumentSamples.begin(); i != _instrumentSamples.end(); ++i) {
+		for (Common::Array<InstrSamples>::const_iterator i = _instrumentsSharedSamples.begin(); i != _instrumentsSharedSamples.end(); ++i) {
 			if (i->_id == id)
 				return i->_resource;
 		}
@@ -1858,7 +1910,7 @@ ShStBuffer HSLowLevelDriver::loadInstrumentSamples(int id, bool sharedBuffer) {
 
 	ShStBuffer res(snd);
 	if (sharedBuffer)
-		_instrumentSamples.push_back(InstrSamples(id, res));
+		_instrumentsSharedSamples.push_back(InstrSamples(id, res));
 	delete snd;
 
 	return res;


Commit: a41f8b1de3edd7ac7678b5df598790abc2d83253
    https://github.com/scummvm/scummvm/commit/a41f8b1de3edd7ac7678b5df598790abc2d83253
Author: athrxx (athrxx at scummvm.org)
Date: 2021-11-17T20:07:01+01:00

Commit Message:
KYRA: (EOB/PC98) - improve final sequence (king scene) for enabled vsync option

Changed paths:
    engines/kyra/sequence/sequences_eob.cpp


diff --git a/engines/kyra/sequence/sequences_eob.cpp b/engines/kyra/sequence/sequences_eob.cpp
index a8bf723d1e..704acc29d2 100644
--- a/engines/kyra/sequence/sequences_eob.cpp
+++ b/engines/kyra/sequence/sequences_eob.cpp
@@ -1410,6 +1410,8 @@ void EoBPC98FinalePlayer::king() {
 	static uint8 xOff[] = { 0, 48, 96, 152 };
 	static uint8 maxW[] = { 48, 48, 56, 48 };
 
+	uint32 nextScreenUpdate = _vm->_system->getMillis();
+
 	for (int i = 0; i < 4 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
 		const uint8 *xypos = xydata;
 		uint16 cx = xOff[i];
@@ -1423,14 +1425,20 @@ void EoBPC98FinalePlayer::king() {
 			if (col)
 				_screen->setPagePixel(0, cx + x + 64, y + 84, col);
 			if (ii % 48 == 0) {
-				_screen->updateScreen();
 				uint32 cur = _vm->_system->getMillis();
+				if (cur >= nextScreenUpdate) {
+					_screen->updateScreen();
+					nextScreenUpdate += 16;
+				}
 				if (nextDelay > cur)
 					_vm->_system->delayMillis(nextDelay - cur);
 				nextDelay += 5;
 			}
 		}
-		_screen->updateScreen();
+		if (_vm->_system->getMillis() >= nextScreenUpdate) {
+			_screen->updateScreen();
+			nextScreenUpdate += 16;
+		}
 	}
 
 	printSubtitle(_strings[5], 9, 24, 225);


Commit: 8a2c97233e7805c7fa734574203330bce46f640b
    https://github.com/scummvm/scummvm/commit/8a2c97233e7805c7fa734574203330bce46f640b
Author: athrxx (athrxx at scummvm.org)
Date: 2021-11-17T20:07:01+01:00

Commit Message:
KYRA: (LoK/Mac) - more sound driver cleanup

(move more code and data to a new class)

Changed paths:
    engines/kyra/sound/drivers/halestorm.cpp


diff --git a/engines/kyra/sound/drivers/halestorm.cpp b/engines/kyra/sound/drivers/halestorm.cpp
index a6911bf58d..4714c605e7 100644
--- a/engines/kyra/sound/drivers/halestorm.cpp
+++ b/engines/kyra/sound/drivers/halestorm.cpp
@@ -164,7 +164,7 @@ public:
 class HSSong {
 public:
 	HSSong() : _data(), _flags(0), _amplitudeScaleFlags(0), _interpolateType(0), _transpose(0), _tickLen(0), _tempo(0), _ticksPerSecond(0), _internalTempo(0),
-		_numChanMusic(0), _numChanSfx(0), _convertUnitSize(0), _midiResId(0), _fastForward(false) {}
+		_numChanMusic(0), _numChanSfx(0), _convertUnitSize(0), _midiResId(0), _fastForward(false), _loop(false), _busy(false) {}
 	void load(const ShStBuffer &data);
 	void reset();
 	void release();
@@ -186,6 +186,9 @@ public:
 	int16 _transpose;
 	uint16 _tickLen;
 
+	bool _loop;
+	bool _busy;
+
 	Common::Array<uint16> _programMappings;
 	bool _fastForward;
 
@@ -199,7 +202,41 @@ private:
 	uint16 _internalTempo;
 };
 
+class HSMidiParser {
+public:
+	HSMidiParser(HSLowLevelDriver *driver);
+	~HSMidiParser();
+
+	bool loadTracks(HSSong &song);
+	bool nextTick(HSSong &song);
+	void stopResource(int id);
+	bool isPlaying() const;
+	void release();
+
+private:
+	struct TrackState {
+		Common::Array<ShStBuffer>::const_iterator data;
+		char status;
+		uint16 resId;
+		uint8 program;
+		int32 ticker;
+		const uint8 *curPos;
+	};
+
+	bool parseEvent(HSSong &song, TrackState *s);
+	void noteOnOff(HSSong &song, TrackState *s, uint8 chan, uint8 note, uint8 velo);
+
+	uint8 _partPrograms[16];
+	uint8 _curCmd;
+
+	ShStBuffer _data;
+	Common::Array<ShStBuffer> _tracks;
+	TrackState *_trackState;
+	HSLowLevelDriver *_driver;
+};
+
 class HSLowLevelDriver {
+	friend class HSMidiParser;
 public:
 	HSLowLevelDriver(SoundMacRes *res, Common::Mutex &mutex);
 	~HSLowLevelDriver();
@@ -306,43 +343,19 @@ private:
 	const uint16 _pcmDstBufferSize;
 
 private:
-	struct MidiTrackState {
-		Common::Array<ShStBuffer>::const_iterator data;
-		char status;
-		uint16 resId;
-		uint8 program;
-		int32 ticker;
-		const uint8 *curPos;
-	};
-
-	void songStopChannel(int id);
 	bool songStart();
 	bool songInit();
-	void midiNextTick();
-	bool isMusicPlaying();
-
-	bool midiParseEvent(MidiTrackState *s);
-	void midiNoteOnOff(MidiTrackState *s, uint8 chan, uint8 note, uint8 velo);
+	void songStopAllChannels();
+	void songNextTick();
+	bool songIsPlaying();
 
 	void noteOn(uint8 part, uint8 prg, uint8 note, uint8 velo, uint16 ticker, const void *handle);
 	void noteOff(uint8 part, uint8 note, const void *handle);
 
 	int16 noteFromTable();
 
-	bool _songLoop;
-	
-	ShStBuffer _midiData;
-	Common::Array<ShStBuffer> _midiTracks;
-
-	MidiTrackState *_trackState;
-	bool _midiBusy;
-	uint16 _midiMaxNotesPlayed;
-	uint32 _songTicker;
-	uint8 _midiCurCmd;
-
 	HSSong _song;
-
-	uint8 _midiPartProgram[16];
+	HSMidiParser *_midi;
 
 private:
 	void loadInstrument(int id);
@@ -642,11 +655,213 @@ void HSSong::updateTempo() {
 	_internalTempo = _fastForward ? 32767 : ((_ticksPerSecond << 6) / _tempo);
 }
 
-HSLowLevelDriver::HSLowLevelDriver(SoundMacRes *res, Common::Mutex &mutex) : _res(res), _vcstr(nullptr), _mutex(mutex), _sampleConvertBuffer(nullptr), _interpolationTable(nullptr), _transCycleLenDef(0),
-_interpolationTable2(nullptr), _amplitudeScaleBuffer(nullptr), _interpolationMode(kNone), _midiData(), _trackState(nullptr), _wtable(nullptr), _wtableCount(0),
-_midiCurCmd(0), _convertBufferNumUnits(0), _songLoop(false), _chan(nullptr), _samplesPerTick(0), _smpTransLen(0), _transCycleLenInter(0), _updateTypeHq(0), _instruments(nullptr),
-_midiBusy(false), _pcmDstBufferSize(370), _midiMaxNotesPlayed(0), _songTicker(0), _transBuffer(nullptr), _convertUnitSizeLast(0), _numChanSfxLast(0),
-_wtableCount2(0), _pmDataTrm(0x8000) {
+HSMidiParser::HSMidiParser(HSLowLevelDriver *driver) : _driver(driver), _trackState(nullptr), _tracks(), _data(), _curCmd(0) {
+	_trackState = new TrackState[24]();
+	memset(_partPrograms, 0, sizeof(_partPrograms));
+}
+
+HSMidiParser::~HSMidiParser() {
+	delete[] _trackState;
+}
+
+bool HSMidiParser::loadTracks(HSSong &song) {
+	for (int i = 0; i < ARRAYSIZE(_partPrograms); ++i)
+		_partPrograms[i] = i;
+
+	Common::SeekableReadStream *midi = _driver->_res->getResource(song._midiResId, 'MIDI');
+	if (!midi)
+		midi = _driver->_res->getResource(song._midiResId, 'Midi');
+	assert(midi);
+
+	_data = midi;
+	const uint8 *in = _data.ptr;
+	const uint8 *end = &_data.ptr[_data.len];
+	_tracks.clear();
+
+	while (in < end) {
+		if (READ_BE_UINT32(in) == 'MThd')
+			break;
+		in += 2;
+	}
+	if (in >= end)
+		return false;
+
+	int tps = READ_BE_UINT16(in + 12);
+	if (tps >= 0)
+		song.setTicksPerSecond(tps);
+
+	while (in < end) {
+		if (READ_BE_UINT32(in) == 'MTrk')
+			break;
+		++in;
+	}
+	if (in >= end)
+		return false;
+
+	do {
+		ShStBuffer track(in + 8, READ_BE_UINT32(in + 4));
+		_tracks.push_back(track);
+		in += (track.len + 8);
+	} while (in < end && READ_BE_UINT32(in) == 'MTrk');
+
+	uint8 prg = 0;
+	for (Common::Array<ShStBuffer>::const_iterator i = _tracks.begin(); i != _tracks.end(); ++i) {
+		int ch = 0;
+		for (; ch < 24; ++ch) {
+			if (!_trackState[ch].status)
+				break;
+		}
+		if (ch == 24)
+			return false;
+
+		_trackState[ch].data = i;
+		_trackState[ch].curPos = i->ptr;
+		_trackState[ch].resId = song._midiResId;
+		_trackState[ch].status = 'F';
+		_trackState[ch].ticker = 0;
+		_trackState[ch].program = prg++;
+	}
+
+	return true;
+}
+
+uint32 vlqRead(const uint8 *&s) {
+	uint32 res = 0;
+	do {
+		res = (res << 7) | (*s & 0x7f);
+	} while (*s++ & 0x80);
+	return res;
+}
+
+bool HSMidiParser::nextTick(HSSong &song) {
+	bool res = false;
+	for (int ch = 0; ch < 24; ++ch) {
+		TrackState *s = &_trackState[ch];
+		if (!s->status)
+			continue;
+
+		res = true;
+		bool checkPos = true;
+
+		if (s->status == 'F') {
+			s->status = 'R';
+			checkPos = false;
+		} else {
+			s->ticker -= song.tempo();
+			if (s->ticker >= 0)
+				continue;
+		}
+
+		bool contMain = false;
+		for (bool checkTicker = true; checkPos || checkTicker; ) {
+			if (checkPos) {
+				if (s->curPos >= &s->data->ptr[s->data->len]) {
+					s->status = '\0';
+					contMain = true;
+					break;
+				}
+				contMain = !parseEvent(song, s);
+			}
+
+			if (contMain)
+				break;
+
+			checkPos = false;
+
+			uint32 val = vlqRead(s->curPos);
+			if (val) {
+				s->ticker += (val << 6);
+				if (s->ticker >= 0)
+					checkTicker = false;
+				else
+					checkPos = true;
+			} else {
+				checkTicker = parseEvent(song, s);
+			}
+		}
+	}
+	return res;
+}
+
+void HSMidiParser::stopResource(int id) {
+	for (int i = 0; i < 24; ++i) {
+		if (id < 0 || _trackState[i].resId == id)
+			_trackState[i].status = '\0';
+	}
+
+	_driver->songStopAllChannels();
+}
+
+bool HSMidiParser::isPlaying() const {
+	for (int ch = 0; ch < 24; ++ch) {
+		if (_trackState[ch].status)
+			return true;
+	}
+	return false;
+}
+
+void HSMidiParser::release() {
+	_data = ShStBuffer();
+}
+
+bool HSMidiParser::parseEvent(HSSong &song, TrackState *s) {
+	uint8 in = *s->curPos++;
+
+	if (in < 0x80) {
+		if (s->curPos <= s->data->ptr)
+			error("HSLowLevelDriver::midiParseEvent(): Data error");
+		s->curPos--;
+		in = _curCmd;
+	} else if (in == 0xff) {
+		uint evt = *s->curPos++;
+		if (evt == 0x2f) {
+			s->status = '\0';
+			return false;
+		} else if (evt == 0x51) {
+			song.setTempo(s->curPos[1] << 16 | s->curPos[2] << 8 | s->curPos[3]);
+		}
+
+		s->curPos += vlqRead(s->curPos);
+		return true;
+	}
+
+	_curCmd = in;
+	uint8 evt = in & 0xf0;
+	uint8 chan = in & 0x0f;
+	uint8 arg1 = *s->curPos++;
+	uint8 arg2 = (evt > 0xb0 && evt < 0xe0) ? 0 : *s->curPos++;
+
+	if (evt < 0xa0)
+		noteOnOff(song, s, chan, arg1, evt == 0x90 ? arg2 : 0);
+	else if (evt == 0xc0 && (song._flags & 0x400))
+		s->program = _partPrograms[chan] = arg1;
+
+	return true;
+}
+
+void HSMidiParser::noteOnOff(HSSong &song, TrackState *s, uint8 chan, uint8 note, uint8 velo) {
+	uint16 prg = (song._flags & 0x800) ? s->program : _partPrograms[chan];
+
+	for (Common::Array<uint16>::const_iterator i = song._programMappings.begin(); i != song._programMappings.end(); i += 2) {
+		if (prg == i[0]) {
+			prg = i[1];
+			break;
+		}
+	}
+
+	if (note + song._transpose > 0)
+		note += song._transpose;
+
+	if (velo)
+		_driver->noteOn(chan, prg, note, velo, 10000, s);
+	else
+		_driver->noteOff(chan, note, s);
+}
+
+HSLowLevelDriver::HSLowLevelDriver(SoundMacRes *res, Common::Mutex &mutex) : _res(res), _vcstr(nullptr), _mutex(mutex), _sampleConvertBuffer(nullptr), _interpolationTable(nullptr),
+_transCycleLenDef(0), _interpolationTable2(nullptr), _amplitudeScaleBuffer(nullptr), _interpolationMode(kNone), _wtable(nullptr), _wtableCount(0), _midi(nullptr),
+_convertBufferNumUnits(0), _chan(nullptr), _samplesPerTick(0), _smpTransLen(0), _transCycleLenInter(0), _updateTypeHq(0), _instruments(nullptr), _pcmDstBufferSize(370),
+_transBuffer(nullptr), _convertUnitSizeLast(0), _numChanSfxLast(0), _wtableCount2(0), _pmDataTrm(0x8000) {
 #define HSOPC(x)	_hsOpcodes.push_back(new HSOpcode(this, &HSLowLevelDriver::x))
 	HSOPC(cmd_startSong);
 	HSOPC(cmd_stopSong);
@@ -693,8 +908,8 @@ HSLowLevelDriver::~HSLowLevelDriver() {
 	delete[] _transBuffer;
 	delete[] _wtable;
 	delete[] _instruments;
-	delete[] _trackState;
 	delete[] _chan;
+	delete _midi;
 
 	for (Common::Array<HSOpcode*>::iterator i = _hsOpcodes.begin(); i != _hsOpcodes.end(); ++i)
 		delete *i;
@@ -708,17 +923,14 @@ HSAudioStream *HSLowLevelDriver::init(uint32 scummVMOutputrate, bool output16bit
 
 	_instruments = new InstrumentEntry[128]();
 
-	_trackState = new MidiTrackState[24];
-	memset(_trackState, 0, 24 * sizeof(MidiTrackState));
-
-	memset(_midiPartProgram, 0, sizeof(_midiPartProgram));
-
 	_transBuffer = new uint16[750];
 	memset(_transBuffer, 0, 750 * sizeof(uint16));
 
 	_wtable = new int16[17];
 	memset(_wtable, 0, 17 * sizeof(int16));
 
+	_midi = new HSMidiParser(this);
+
 	_vcstr = new HSAudioStream(this, scummVMOutputrate, ASC_DEVICE_RATE, _pcmDstBufferSize, output16bit);
 	return _vcstr;
 }
@@ -738,7 +950,7 @@ int HSLowLevelDriver::send(int cmd, ...) {
 
 template<typename T> void HSLowLevelDriver::generateData(T *dst, uint32 len) {
 	pcmNextTick();
-	midiNextTick();
+	songNextTick();
 	fillBuffer<T>(dst);
 }
 
@@ -756,31 +968,30 @@ int HSLowLevelDriver::cmd_startSong(va_list &arg) {
 	song->seek(0);
 	_song.load(ShStBuffer(song));
 	delete song;
-	_midiData = midi;
 	delete midi;
 
 	for (int i = 0; i < 128; ++i)
 		_instruments[i].status = InstrumentEntry::kUnusable;
 
 	_song._fastForward = true;
-	songStopChannel(-1);
+	_midi->stopResource(-1);
 	if (!songStart())
 		error("HSLowLevelDriver::cmd_startSong(): Error reading song data.");
 
 	// Fast-forward through the whole song to check which instruments need to be loaded
-	bool loop = _songLoop;
-	_songLoop = false;
-	_midiBusy = true;
-	for (bool lp = true; lp; lp = isMusicPlaying())
-		midiNextTick();
-
-	_songLoop = loop;
-	_midiBusy = _song._fastForward = false;
+	bool loop = _song._loop;
+	_song._loop = false;
+	_song._busy = true;
+	for (bool lp = true; lp; lp = songIsPlaying())
+		songNextTick();
+
+	_song._loop = loop;
+	_song._busy = _song._fastForward = false;
 	for (int i = 0; i < 128; ++i)
 		loadInstrument(i);
 
-	_midiBusy = true;
-	songStopChannel(-1);
+	_song._busy = true;
+	_midi->stopResource(-1);
 	if (!songStart())
 		error("HSLowLevelDriver::cmd_startSong(): Error reading song data.");
 
@@ -790,7 +1001,7 @@ int HSLowLevelDriver::cmd_startSong(va_list &arg) {
 }
 
 int HSLowLevelDriver::cmd_stopSong(va_list &arg) {
-	songStopChannel(-1);
+	_midi->stopResource(-1);
 	return 0;
 }
 
@@ -804,12 +1015,12 @@ int HSLowLevelDriver::cmd_getDriverStatus(va_list &arg) {
 }
 
 int HSLowLevelDriver::cmd_getSongStatus(va_list &arg) {
-	return isMusicPlaying() ? -1 : 0;
+	return songIsPlaying() ? -1 : 0;
 }
 
 int HSLowLevelDriver::cmd_stopSong2(va_list &arg) {
-	_songLoop = false;
-	songStopChannel(-1);
+	_song._loop = false;
+	_midi->stopResource(-1);
 	return 0;
 }
 
@@ -820,12 +1031,12 @@ int HSLowLevelDriver::smd_stopSong3(va_list &arg) {
 }
 
 int HSLowLevelDriver::cmd_releaseSongData(va_list &arg) {
-	_midiBusy = false;
+	_song._busy = false;
 	for (int i = 0; i < _song._numChanMusic; ++i)
 		_chan[i].status = -1;
 
 	_song.release();
-	_midiData = ShStBuffer();
+	_midi->release();
 	_instrumentsSharedSamples.clear();
 
 	for (int i = 0; i < 128; ++i) {
@@ -865,7 +1076,7 @@ int HSLowLevelDriver::cmd_12(va_list &arg) {
 }
 
 int HSLowLevelDriver::cmd_setLoop(va_list &arg) {
-	_songLoop = va_arg(arg, int);
+	_song._loop = va_arg(arg, int);
 	return 0;
 }
 
@@ -1129,8 +1340,6 @@ void HSLowLevelDriver::createTables() {
 				*dst++ = ((i * ii) + 0x80) >> 8;
 		}
 	}
-
-	_songTicker = 0;
 }
 
 void HSLowLevelDriver::pcmNextTick() {
@@ -1149,13 +1358,8 @@ void HSLowLevelDriver::pcmNextTick() {
 
 	Common::fill<uint16*, uint16>(_transBuffer, &_transBuffer[_smpTransLen], val);
 
-	if (!cnt) {
-		++_songTicker;
+	if (!cnt)
 		return;
-	}
-
-	if (_midiMaxNotesPlayed < cnt)
-		_midiMaxNotesPlayed = cnt;
 
 	for (int i = 0; i < _song._numChanMusic + _song._numChanSfx; ++i) {
 		if (_chan[i].status < 0)
@@ -1381,7 +1585,6 @@ void HSLowLevelDriver::pcmUpdateChannel(HSSoundChannel &chan) {
 
 	chan.stateCur.phase = ih & 0xffff;
 	chan.stateCur.dataPos = src;
-	++_songTicker;
 }
 
 #undef HS_CYCL_DEF
@@ -1434,210 +1637,41 @@ template<typename T> void HSLowLevelDriver::fillBuffer(T *dst) {
 	}
 }
 
-void HSLowLevelDriver::songStopChannel(int id) {
-	for (int i = 0; i < 24; ++i) {
-		if (id < 0 || _trackState[i].resId == id)
-			_trackState[i].status = '\0';
-	}
-
-	for (int i = 0; i < _song._numChanMusic; ++i)
-		_chan[i].status = -1;
-}
-
 bool HSLowLevelDriver::songStart() {
 	if (!songInit())
 		return false;
 	createTables();
-	_songTicker = 0;
 
 	return true;
 }
 
 bool HSLowLevelDriver::songInit() {
-	_midiMaxNotesPlayed = 0;
-	for (int i = 0; i < ARRAYSIZE(_midiPartProgram); ++i)
-		_midiPartProgram[i] = i;
-
 	_song.reset();
-
-	const uint8 *in = _midiData.ptr;
-	const uint8 *end = &_midiData.ptr[_midiData.len];
-	_midiTracks.clear();
-
-	while (in < end) {
-		if (READ_BE_UINT32(in) == 'MThd')
-			break;
-		in += 2;
-	}
-	if (in >= end)
-		return false;
-
-	int tps = READ_BE_UINT16(in + 12);
-	if (tps >= 0)
-		_song.setTicksPerSecond(tps);
-
-	while (in < end) {
-		if (READ_BE_UINT32(in) == 'MTrk')
-			break;
-		++in;
-	}
-	if (in >= end)
-		return false;
-
-	do {
-		ShStBuffer track(in + 8, READ_BE_UINT32(in + 4));
-		_midiTracks.push_back(track);
-		in += (track.len + 8);
-	} while (in < end && READ_BE_UINT32(in) == 'MTrk');
-
-	uint8 prg = 0;
-	for (Common::Array<ShStBuffer>::const_iterator i = _midiTracks.begin(); i != _midiTracks.end(); ++i) {
-		int ch = 0;
-		for (; ch < 24; ++ch) {
-			if (!_trackState[ch].status)
-				break;
-		}
-		if (ch == 24)
-			return false;
-
-		_trackState[ch].data = i;
-		_trackState[ch].curPos = i->ptr;
-		_trackState[ch].resId = _song._midiResId;
-		_trackState[ch].status = 'F';
-		_trackState[ch].ticker = 0;
-		_trackState[ch].program = prg++;
-	}
-
-	return true;
+	return _midi->loadTracks(_song);
 }
 
-uint32 vlqRead(const uint8 *&s) {
-	uint32 res = 0;
-	do {
-		res = (res << 7) | (*s & 0x7f);
-	} while (*s++ & 0x80);
-	return res;
+void HSLowLevelDriver::songStopAllChannels() {
+	for (int i = 0; i < _song._numChanMusic; ++i)
+		_chan[i].status = -1;
 }
 
-void HSLowLevelDriver::midiNextTick() {
-	if (!_midiBusy)
+void HSLowLevelDriver::songNextTick() {
+	if (!_song._busy)
 		return;
 
-	bool foundActiveTrack = false;
-	for (int ch = 0; ch < 24; ++ch) {
-		MidiTrackState *s = &_trackState[ch];
-		if (!s->status)
-			continue;
-
-		foundActiveTrack = true;
-		bool checkPos = true;
-
-		if (s->status == 'F') {
-			s->status = 'R';
-			checkPos = false;
-		} else {
-			s->ticker -= _song.tempo();
-			if (s->ticker >= 0)
-				continue;
-		}
+	bool active = _midi->nextTick(_song);
 
-		bool contMain = false;
-		for (bool checkTicker = true; checkPos || checkTicker; ) {
-			if (checkPos) {
-				if (s->curPos >= &s->data->ptr[s->data->len]) {
-					s->status = '\0';
-					contMain = true;
-					break;
-				}
-				contMain = !midiParseEvent(s);
-			}
-
-			if (contMain)
-				break;
-
-			checkPos = false;
-
-			uint32 val = vlqRead(s->curPos);
-			if (val) {
-				s->ticker += (val << 6);
-				if (s->ticker >= 0)
-					checkTicker = false;
-				else
-					checkPos = true;
-			} else {
-				checkTicker = midiParseEvent(s);
-			}
-		}
-	}
-
-	if (!foundActiveTrack && _songLoop)
+	if (!active && _song._loop)
 		songInit();
 }
 
-bool HSLowLevelDriver::isMusicPlaying() {
-	if (!_midiBusy)
+bool HSLowLevelDriver::songIsPlaying() {
+	if (!_song._busy)
 		return false;
-	if (_songLoop)
-		return true;
-	for (int ch = 0; ch < 24; ++ch) {
-		if (_trackState[ch].status)
-			return true;
-	}
-	return false;
-}
-
-bool HSLowLevelDriver::midiParseEvent(MidiTrackState *s) {
-	uint8 in = *s->curPos++;
-
-	if (in < 0x80) {
-		if (s->curPos <= s->data->ptr)
-			error("HSLowLevelDriver::midiParseEvent(): Data error");
-		s->curPos--;
-		in = _midiCurCmd;
-	} else if (in == 0xff) {
-		uint evt = *s->curPos++;
-		if (evt == 0x2f) {
-			s->status = '\0';
-			return false;
-		} else if (evt == 0x51) {
-			_song.setTempo(s->curPos[1] << 16 | s->curPos[2] << 8 | s->curPos[3]);
-		}
-
-		s->curPos += vlqRead(s->curPos);
+	if (_song._loop)
 		return true;
-	}
-
-	_midiCurCmd = in;
-	uint8 evt = in & 0xf0;
-	uint8 chan = in & 0x0f;
-	uint8 arg1 = *s->curPos++;
-	uint8 arg2 = (evt > 0xb0 && evt < 0xe0) ? 0 : *s->curPos++;
-
-	if (evt < 0xa0)
-		midiNoteOnOff(s, chan, arg1, evt == 0x90 ? arg2 : 0);
-	else if (evt == 0xc0 && (_song._flags & 0x400))
-		s->program = _midiPartProgram[chan] = arg1;
-
-	return true;
-}
 
-void HSLowLevelDriver::midiNoteOnOff(MidiTrackState *s, uint8 chan, uint8 note, uint8 velo) {
-	uint16 prg = (_song._flags & 0x800) ? s->program : _midiPartProgram[chan];
-
-	for (Common::Array<uint16>::const_iterator i = _song._programMappings.begin(); i != _song._programMappings.end(); i += 2) {
-		if (prg == i[0]) {
-			prg = i[1];
-			break;
-		}
-	}
-
-	if (note + _song._transpose > 0)
-		note += _song._transpose;
-
-	if (velo)
-		noteOn(chan, prg, note, velo, 10000, s);
-	else
-		noteOff(chan, note, s);
+	return _midi->isPlaying();
 }
 
 void HSLowLevelDriver::noteOn(uint8 part, uint8 prg, uint8 note, uint8 velo, uint16 ticker, const void *handle) {


Commit: 7ce98275a2ca06aa23c745a13a4aeda629d96bbc
    https://github.com/scummvm/scummvm/commit/7ce98275a2ca06aa23c745a13a4aeda629d96bbc
Author: athrxx (athrxx at scummvm.org)
Date: 2021-11-17T20:07:01+01:00

Commit Message:
SCUMM: fix unused var warning

Changed paths:
    engines/scumm/sound.cpp


diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 5792e08bb0..5c4be46f9a 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -563,8 +563,8 @@ void Sound::startTalkSound(uint32 offset, uint32 b, int mode, Audio::SoundHandle
 		}
 
 		file->seek(0, SEEK_END);
-		int fileSize = file->pos();
 #if defined(ENABLE_SCUMM_7_8)
+		int fileSize = file->pos();
 		_vm->_imuseDigital->startVoice(filename, file.release(), 0, fileSize);
 #endif
 		return;




More information about the Scummvm-git-logs mailing list