aboutsummaryrefslogtreecommitdiff
path: root/queen/music.cpp
diff options
context:
space:
mode:
authorGregory Montoir2004-12-31 00:25:18 +0000
committerGregory Montoir2004-12-31 00:25:18 +0000
commita44e8248159fc836f9d534872b0d55741f0c803c (patch)
tree47df2cacddf071f0ff1c8a761b3038acc0d8c7d1 /queen/music.cpp
parentf06348440fd2040cb8bf57849c7e6670db91caf0 (diff)
downloadscummvm-rg350-a44e8248159fc836f9d534872b0d55741f0c803c.tar.gz
scummvm-rg350-a44e8248159fc836f9d534872b0d55741f0c803c.tar.bz2
scummvm-rg350-a44e8248159fc836f9d534872b0d55741f0c803c.zip
added some comments and re-indented some parts of code
svn-id: r16394
Diffstat (limited to 'queen/music.cpp')
-rw-r--r--queen/music.cpp539
1 files changed, 266 insertions, 273 deletions
diff --git a/queen/music.cpp b/queen/music.cpp
index c52974a757..15b6596299 100644
--- a/queen/music.cpp
+++ b/queen/music.cpp
@@ -42,322 +42,315 @@ static const byte mt32_to_gm[128] = {
47, 117, 127, 118, 118, 116, 115, 119, 115, 112, 55, 124, 123, 0, 14, 117 // 7x
};
- MusicPlayer::MusicPlayer(MidiDriver *driver, byte *data, uint32 size) : _driver(driver), _isPlaying(false), _looping(false), _randomLoop(false), _masterVolume(192), _queuePos(0), _musicData(data), _musicDataSize(size), _passThrough(false), _buf(0) {
- memset(_channel, 0, sizeof(_channel));
- queueClear();
- _lastSong = _currentSong = 0;
- _parser = MidiParser::createParser_SMF();
- _parser->setMidiDriver(this);
- _parser->setTimerRate(_driver->getBaseTempo());
-
- _numSongs = READ_LE_UINT16(_musicData);
- this->open();
- }
+MusicPlayer::MusicPlayer(MidiDriver *driver, byte *data, uint32 size) : _driver(driver), _isPlaying(false), _looping(false), _randomLoop(false), _masterVolume(192), _queuePos(0), _musicData(data), _musicDataSize(size), _passThrough(false), _buf(0) {
+ memset(_channel, 0, sizeof(_channel));
+ queueClear();
+ _lastSong = _currentSong = 0;
+ _parser = MidiParser::createParser_SMF();
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
- MusicPlayer::~MusicPlayer() {
- _parser->unloadMusic();
- delete _parser;
- this->close();
- delete[] _buf;
- }
+ _numSongs = READ_LE_UINT16(_musicData);
+ this->open();
+}
+
+MusicPlayer::~MusicPlayer() {
+ _parser->unloadMusic();
+ delete _parser;
+ this->close();
+ delete[] _buf;
+}
+
+void MusicPlayer::setVolume(int volume) {
+ if (volume < 0)
+ volume = 0;
+ else if (volume > 255)
+ volume = 255;
- void MusicPlayer::setVolume(int volume) {
- if (volume < 0)
- volume = 0;
- else if (volume > 255)
- volume = 255;
-
- if (_masterVolume == volume)
+ if (_masterVolume == volume)
return;
-
- _masterVolume = volume;
-
- for (int i = 0; i < 16; ++i) {
- if (_channel[i])
- _channel[i]->volume(_channelVolume[i] * _masterVolume / 255);
- }
- }
- bool MusicPlayer::queueSong(uint16 songNum) {
- if (songNum >= _numSongs && songNum < 1000) {
- // this happens at the end of the car chase, where we try to play song 176,
- // see Sound::_tune[], entry 39
- warning("Trying to queue an invalid song number %d, max %d", songNum, _numSongs);
- return false;
- }
-
- uint8 emptySlots = 0;
- for (int i = 0; i < MUSIC_QUEUE_SIZE; i++)
- if (!_songQueue[i])
- emptySlots++;
-
- if (!emptySlots)
- return false;
-
- // Work around bug in Roland music, note that these numbers are 'one-off'
- // from the original code
- if (/*isRoland && */ songNum == 88 || songNum == 89)
- songNum = 62;
-
- _songQueue[MUSIC_QUEUE_SIZE - emptySlots] = songNum;
- return true;
- }
+ _masterVolume = volume;
- void MusicPlayer::queueClear() {
- _lastSong = _songQueue[0];
- _queuePos = 0;
- _looping = _randomLoop = false;
- memset(_songQueue, 0, sizeof(_songQueue));
+ for (int i = 0; i < 16; ++i) {
+ if (_channel[i])
+ _channel[i]->volume(_channelVolume[i] * _masterVolume / 255);
}
+}
+
+bool MusicPlayer::queueSong(uint16 songNum) {
+ if (songNum >= _numSongs && songNum < 1000) {
+ // this happens at the end of the car chase, where we try to play song 176,
+ // see Sound::_tune[], entry 39
+ warning("Trying to queue an invalid song number %d, max %d", songNum, _numSongs);
+ return false;
+ }
+ uint8 emptySlots = 0;
+ for (int i = 0; i < MUSIC_QUEUE_SIZE; i++)
+ if (!_songQueue[i])
+ emptySlots++;
- int MusicPlayer::open() {
- // Don't ever call open without first setting the output driver!
- if (!_driver)
- return 255;
+ if (!emptySlots)
+ return false;
+
+ // Work around bug in Roland music, note that these numbers are 'one-off'
+ // from the original code
+ if (/*isRoland && */ songNum == 88 || songNum == 89)
+ songNum = 62;
+
+ _songQueue[MUSIC_QUEUE_SIZE - emptySlots] = songNum;
+ return true;
+}
+
+void MusicPlayer::queueClear() {
+ _lastSong = _songQueue[0];
+ _queuePos = 0;
+ _looping = _randomLoop = false;
+ memset(_songQueue, 0, sizeof(_songQueue));
+}
+
+int MusicPlayer::open() {
+ // Don't ever call open without first setting the output driver!
+ if (!_driver)
+ return 255;
- int ret = _driver->open();
- if (ret)
- return ret;
- _driver->setTimerCallback(this, &onTimer);
- return 0;
- }
+ int ret = _driver->open();
+ if (ret)
+ return ret;
+ _driver->setTimerCallback(this, &onTimer);
+ return 0;
+}
+
+void MusicPlayer::close() {
+ _driver->setTimerCallback(NULL, NULL);
+ if (_driver)
+ _driver->close();
+ _driver = 0;
+}
- void MusicPlayer::close() {
- _driver->setTimerCallback(NULL, NULL);
- if (_driver)
- _driver->close();
- _driver = 0;
+void MusicPlayer::send(uint32 b) {
+ if (_passThrough) {
+ _driver->send(b);
+ return;
}
- void MusicPlayer::send(uint32 b) {
- if (_passThrough) {
- _driver->send(b);
+ byte channel = (byte)(b & 0x0F);
+ if ((b & 0xFFF0) == 0x07B0) {
+ // Adjust volume changes by master volume
+ byte volume = (byte)((b >> 16) & 0x7F);
+ _channelVolume[channel] = volume;
+ volume = volume * _masterVolume / 255;
+ b = (b & 0xFF00FFFF) | (volume << 16);
+ } else if ((b & 0xF0) == 0xC0 && !_nativeMT32) {
+ b = (b & 0xFFFF00FF) | mt32_to_gm[(b >> 8) & 0xFF] << 8;
+ }
+ else if ((b & 0xFFF0) == 0x007BB0) {
+ //Only respond to All Notes Off if this channel
+ //has currently been allocated
+ if (_channel[b & 0x0F])
return;
- }
-
- byte channel = (byte)(b & 0x0F);
- if ((b & 0xFFF0) == 0x07B0) {
- // Adjust volume changes by master volume
- byte volume = (byte)((b >> 16) & 0x7F);
- _channelVolume[channel] = volume;
- volume = volume * _masterVolume / 255;
- b = (b & 0xFF00FFFF) | (volume << 16);
- } else if ((b & 0xF0) == 0xC0 && !_nativeMT32) {
- b = (b & 0xFFFF00FF) | mt32_to_gm[(b >> 8) & 0xFF] << 8;
- }
- else if ((b & 0xFFF0) == 0x007BB0) {
- //Only respond to All Notes Off if this channel
- //has currently been allocated
- if (_channel[b & 0x0F])
- return;
- }
-
- //Work around annoying loud notes in certain Roland Floda tunes
- if (channel == 3 && _currentSong == 90)
- return;
- if (channel == 4 && _currentSong == 27)
- return;
- if (channel == 5 && _currentSong == 38)
- return;
-
- if (!_channel[channel])
- _channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
-
- if (_channel[channel])
- _channel[channel]->send(b);
}
- void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) {
- //Only thing we care about is End of Track.
- if (type != 0x2F)
- return;
+ //Work around annoying loud notes in certain Roland Floda tunes
+ if (channel == 3 && _currentSong == 90)
+ return;
+ if (channel == 4 && _currentSong == 27)
+ return;
+ if (channel == 5 && _currentSong == 38)
+ return;
- if (_looping || _songQueue[1])
- playMusic();
- else
- stopMusic();
- }
+ if (!_channel[channel])
+ _channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
- void MusicPlayer::onTimer(void *refCon) {
- MusicPlayer *music = (MusicPlayer *)refCon;
- if (music->_isPlaying)
- music->_parser->onTimer();
- }
+ if (_channel[channel])
+ _channel[channel]->send(b);
+}
+
+void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) {
+ //Only thing we care about is End of Track.
+ if (type != 0x2F)
+ return;
- void MusicPlayer::queueTuneList(int16 tuneList) {
- queueClear();
-
- //Jungle is the only part of the game that uses multiple tunelists.
- //For the sake of code simplification we just hardcode the extended list ourselves
- if ((tuneList + 1) == 3) {
- _randomLoop = true;
- int i = 0;
- while (Sound::_jungleList[i])
- queueSong(Sound::_jungleList[i++] - 1);
- return;
- }
+ if (_looping || _songQueue[1])
+ playMusic();
+ else
+ stopMusic();
+}
+
+void MusicPlayer::onTimer(void *refCon) {
+ MusicPlayer *music = (MusicPlayer *)refCon;
+ if (music->_isPlaying)
+ music->_parser->onTimer();
+}
+
+void MusicPlayer::queueTuneList(int16 tuneList) {
+ queueClear();
+
+ //Jungle is the only part of the game that uses multiple tunelists.
+ //For the sake of code simplification we just hardcode the extended list ourselves
+ if ((tuneList + 1) == 3) {
+ _randomLoop = true;
+ int i = 0;
+ while (Sound::_jungleList[i])
+ queueSong(Sound::_jungleList[i++] - 1);
+ return;
+ }
- int mode = (_numSongs == 40) ? Sound::_tuneDemo[tuneList].mode : Sound::_tune[tuneList].mode;
- switch (mode) {
- //Random loop
- case 0:
- _randomLoop = true;
- setLoop(false);
- break;
- //Sequential loop
- case 1:
- setLoop(_songQueue[1] == 0);
- break;
- //Play once
- case 2:
- default:
- setLoop(false);
- break;
- }
+ int mode = (_numSongs == 40) ? Sound::_tuneDemo[tuneList].mode : Sound::_tune[tuneList].mode;
+ switch (mode) {
+ case 0: // random loop
+ _randomLoop = true;
+ setLoop(false);
+ break;
+ case 1: // sequential loop
+ setLoop(_songQueue[1] == 0);
+ break;
+ case 2: // play once
+ default:
+ setLoop(false);
+ break;
+ }
- int i = 0;
- if (_numSongs == 40) {
- while (Sound::_tuneDemo[tuneList].tuneNum[i])
- queueSong(Sound::_tuneDemo[tuneList].tuneNum[i++] - 1);
- } else {
- while (Sound::_tune[tuneList].tuneNum[i])
- queueSong(Sound::_tune[tuneList].tuneNum[i++] - 1);
- }
-
- if (_randomLoop)
- _queuePos = randomQueuePos();
+ int i = 0;
+ if (_numSongs == 40) {
+ while (Sound::_tuneDemo[tuneList].tuneNum[i])
+ queueSong(Sound::_tuneDemo[tuneList].tuneNum[i++] - 1);
+ } else {
+ while (Sound::_tune[tuneList].tuneNum[i])
+ queueSong(Sound::_tune[tuneList].tuneNum[i++] - 1);
}
- void MusicPlayer::playMusic() {
- if (!_songQueue[0]) {
- debug(5, "MusicPlayer::playMusic - Music queue is empty!");
- return;
- }
+ if (_randomLoop)
+ _queuePos = randomQueuePos();
+}
- uint16 songNum = _songQueue[_queuePos];
+void MusicPlayer::playMusic() {
+ if (!_songQueue[0]) {
+ debug(5, "MusicPlayer::playMusic - Music queue is empty!");
+ return;
+ }
+
+ uint16 songNum = _songQueue[_queuePos];
- //Special type
- // > 1000 && < 2000 -> queue different tunelist
- // 2000 -> repeat music from previous queue
- if (songNum > 999) {
- if ((songNum + 1) == 2000) {
- songNum = _lastSong;
- queueClear();
- queueSong(songNum);
- } else {
- queueTuneList(songNum - 1000);
- _queuePos = _randomLoop ? randomQueuePos() : 0;
- songNum = _songQueue[_queuePos];
- }
+ //Special type
+ // > 1000 && < 2000 -> queue different tunelist
+ // 2000 -> repeat music from previous queue
+ if (songNum > 999) {
+ if ((songNum + 1) == 2000) {
+ songNum = _lastSong;
+ queueClear();
+ queueSong(songNum);
+ } else {
+ queueTuneList(songNum - 1000);
+ _queuePos = _randomLoop ? randomQueuePos() : 0;
+ songNum = _songQueue[_queuePos];
}
+ }
- byte *prevSong = _musicData + songOffset(_currentSong);
- if (*prevSong == 0x43 || *prevSong == 0x63) {
- if (_buf) {
- delete[] _buf;
- _buf = 0;
- }
+ byte *prevSong = _musicData + songOffset(_currentSong);
+ if (*prevSong == 0x43 || *prevSong == 0x63) {
+ if (_buf) {
+ delete[] _buf;
+ _buf = 0;
}
+ }
- _currentSong = songNum;
- if (!songNum) {
- stopMusic();
- return;
- }
-
- byte *musicPtr = _musicData + songOffset(songNum);
- uint32 size = songLength(songNum);
+ _currentSong = songNum;
+ if (!songNum) {
+ stopMusic();
+ return;
+ }
- if (*musicPtr == 0x43 || *musicPtr == 0x63) {
- uint32 packedSize = songLength(songNum) - 0x200;
- _buf = new uint16[packedSize];
+ byte *musicPtr = _musicData + songOffset(songNum);
+ uint32 size = songLength(songNum);
+ if (*musicPtr == 0x43 || *musicPtr == 0x63) {
+ uint32 packedSize = songLength(songNum) - 0x200;
+ _buf = new uint16[packedSize];
- uint16 *data = (uint16 *)(musicPtr + 1);
- byte *idx = ((byte *)data) + 0x200;
+ uint16 *data = (uint16 *)(musicPtr + 1);
+ byte *idx = ((byte *)data) + 0x200;
- for (uint i = 0; i < packedSize; i++)
+ for (uint i = 0; i < packedSize; i++)
#if defined(SCUMM_NEED_ALIGNMENT)
- memcpy(&_buf[i], &data[*(idx + i)], sizeof(uint16));
+ memcpy(&_buf[i], &data[*(idx + i)], sizeof(uint16));
#else
- _buf[i] = data[*(idx + i)];
+ _buf[i] = data[*(idx + i)];
#endif
- musicPtr = ((byte *)_buf) + ((*musicPtr == 0x63) ? 1 : 0);
- size = packedSize * 2;
- }
-
- _parser->loadMusic(musicPtr, size);
- _parser->setTrack(0);
- //debug(0, "Playing song %d [queue position: %d]", songNum, _queuePos);
- _isPlaying = true;
- queueUpdatePos();
+ musicPtr = ((byte *)_buf) + ((*musicPtr == 0x63) ? 1 : 0);
+ size = packedSize * 2;
}
+
+ _parser->loadMusic(musicPtr, size);
+ _parser->setTrack(0);
+ debug(8, "Playing song %d [queue position: %d]", songNum, _queuePos);
+ _isPlaying = true;
+ queueUpdatePos();
+}
- void MusicPlayer::queueUpdatePos() {
- if (_randomLoop)
- _queuePos = randomQueuePos();
- else {
- if (_queuePos < (MUSIC_QUEUE_SIZE - 1) && _songQueue[_queuePos + 1])
- _queuePos++;
- else
- if (_looping)
- _queuePos = 0;
- }
+void MusicPlayer::queueUpdatePos() {
+ if (_randomLoop) {
+ _queuePos = randomQueuePos();
+ } else {
+ if (_queuePos < (MUSIC_QUEUE_SIZE - 1) && _songQueue[_queuePos + 1])
+ _queuePos++;
+ else if (_looping)
+ _queuePos = 0;
}
+}
- uint8 MusicPlayer::randomQueuePos() {
- int queueSize = 0;
- for (int i = 0; i < MUSIC_QUEUE_SIZE; i++)
- if (_songQueue[i])
- queueSize++;
-
- if (!queueSize)
- return 0;
-
- return (uint8) _rnd.getRandomNumber(queueSize - 1) & 0xFF;
- }
+uint8 MusicPlayer::randomQueuePos() {
+ int queueSize = 0;
+ for (int i = 0; i < MUSIC_QUEUE_SIZE; i++)
+ if (_songQueue[i])
+ queueSize++;
- void MusicPlayer::stopMusic() {
- _isPlaying = false;
- _parser->unloadMusic();
- }
+ if (!queueSize)
+ return 0;
+
+ return (uint8) _rnd.getRandomNumber(queueSize - 1) & 0xFF;
+}
- uint32 MusicPlayer::songOffset(uint16 songNum) const {
- uint16 offsLo = READ_LE_UINT16(_musicData + (songNum * 4) + 2);
- uint16 offsHi = READ_LE_UINT16(_musicData + (songNum * 4) + 4);
- return (offsHi << 4) | offsLo;
- }
+void MusicPlayer::stopMusic() {
+ _isPlaying = false;
+ _parser->unloadMusic();
+}
- uint32 MusicPlayer::songLength(uint16 songNum) const {
- if (songNum < _numSongs)
- return (songOffset(songNum + 1) - songOffset(songNum));
- return (_musicDataSize - songOffset(songNum));
- }
+uint32 MusicPlayer::songOffset(uint16 songNum) const {
+ uint16 offsLo = READ_LE_UINT16(_musicData + (songNum * 4) + 2);
+ uint16 offsHi = READ_LE_UINT16(_musicData + (songNum * 4) + 4);
+ return (offsHi << 4) | offsLo;
+}
- Music::Music(MidiDriver *driver, QueenEngine *vm) : _vToggle(false) {
- if (vm->resource()->isDemo()) {
- _musicData = vm->resource()->loadFile("AQ8.RL", 0, &_musicDataSize);
- } else {
- _musicData = vm->resource()->loadFile("AQ.RL", 0, &_musicDataSize);
- }
-
- _player = new MusicPlayer(driver, _musicData, _musicDataSize);
- }
+uint32 MusicPlayer::songLength(uint16 songNum) const {
+ if (songNum < _numSongs)
+ return (songOffset(songNum + 1) - songOffset(songNum));
+ return (_musicDataSize - songOffset(songNum));
+}
- Music::~Music() {
- delete _player;
- delete[] _musicData;
- }
-
- void Music::playSong(uint16 songNum) {
- _player->queueClear();
- _player->queueSong(songNum);
- _player->playMusic();
- }
-
- void Music::toggleVChange() {
- setVolume(_vToggle ? (volume() * 2) : (volume() / 2));
- _vToggle ^= true;
+Music::Music(MidiDriver *driver, QueenEngine *vm) : _vToggle(false) {
+ if (vm->resource()->isDemo()) {
+ _musicData = vm->resource()->loadFile("AQ8.RL", 0, &_musicDataSize);
+ } else {
+ _musicData = vm->resource()->loadFile("AQ.RL", 0, &_musicDataSize);
}
+ _player = new MusicPlayer(driver, _musicData, _musicDataSize);
+}
+
+Music::~Music() {
+ delete _player;
+ delete[] _musicData;
+}
+
+void Music::playSong(uint16 songNum) {
+ _player->queueClear();
+ _player->queueSong(songNum);
+ _player->playMusic();
+}
+
+void Music::toggleVChange() {
+ setVolume(_vToggle ? (volume() * 2) : (volume() / 2));
+ _vToggle ^= true;
+}
} // End of namespace Queen