Ticket #8460: kyra_sound_v1.patch
File kyra_sound_v1.patch, 13.4 KB (added by , 19 years ago) |
---|
-
kyra/kyra.cpp
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/kyra/kyra.cpp ./scummvm/kyra/kyra.cpp
old new 155 155 assert(_midi); 156 156 _midi->hasNativeMT32(native_mt32); 157 157 _midi->setVolume(255); 158 158 159 159 _res = new Resource(this); 160 160 assert(_res); 161 161 _screen = new Screen(this, _system); … … 349 349 _skipIntroFlag = true; // only true if user already played the game once 350 350 _seq_copyViewOffs = 1; 351 351 352 // snd_kyraPlayTheme(0); 352 snd_playTheme(kIntro, 2); 353 snd_setSoundEffectFile(kIntro); 354 debug("Done"); 353 355 setTalkCoords(0x90); 354 356 355 357 memset(_screen->_palette1, 0, 768); … … 781 783 } 782 784 break; 783 785 case 24: { // sound related 784 seqData++; 785 warning("Sequence opcode 24 skipped"); 786 uint8 param = *seqData++; 787 waitTicks(3); 788 snd_playSoundEffect(param); 786 789 } 787 790 break; 788 791 case 25: { // sound related 789 seqData++;790 warning("Sequence opcode 25 skipped");792 uint8 param = *seqData++; 793 snd_seqMessage(param); 791 794 } 792 795 break; 793 796 case 26: -
kyra/kyra.h
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/kyra/kyra.h ./scummvm/kyra/kyra.h
old new 60 60 class Screen; 61 61 62 62 class KyraEngine : public Engine { 63 friend class MusicPlayer; 63 64 public: 64 65 65 66 KyraEngine(GameDetector *detector, OSystem *system); … … 74 75 75 76 Common::RandomSource _rnd; 76 77 78 enum { 79 kIntro = 0, 80 kKyraMisc = 11 81 }; 82 77 83 protected: 78 84 79 85 int go(); … … 108 114 uint16 wsa_getNumFrames(WSAMovieV1 *wsa) const; 109 115 void wsa_play(WSAMovieV1 *wsa, int frameNum, int x, int y, int pageNum); 110 116 void wsa_processFrame(WSAMovieV1 *wsa, int frameNum, uint8 *dst); 117 118 void snd_playTheme(int file, int track = 0); 119 void snd_playTrack(int track); 120 void snd_startTrack(); 121 void snd_haltTrack(); 122 void snd_setSoundEffectFile(int file); 123 void snd_playSoundEffect(int track); 124 void snd_seqMessage(int msg); 111 125 112 126 uint8 _game; 113 127 bool _fastMode; -
kyra/sound.cpp
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/kyra/sound.cpp ./scummvm/kyra/sound.cpp
old new 22 22 #include "common/stdafx.h" 23 23 #include "kyra/resource.h" 24 24 #include "kyra/sound.h" 25 #include "common/system.h" 25 26 26 27 namespace Kyra { 27 28 … … 29 30 _engine = engine; 30 31 _driver = driver; 31 32 _passThrough = false; 32 _isPlaying = _nativeMT32 = false; 33 34 memset(_channel, 0, sizeof(MidiChannel*) * 16); 35 memset(_channelVolume, 255, sizeof(uint8) * 16); 33 _eventFromMusic = false; 34 _fadeMusicOut = _sfxIsPlaying = false; 35 _isPlaying = _isLooping = _nativeMT32 = false; 36 _soundEffect = _parser = 0; 37 38 memset(_channel, 0, sizeof(MidiChannel*) * 32); 39 memset(_channelVolume, 50, sizeof(uint8) * 16); 40 _channelVolume[10] = 100; 41 for (int i = 0; i < 16; ++i) { 42 _virChannel[i] = i; 43 } 36 44 _volume = 0; 37 45 38 46 int ret = open(); … … 56 64 return; 57 65 58 66 _volume = volume; 59 for (int i = 0; i < 16; ++i) {67 for (int i = 0; i < 32; ++i) { 60 68 if (_channel[i]) { 61 _channel[i]->volume(_channelVolume[i] * _volume / 255); 69 if (i >= 16) { 70 _channel[i]->volume(_channelVolume[i - 16] * _volume / 255); 71 } else { 72 _channel[i]->volume(_channelVolume[i] * _volume / 255); 73 } 62 74 } 63 75 } 64 76 } … … 84 96 85 97 void MusicPlayer::send(uint32 b) { 86 98 if (_passThrough) { 99 if ((b & 0xFFF0) == 0x007BB0) 100 return; 87 101 _driver->send(b); 88 102 return; 89 103 } 90 104 91 105 uint8 channel = (byte)(b & 0x0F); 106 if (((b & 0xFFF0) == 0x6FB0 || (b & 0xFFF0) == 0x6EB0) && channel != 9) { 107 if (_virChannel[channel] == channel) { 108 _virChannel[channel] = channel + 16; 109 if (!_channel[_virChannel[channel]]) 110 _channel[_virChannel[channel]] = _driver->allocateChannel(); 111 _channel[_virChannel[channel]]->volume(_channelVolume[channel] * _volume / 255); 112 } 113 return; 114 } 115 92 116 if ((b & 0xFFF0) == 0x07B0) { 93 117 // Adjust volume changes by master volume 94 118 uint8 volume = (uint8)((b >> 16) & 0x7F); … … 104 128 return; 105 129 } 106 130 107 if (!_channel[channel]) 108 _channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); 109 if (_channel[channel]) 110 _channel[channel]->send(b); 131 if (!_channel[_virChannel[channel]]) { 132 _channel[_virChannel[channel]] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); 133 _channel[_virChannel[channel]]->volume(_channelVolume[channel] * _volume / 255); 134 } 135 if (_channel[_virChannel[channel]]) 136 _channel[_virChannel[channel]]->send(b); 111 137 } 112 138 113 139 void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) { 114 140 switch (type) { 115 141 case 0x2F: // End of Track 116 _parser->jumpToTick(0); 142 if (_eventFromMusic) { 143 if (!_isLooping) { 144 _isPlaying = false; 145 } 146 147 // remap all channels 148 for (int i = 0; i < 16; ++i) { 149 _virChannel[i] = i; 150 } 151 152 } else { 153 _sfxIsPlaying = false; 154 } 117 155 break; 118 156 default: 119 warning("Unhandled meta event: 0x%02x", type);157 _driver->metaEvent(type, data, length); 120 158 break; 121 159 } 122 160 } … … 134 172 } 135 173 136 174 void MusicPlayer::playMusic(uint8* data, uint32 size) { 137 if (_isPlaying) 138 stopMusic(); 175 stopMusic(); 139 176 140 177 _parser = MidiParser::createParser_XMIDI(); 141 178 assert(_parser); … … 150 187 _parser->setTrack(0); 151 188 _parser->setMidiDriver(this); 152 189 _parser->setTimerRate(getBaseTempo()); 190 _parser->property(MidiParser::mpAutoLoop, false); 191 } 192 193 void MusicPlayer::loadSoundEffectFile(const char* file) { 194 uint32 size; 195 uint8 *data = (_engine->resource())->fileData(file, &size); 196 197 if (!data) { 198 warning("couldn't load '%s'", file); 199 return; 200 } 153 201 154 _isPlaying = true; 202 loadSoundEffectFile(data, size); 203 } 204 205 void MusicPlayer::loadSoundEffectFile(uint8* data, uint32 size) { 206 stopSoundEffect(); 207 208 _soundEffect = MidiParser::createParser_XMIDI(); 209 assert(_soundEffect); 210 211 if (!_soundEffect->loadMusic(data, size)) { 212 warning("Error reading track!"); 213 delete _parser; 214 _parser = 0; 215 return; 216 } 217 218 _soundEffect->setTrack(0); 219 _soundEffect->setMidiDriver(this); 220 _soundEffect->setTimerRate(getBaseTempo()); 221 _soundEffect->property(MidiParser::mpAutoLoop, false); 155 222 } 156 223 157 224 void MusicPlayer::stopMusic() { 158 _is Playing = false;225 _isLooping = false; 159 226 if (_parser) { 160 227 _parser->unloadMusic(); 161 228 delete _parser; 162 _parser = NULL; 229 _parser = 0; 230 } 231 } 232 233 void MusicPlayer::stopSoundEffect() { 234 if (_soundEffect) { 235 _soundEffect->unloadMusic(); 236 delete _soundEffect; 237 _soundEffect = 0; 163 238 } 164 239 } 165 240 166 241 void MusicPlayer::onTimer(void *refCon) { 167 242 MusicPlayer *music = (MusicPlayer *)refCon; 168 if (music->_isPlaying) 169 music->_parser->onTimer(); 243 244 // this should be set to the fadeToBlack value 245 const static uint32 musicFadeTime = 2 * 1000; 246 if (music->_fadeMusicOut && music->_fadeStartTime + musicFadeTime > music->_engine->_system->getMillis()) { 247 byte volume = (byte)((musicFadeTime - (music->_engine->_system->getMillis() - music->_fadeStartTime)) * 255 / musicFadeTime); 248 music->setVolume(volume); 249 } else if(music->_fadeStartTime) { 250 music->setVolume(255); 251 music->_fadeStartTime = 0; 252 music->_fadeMusicOut = false; 253 } 254 255 if (music->_isPlaying) { 256 if (music->_parser) { 257 music->_eventFromMusic = true; 258 music->_parser->onTimer(); 259 } 260 } 261 262 if (music->_sfxIsPlaying) { 263 if (music->_soundEffect) { 264 music->_eventFromMusic = false; 265 music->_soundEffect->onTimer(); 266 } 267 } 170 268 } 171 269 172 void MusicPlayer::playTrack(uint8 track ) {270 void MusicPlayer::playTrack(uint8 track, bool loop) { 173 271 if (_parser) { 174 272 _isPlaying = true; 273 _isLooping = loop; 175 274 _parser->setTrack(track); 176 275 _parser->jumpToTick(0); 276 _parser->setTempo(1); 277 _parser->property(MidiParser::mpAutoLoop, loop); 278 } 279 } 280 281 void MusicPlayer::playSoundEffect(uint8 track) { 282 if (_soundEffect) { 283 _sfxIsPlaying = true; 284 _soundEffect->setTrack(track); 285 _soundEffect->jumpToTick(0); 286 _soundEffect->property(MidiParser::mpAutoLoop, false); 287 } 288 } 289 290 void MusicPlayer::beginFadeOut() { 291 // this should be something like fade out... 292 _fadeMusicOut = true; 293 _fadeStartTime = _engine->_system->getMillis(); 294 } 295 296 void KyraEngine::snd_playTheme(int file, int track) { 297 switch(file) { 298 case kIntro: 299 debug(9, "Load music file 'INTRO.XMI'"); 300 _midi->playMusic("INTRO.XMI"); 301 break; 302 303 default: 304 warning("Unkown music file: %d", file); 305 return; 306 break; 307 } 308 309 debug(9, "Playing track: %d", track); 310 _midi->playTrack(track, false); 311 } 312 313 void KyraEngine::snd_playTrack(int track) { 314 debug(9, "Playing track: %d", track); 315 _midi->playTrack(track, false); 316 } 317 318 void KyraEngine::snd_setSoundEffectFile(int file) { 319 switch(file) { 320 case kIntro: 321 debug(3, "Load soundeffect file 'INTRO.XMI'"); 322 _midi->loadSoundEffectFile("INTRO.XMI"); 323 break; 324 325 case kKyraMisc: 326 debug(3, "Load soundeffect file 'KYRAMISC.XMI'"); 327 _midi->loadSoundEffectFile("KYRAMISC.XMI"); 328 break; 329 330 default: 331 warning("Unkown soundeffect file: %d", file); 332 return; 333 break; 334 } 335 } 336 337 void KyraEngine::snd_playSoundEffect(int track) { 338 debug(9, "Playing soundeffect: %d", track); 339 _midi->playSoundEffect(track); 340 } 341 342 void KyraEngine::snd_startTrack() { 343 _midi->startTrack(); 344 } 345 346 void KyraEngine::snd_haltTrack() { 347 _midi->haltTrack(); 348 } 349 350 void KyraEngine::snd_seqMessage(int msg) { 351 debug(9, "snd_seqMessage(%.02d)", msg); 352 switch(msg) { 353 case 0: 354 warning("snd_seqMessage(0)"); 355 break; 356 357 case 1: 358 _midi->beginFadeOut(); 359 break; 360 361 case 56: 362 snd_playTheme(kIntro, 3); 363 break; 364 365 case 57: 366 snd_playTheme(kIntro, 4); 367 break; 368 369 case 58: 370 snd_playTheme(kIntro, 5); 371 break; 372 373 default: 374 warning("Unknown seq. message: %.02d", msg); 375 break; 177 376 } 178 377 } 179 378 -
kyra/sound.h
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/kyra/sound.h ./scummvm/kyra/sound.h
old new 29 29 #include "kyra/kyra.h" 30 30 31 31 namespace Kyra { 32 class MusicPlayer : public MidiDriver {33 32 34 public: 33 class MusicPlayer : public MidiDriver { 35 34 36 MusicPlayer(MidiDriver* driver, KyraEngine* engine); 37 ~MusicPlayer(); 35 public: 38 36 39 void setVolume(int volume);40 int getVolume() { return _volume; }37 MusicPlayer(MidiDriver* driver, KyraEngine* engine); 38 ~MusicPlayer(); 41 39 42 void hasNativeMT32(bool nativeMT32) { _nativeMT32 = nativeMT32; } 40 void setVolume(int volume); 41 int getVolume() { return _volume; } 42 43 void hasNativeMT32(bool nativeMT32) { _nativeMT32 = nativeMT32; } 44 45 void playMusic(const char* file); 46 void playMusic(uint8* data, uint32 size); 47 void stopMusic(); 48 49 void playTrack(uint8 track, bool looping = true); 50 void haltTrack() { _isPlaying = false; } 51 void startTrack() { _isPlaying = true; } 52 void setPassThrough(bool b) { _passThrough = b; } 53 54 void loadSoundEffectFile(const char* file); 55 void loadSoundEffectFile(uint8* data, uint32 size); 56 void stopSoundEffect(); 57 58 void playSoundEffect(uint8 track); 59 60 void beginFadeOut(); 61 62 //MidiDriver interface implementation 63 int open(); 64 void close(); 65 void send(uint32 b); 66 void metaEvent(byte type, byte *data, uint16 length); 67 68 void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { } 69 uint32 getBaseTempo(void) { return _driver ? _driver->getBaseTempo() : 0; } 70 71 //Channel allocation functions 72 MidiChannel *allocateChannel() { return 0; } 73 MidiChannel *getPercussionChannel() { return 0; } 74 75 protected: 76 77 static void onTimer(void *data); 78 79 MidiChannel* _channel[32]; 80 int _virChannel[16]; 81 uint8 _channelVolume[16]; 82 MidiDriver* _driver; 83 bool _nativeMT32; 84 bool _passThrough; 85 uint8 _volume; 86 bool _isPlaying; 87 bool _sfxIsPlaying; 88 uint32 _fadeStartTime; 89 bool _fadeMusicOut; 90 bool _isLooping; 91 bool _eventFromMusic; 92 MidiParser* _parser; 93 MidiParser* _soundEffect; 94 KyraEngine* _engine; 43 95 44 void playMusic(const char* file); 45 void playMusic(uint8* data, uint32 size); 46 void stopMusic(); 96 }; 47 97 48 void playTrack(uint8 track);49 void setPassThrough(bool b) { _passThrough = b; }50 51 //MidiDriver interface implementation52 int open();53 void close();54 void send(uint32 b);55 void metaEvent(byte type, byte *data, uint16 length);56 57 void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { }58 uint32 getBaseTempo(void) { return _driver ? _driver->getBaseTempo() : 0; }59 60 //Channel allocation functions61 MidiChannel *allocateChannel() { return 0; }62 MidiChannel *getPercussionChannel() { return 0; }63 64 protected:65 66 static void onTimer(void *data);67 68 MidiChannel* _channel[16];69 uint8 _channelVolume[16];70 MidiDriver* _driver;71 bool _nativeMT32;72 bool _passThrough;73 uint8 _volume;74 bool _isPlaying;75 MidiParser* _parser;76 KyraEngine* _engine;77 78 };79 98 } // end of namespace Kyra 80 99 81 100 #endif -
sound/midiparser_xmidi.cpp
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/sound/midiparser_xmidi.cpp ./scummvm/sound/midiparser_xmidi.cpp
old new 69 69 _inserted_delta = 0; 70 70 info.event = *(_position._play_pos++); 71 71 switch (info.event >> 4) { 72 case 0x7: 73 // TODO: why has the kyra intro this strange event? 74 // maybe it is handeld in another way, but for now this will work 75 warning("Kyrandia Hack, if this is NOT Kyrandia pls report it! (info.event: 0x%X)", info.event); 76 parseNextEvent(info); 77 break; 72 78 case 0x9: // Note On 73 79 info.basic.param1 = *(_position._play_pos++); 74 80 info.basic.param2 = *(_position._play_pos++);