aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/agi/sound_midi.cpp37
-rw-r--r--engines/agi/sound_midi.h13
-rw-r--r--engines/draci/music.cpp42
-rw-r--r--engines/draci/music.h9
-rw-r--r--engines/hugo/sound.cpp87
-rw-r--r--engines/hugo/sound.h10
-rw-r--r--engines/m4/midi.cpp55
-rw-r--r--engines/m4/midi.h5
-rw-r--r--engines/made/music.cpp43
-rw-r--r--engines/made/music.h7
-rw-r--r--engines/parallaction/parallaction_br.cpp4
-rw-r--r--engines/parallaction/parallaction_ns.cpp4
-rw-r--r--engines/parallaction/sound.h4
-rw-r--r--engines/parallaction/sound_br.cpp73
-rw-r--r--engines/parallaction/sound_ns.cpp69
-rw-r--r--engines/sci/console.cpp4
-rw-r--r--engines/sci/debug.h12
-rw-r--r--engines/sci/engine/vm.cpp296
-rw-r--r--engines/sci/engine/workarounds.cpp2
-rw-r--r--engines/sci/graphics/frameout.cpp3
-rw-r--r--engines/sci/graphics/screen.cpp2
-rw-r--r--engines/sword25/gfx/image/pngloader.cpp2
-rw-r--r--engines/sword25/gfx/image/renderedimage.cpp18
-rw-r--r--engines/sword25/gfx/image/renderedimage.h24
-rw-r--r--engines/sword25/gfx/image/swimage.cpp8
-rw-r--r--engines/sword25/gfx/image/vectorimage.cpp102
-rw-r--r--engines/tinsel/music.cpp38
-rw-r--r--engines/tinsel/music.h7
-rw-r--r--engines/tinsel/tinsel.cpp2
-rw-r--r--engines/tinsel/tinsel.h3
-rw-r--r--engines/touche/midi.cpp115
-rw-r--r--engines/touche/midi.h32
-rw-r--r--engines/touche/staticres.cpp11
33 files changed, 384 insertions, 759 deletions
diff --git a/engines/agi/sound_midi.cpp b/engines/agi/sound_midi.cpp
index 2c6a189fbd..ff23a70808 100644
--- a/engines/agi/sound_midi.cpp
+++ b/engines/agi/sound_midi.cpp
@@ -90,24 +90,11 @@ SoundGenMIDI::SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, p
else
_driver->sendGMReset();
- _driver->setTimerCallback(this, &onTimer);
+ // FIXME: We need to cast "this" here due to the effects of
+ // multiple inheritance. This hack can go away once this
+ // setTimerCallback() has been moved inside Audio::MidiPlayer code.
+ _driver->setTimerCallback(static_cast<Audio::MidiPlayer *>(this), &timerCallback);
}
-
- _smfParser = MidiParser::createParser_SMF();
- _midiMusicData = NULL;
-}
-
-SoundGenMIDI::~SoundGenMIDI() {
- _driver->setTimerCallback(NULL, NULL);
- stop();
- if (_driver) {
- _driver->close();
- delete _driver;
- _driver = 0;
- }
- _smfParser->setMidiDriver(NULL);
- delete _smfParser;
- delete[] _midiMusicData;
}
void SoundGenMIDI::send(uint32 b) {
@@ -136,14 +123,6 @@ void SoundGenMIDI::endOfTrack() {
_vm->_sound->soundIsFinished();
}
-void SoundGenMIDI::onTimer(void *refCon) {
- SoundGenMIDI *music = (SoundGenMIDI *)refCon;
- Common::StackLock lock(music->_mutex);
-
- if (music->_parser)
- music->_parser->onTimer();
-}
-
void SoundGenMIDI::play(int resnum) {
MIDISound *track;
@@ -154,10 +133,10 @@ void SoundGenMIDI::play(int resnum) {
track = (MIDISound *)_vm->_game.sounds[resnum];
// Convert AGI Sound data to MIDI
- int midiMusicSize = convertSND2MIDI(track->_data, &_midiMusicData);
+ int midiMusicSize = convertSND2MIDI(track->_data, &_midiData);
- if (_smfParser->loadMusic(_midiMusicData, midiMusicSize)) {
- MidiParser *parser = _smfParser;
+ MidiParser *parser = MidiParser::createParser_SMF();
+ if (parser->loadMusic(_midiData, midiMusicSize)) {
parser->setTrack(0);
parser->setMidiDriver(this);
parser->setTimerRate(_driver->getBaseTempo());
@@ -168,6 +147,8 @@ void SoundGenMIDI::play(int resnum) {
syncVolume();
_isPlaying = true;
+ } else {
+ delete parser;
}
}
diff --git a/engines/agi/sound_midi.h b/engines/agi/sound_midi.h
index 9551673a4e..5733358fee 100644
--- a/engines/agi/sound_midi.h
+++ b/engines/agi/sound_midi.h
@@ -28,6 +28,8 @@
#ifndef AGI_SOUND_MIDI_H
#define AGI_SOUND_MIDI_H
+#include "agi/sound.h"
+
#include "audio/midiplayer.h"
namespace Agi {
@@ -47,13 +49,12 @@ protected:
class SoundGenMIDI : public SoundGen, public Audio::MidiPlayer {
public:
SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer);
- ~SoundGenMIDI();
void play(int resnum);
+ // We must overload stop() here to implement the pure virtual
+ // stop() method of the SoundGen class.
void stop() { Audio::MidiPlayer::stop(); }
- void setGM(bool isGM) { _isGM = isGM; }
-
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
@@ -62,14 +63,8 @@ public:
virtual void endOfTrack();
private:
-
- static void onTimer(void *data);
-
- MidiParser *_smfParser;
bool _isGM;
- byte *_midiMusicData;
-
SoundMgr *_manager;
};
diff --git a/engines/draci/music.cpp b/engines/draci/music.cpp
index 77f51544d5..242e58e92c 100644
--- a/engines/draci/music.cpp
+++ b/engines/draci/music.cpp
@@ -47,9 +47,6 @@ MusicPlayer::MusicPlayer(const char *pathMask) : _pathMask(pathMask), _isGM(fals
if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
- _smfParser = MidiParser::createParser_SMF();
- _midiMusicData = NULL;
-
int ret = _driver->open();
if (ret == 0) {
if (_nativeMT32)
@@ -61,21 +58,8 @@ MusicPlayer::MusicPlayer(const char *pathMask) : _pathMask(pathMask), _isGM(fals
// interface for such an operation is supported for AdLib. Maybe for
// this card, setting instruments is necessary.
- _driver->setTimerCallback(this, &onTimer);
- }
-}
-
-MusicPlayer::~MusicPlayer() {
- _driver->setTimerCallback(NULL, NULL);
- stop();
- if (_driver) {
- _driver->close();
- delete _driver;
- _driver = 0;
+ _driver->setTimerCallback(this, &timerCallback);
}
- _smfParser->setMidiDriver(NULL);
- delete _smfParser;
- delete[] _midiMusicData;
}
void MusicPlayer::sendToChannel(byte channel, uint32 b) {
@@ -91,15 +75,9 @@ void MusicPlayer::sendToChannel(byte channel, uint32 b) {
_channelsTable[channel]->send(b);
}
-void MusicPlayer::onTimer(void *refCon) {
- MusicPlayer *music = (MusicPlayer *)refCon;
- Common::StackLock lock(music->_mutex);
-
- if (music->_parser)
- music->_parser->onTimer();
-}
-
void MusicPlayer::playSMF(int track, bool loop) {
+ Common::StackLock lock(_mutex);
+
if (_isPlaying && track == _track) {
debugC(2, kDraciSoundDebugLevel, "Already plaing track %d", track);
return;
@@ -109,24 +87,23 @@ void MusicPlayer::playSMF(int track, bool loop) {
_isGM = true;
-
// Load MIDI resource data
Common::File musicFile;
char musicFileName[40];
- sprintf(musicFileName, _pathMask.c_str(), track);
+ snprintf(musicFileName, sizeof(musicFileName), _pathMask.c_str(), track);
musicFile.open(musicFileName);
if (!musicFile.isOpen()) {
debugC(2, kDraciSoundDebugLevel, "Cannot open track %d", track);
return;
}
int midiMusicSize = musicFile.size();
- delete[] _midiMusicData;
- _midiMusicData = new byte[midiMusicSize];
- musicFile.read(_midiMusicData, midiMusicSize);
+ free(_midiData);
+ _midiData = (byte *)malloc(midiMusicSize);
+ musicFile.read(_midiData, midiMusicSize);
musicFile.close();
- if (_smfParser->loadMusic(_midiMusicData, midiMusicSize)) {
- MidiParser *parser = _smfParser;
+ MidiParser *parser = MidiParser::createParser_SMF();
+ if (parser->loadMusic(_midiData, midiMusicSize)) {
parser->setTrack(0);
parser->setMidiDriver(this);
parser->setTimerRate(_driver->getBaseTempo());
@@ -142,6 +119,7 @@ void MusicPlayer::playSMF(int track, bool loop) {
debugC(2, kDraciSoundDebugLevel, "Playing track %d", track);
} else {
debugC(2, kDraciSoundDebugLevel, "Cannot play track %d", track);
+ delete parser;
}
}
diff --git a/engines/draci/music.h b/engines/draci/music.h
index a1d0aaacb6..c0228074e5 100644
--- a/engines/draci/music.h
+++ b/engines/draci/music.h
@@ -37,27 +37,18 @@ namespace Draci {
class MusicPlayer : public Audio::MidiPlayer {
public:
MusicPlayer(const char *pathMask);
- ~MusicPlayer();
void playSMF(int track, bool loop);
void stop();
- void setGM(bool isGM) { _isGM = isGM; }
-
// Overload Audio::MidiPlayer method
virtual void sendToChannel(byte channel, uint32 b);
protected:
-
- static void onTimer(void *data);
-
- MidiParser *_smfParser;
Common::String _pathMask;
bool _isGM;
int _track;
-
- byte *_midiMusicData;
};
} // End of namespace Draci
diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp
index 04da0c89ee..24359a2c54 100644
--- a/engines/hugo/sound.cpp
+++ b/engines/hugo/sound.cpp
@@ -47,58 +47,46 @@
namespace Hugo {
-MidiPlayer::MidiPlayer(MidiDriver *driver)
- : _midiData(0) {
+MidiPlayer::MidiPlayer() {
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
+ _driver = MidiDriver::createMidi(dev);
assert(_driver);
_paused = false;
-}
-MidiPlayer::~MidiPlayer() {
- stop();
- Common::StackLock lock(_mutex);
- _driver->setTimerCallback(0, 0);
- _driver->close();
- delete _driver;
- _driver = 0;
- if (_parser)
- _parser->setMidiDriver(0);
- delete _parser;
+ int ret = _driver->open();
+ if (ret == 0) {
+ _driver->sendGMReset();
+
+ _driver->setTimerCallback(this, &timerCallback);
+ }
}
void MidiPlayer::play(uint8 *stream, uint16 size) {
debugC(3, kDebugMusic, "MidiPlayer::play");
- if (!stream) {
- stop();
- return;
- }
+
+ Common::StackLock lock(_mutex);
stop();
+ if (!stream)
+ return;
+
_midiData = (uint8 *)malloc(size);
if (_midiData) {
memcpy(_midiData, stream, size);
- Common::StackLock lock(_mutex);
syncVolume(); // FIXME: syncVolume calls setVolume which in turn also locks the mutex! ugh
+
+ _parser = MidiParser::createParser_SMF();
_parser->loadMusic(_midiData, size);
_parser->setTrack(0);
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
_isLooping = false;
_isPlaying = true;
}
}
-void MidiPlayer::stop() {
- debugC(3, kDebugMusic, "MidiPlayer::stop");
-
- Common::StackLock lock(_mutex);
- if (_isPlaying) {
- _isPlaying = false;
- _parser->unloadMusic();
- free(_midiData);
- _midiData = 0;
- }
-}
-
void MidiPlayer::pause(bool p) {
_paused = p;
@@ -109,34 +97,14 @@ void MidiPlayer::pause(bool p) {
}
}
-void MidiPlayer::updateTimer() {
- if (_paused) {
- return;
- }
-
+void MidiPlayer::onTimer() {
Common::StackLock lock(_mutex);
- if (_isPlaying) {
+
+ if (!_paused && _isPlaying && _parser) {
_parser->onTimer();
}
}
-int MidiPlayer::open() {
- if (!_driver)
- return 255;
- int ret = _driver->open();
- if (ret)
- return ret;
-
- _driver->sendGMReset();
-
- _parser = MidiParser::createParser_SMF();
- _parser->setMidiDriver(this);
- _parser->setTimerRate(_driver->getBaseTempo());
- _driver->setTimerCallback(this, &timerCallback);
-
- return 0;
-}
-
void MidiPlayer::sendToChannel(byte channel, uint32 b) {
if (!_channelsTable[channel]) {
_channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
@@ -151,17 +119,8 @@ void MidiPlayer::sendToChannel(byte channel, uint32 b) {
}
-void MidiPlayer::timerCallback(void *p) {
- MidiPlayer *player = (MidiPlayer *)p;
-
- player->updateTimer();
-}
-
SoundHandler::SoundHandler(HugoEngine *vm) : _vm(vm) {
- MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
- MidiDriver *driver = MidiDriver::createMidi(dev);
-
- _midiPlayer = new MidiPlayer(driver);
+ _midiPlayer = new MidiPlayer();
_speakerStream = new Audio::PCSpeaker(_vm->_mixer->getOutputRate());
_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
_speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
@@ -263,7 +222,7 @@ void SoundHandler::playSound(int16 sound, const byte priority) {
* Initialize for MCI sound and midi
*/
void SoundHandler::initSound() {
- _midiPlayer->open();
+ //_midiPlayer->open();
}
void SoundHandler::syncVolume() {
diff --git a/engines/hugo/sound.h b/engines/hugo/sound.h
index b8a7bf9678..d5f51704aa 100644
--- a/engines/hugo/sound.h
+++ b/engines/hugo/sound.h
@@ -41,24 +41,18 @@ namespace Hugo {
class MidiPlayer : public Audio::MidiPlayer {
public:
- MidiPlayer(MidiDriver *driver);
- ~MidiPlayer();
+ MidiPlayer();
void pause(bool p);
void play(uint8 *stream, uint16 size);
- void stop();
- void updateTimer();
- int open();
uint32 getBaseTempo();
// Overload Audio::MidiPlayer method
virtual void sendToChannel(byte channel, uint32 b);
+ virtual void onTimer();
private:
- static void timerCallback(void *p);
-
- uint8 *_midiData;
bool _paused;
};
diff --git a/engines/m4/midi.cpp b/engines/m4/midi.cpp
index b982fc8129..d58b92bf01 100644
--- a/engines/m4/midi.cpp
+++ b/engines/m4/midi.cpp
@@ -34,7 +34,7 @@
namespace M4 {
-MidiPlayer::MidiPlayer(MadsM4Engine *vm) : _vm(vm), _midiData(NULL), _isGM(false) {
+MidiPlayer::MidiPlayer(MadsM4Engine *vm) : _vm(vm), _isGM(false) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
@@ -44,26 +44,10 @@ MidiPlayer::MidiPlayer(MadsM4Engine *vm) : _vm(vm), _midiData(NULL), _isGM(false
if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
- _parser = MidiParser::createParser_SMF();
- _parser->setMidiDriver(this);
- _parser->setTimerRate(_driver->getBaseTempo());
-
int ret = _driver->open();
- if (ret == 0)
- _driver->setTimerCallback(this, &onTimer);
-}
-
-MidiPlayer::~MidiPlayer() {
- _driver->setTimerCallback(NULL, NULL);
- _parser->setMidiDriver(NULL);
- stop();
- if (_driver) {
- _driver->close();
- delete _driver;
+ if (ret == 0) {
+ _driver->setTimerCallback(this, &timerCallback);
}
- _driver = 0;
- delete _parser;
- free(_midiData);
}
void MidiPlayer::send(uint32 b) {
@@ -74,15 +58,9 @@ void MidiPlayer::send(uint32 b) {
Audio::MidiPlayer::send(b);
}
-void MidiPlayer::onTimer(void *refCon) {
- MidiPlayer *midi = (MidiPlayer *)refCon;
- Common::StackLock lock(midi->_mutex);
-
- if (midi->_isPlaying)
- midi->_parser->onTimer();
-}
-
void MidiPlayer::playMusic(const char *name, int32 vol, bool loop, int32 trigger, int32 scene) {
+ Common::StackLock lock(_mutex);
+
stop();
char fullname[144];
@@ -99,11 +77,10 @@ void MidiPlayer::playMusic(const char *name, int32 vol, bool loop, int32 trigger
_vm->res()->purge();
if (_midiData) {
- /*
- FILE *out = fopen("music.mid", "wb");
- fwrite(_midiData, smfSize, 1, out);
- fclose(out);
- */
+ _parser = MidiParser::createParser_SMF();
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
+
_parser->loadMusic(_midiData, smfSize);
_parser->property(MidiParser::mpAutoLoop, loop);
}
@@ -113,20 +90,6 @@ void MidiPlayer::playMusic(const char *name, int32 vol, bool loop, int32 trigger
_isPlaying = true;
}
-void MidiPlayer::stop() {
- Common::StackLock lock(_mutex);
-
- _isPlaying = false;
- if (_parser) {
- _parser->unloadMusic();
- }
-
- if (_midiData) {
- free(_midiData);
- _midiData = NULL;
- }
-}
-
// This function will convert HMP music into type 1 SMF, which our SMF parser
// will be able to handle. It is based on Hans de Goede's HMP 2 MIDI file
// converter, which in turn is "based on the conversion algorithms found in
diff --git a/engines/m4/midi.h b/engines/m4/midi.h
index e1f92cd4b6..a544fb72aa 100644
--- a/engines/m4/midi.h
+++ b/engines/m4/midi.h
@@ -35,10 +35,8 @@ namespace M4 {
class MidiPlayer : public Audio::MidiPlayer {
public:
MidiPlayer(MadsM4Engine *vm);
- ~MidiPlayer();
void playMusic(const char *name, int32 vol, bool loop, int32 trigger, int32 scene);
- virtual void stop();
void setGM(bool isGM) { _isGM = isGM; }
@@ -46,10 +44,7 @@ public:
virtual void send(uint32 b);
protected:
- static void onTimer(void *data);
-
MadsM4Engine *_vm;
- byte *_midiData;
bool _isGM;
diff --git a/engines/made/music.cpp b/engines/made/music.cpp
index 054f8126d6..c8b13ba210 100644
--- a/engines/made/music.cpp
+++ b/engines/made/music.cpp
@@ -47,9 +47,6 @@ MusicPlayer::MusicPlayer() : _isGM(false) {
if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
- _xmidiParser = MidiParser::createParser_XMIDI();
- _smfParser = MidiParser::createParser_SMF();
-
int ret = _driver->open();
if (ret == 0) {
if (_nativeMT32)
@@ -57,22 +54,8 @@ MusicPlayer::MusicPlayer() : _isGM(false) {
else
_driver->sendGMReset();
- _driver->setTimerCallback(this, &onTimer);
- }
-}
-
-MusicPlayer::~MusicPlayer() {
- _driver->setTimerCallback(NULL, NULL);
- stop();
- if (_driver) {
- _driver->close();
- delete _driver;
- _driver = 0;
+ _driver->setTimerCallback(this, &timerCallback);
}
- _xmidiParser->setMidiDriver(NULL);
- _smfParser->setMidiDriver(NULL);
- delete _xmidiParser;
- delete _smfParser;
}
void MusicPlayer::send(uint32 b) {
@@ -83,15 +66,9 @@ void MusicPlayer::send(uint32 b) {
Audio::MidiPlayer::send(b);
}
-void MusicPlayer::onTimer(void *refCon) {
- MusicPlayer *music = (MusicPlayer *)refCon;
- Common::StackLock lock(music->_mutex);
-
- if (music->_isPlaying)
- music->_parser->onTimer();
-}
-
void MusicPlayer::playXMIDI(GenericResource *midiResource, MusicFlags flags) {
+ Common::StackLock lock(_mutex);
+
if (_isPlaying)
return;
@@ -101,8 +78,8 @@ void MusicPlayer::playXMIDI(GenericResource *midiResource, MusicFlags flags) {
_isGM = true;
- if (_xmidiParser->loadMusic(midiResource->getData(), midiResource->getSize())) {
- MidiParser *parser = _xmidiParser;
+ MidiParser *parser = MidiParser::createParser_XMIDI();
+ if (parser->loadMusic(midiResource->getData(), midiResource->getSize())) {
parser->setTrack(0);
parser->setMidiDriver(this);
parser->setTimerRate(_driver->getBaseTempo());
@@ -115,10 +92,14 @@ void MusicPlayer::playXMIDI(GenericResource *midiResource, MusicFlags flags) {
_isLooping = flags & MUSIC_LOOP;
_isPlaying = true;
+ } else {
+ delete parser;
}
}
void MusicPlayer::playSMF(GenericResource *midiResource, MusicFlags flags) {
+ Common::StackLock lock(_mutex);
+
if (_isPlaying)
return;
@@ -128,8 +109,8 @@ void MusicPlayer::playSMF(GenericResource *midiResource, MusicFlags flags) {
_isGM = true;
- if (_smfParser->loadMusic(midiResource->getData(), midiResource->getSize())) {
- MidiParser *parser = _smfParser;
+ MidiParser *parser = MidiParser::createParser_SMF();
+ if (parser->loadMusic(midiResource->getData(), midiResource->getSize())) {
parser->setTrack(0);
parser->setMidiDriver(this);
parser->setTimerRate(_driver->getBaseTempo());
@@ -141,6 +122,8 @@ void MusicPlayer::playSMF(GenericResource *midiResource, MusicFlags flags) {
_isLooping = flags & MUSIC_LOOP;
_isPlaying = true;
+ } else {
+ delete parser;
}
}
diff --git a/engines/made/music.h b/engines/made/music.h
index 8925440b75..f8f70cdad6 100644
--- a/engines/made/music.h
+++ b/engines/made/music.h
@@ -44,7 +44,6 @@ enum MusicFlags {
class MusicPlayer : public Audio::MidiPlayer {
public:
MusicPlayer();
- ~MusicPlayer();
void playXMIDI(GenericResource *midiResource, MusicFlags flags = MUSIC_NORMAL);
void playSMF(GenericResource *midiResource, MusicFlags flags = MUSIC_NORMAL);
@@ -52,16 +51,10 @@ public:
void pause();
void resume();
- void setGM(bool isGM) { _isGM = isGM; }
-
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
protected:
-
- static void onTimer(void *data);
-
- MidiParser *_xmidiParser, *_smfParser;
bool _isGM;
};
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index 457c421fd7..619a4f7559 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -61,9 +61,7 @@ Common::Error Parallaction_br::init() {
_disk = new DosDisk_br(this);
}
_disk->setLanguage(2); // NOTE: language is now hardcoded to English. Original used command-line parameters.
- MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
- MidiDriver *driver = MidiDriver::createMidi(dev);
- _soundManI = new DosSoundMan_br(this, driver);
+ _soundManI = new DosSoundMan_br(this);
} else {
_disk = new AmigaDisk_br(this);
_disk->setLanguage(2); // NOTE: language is now hardcoded to English. Original used command-line parameters.
diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp
index c3d917a33d..ffac22e118 100644
--- a/engines/parallaction/parallaction_ns.cpp
+++ b/engines/parallaction/parallaction_ns.cpp
@@ -166,9 +166,7 @@ Common::Error Parallaction_ns::init() {
_disk->init();
if (getPlatform() == Common::kPlatformPC) {
- MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
- MidiDriver *driver = MidiDriver::createMidi(dev);
- _soundManI = new DosSoundMan_ns(this, driver);
+ _soundManI = new DosSoundMan_ns(this);
_soundManI->setMusicVolume(ConfMan.getInt("music_volume"));
} else {
_soundManI = new AmigaSoundMan_ns(this);
diff --git a/engines/parallaction/sound.h b/engines/parallaction/sound.h
index 7b3eff37cb..455189d1fc 100644
--- a/engines/parallaction/sound.h
+++ b/engines/parallaction/sound.h
@@ -140,7 +140,7 @@ class DosSoundMan_ns : public SoundMan_ns {
public:
- DosSoundMan_ns(Parallaction_ns *vm, MidiDriver *midiDriver);
+ DosSoundMan_ns(Parallaction_ns *vm);
~DosSoundMan_ns();
void playMusic();
void stopMusic();
@@ -228,7 +228,7 @@ class DosSoundMan_br : public SoundMan_br {
Audio::AudioStream *loadChannelData(const char *filename, Channel *ch, bool looping);
public:
- DosSoundMan_br(Parallaction_br *vm, MidiDriver *midiDriver);
+ DosSoundMan_br(Parallaction_br *vm);
~DosSoundMan_br();
void playMusic();
diff --git a/engines/parallaction/sound_br.cpp b/engines/parallaction/sound_br.cpp
index 1bc085fd34..ee53f9641e 100644
--- a/engines/parallaction/sound_br.cpp
+++ b/engines/parallaction/sound_br.cpp
@@ -204,94 +204,69 @@ MidiParser *createParser_MSC() {
class MidiPlayer_MSC : public Audio::MidiPlayer {
public:
- MidiPlayer_MSC(MidiDriver *driver);
- ~MidiPlayer_MSC();
+ MidiPlayer_MSC();
void play(Common::SeekableReadStream *stream);
- void stop();
- void pause(bool p);
- void updateTimer();
- void setVolume(int volume);
+ virtual void pause(bool p);
+ virtual void setVolume(int volume);
+ virtual void onTimer();
// MidiDriver_BASE interface
virtual void send(uint32 b);
-private:
- static void timerCallback(void *p);
+private:
void setVolumeInternal(int volume);
-
- uint8 *_midiData;
bool _paused;
};
-MidiPlayer_MSC::MidiPlayer_MSC(MidiDriver *driver)
- : _midiData(0), _paused(false) {
- _driver = driver;
+MidiPlayer_MSC::MidiPlayer_MSC()
+ : _paused(false) {
+
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
+ _driver = MidiDriver::createMidi(dev);
assert(_driver);
int ret = _driver->open();
if (ret == 0) {
- _parser = createParser_MSC();
- _parser->setMidiDriver(this);
- _parser->setTimerRate(_driver->getBaseTempo());
_driver->setTimerCallback(this, &timerCallback);
}
}
-MidiPlayer_MSC::~MidiPlayer_MSC() {
- stop();
-
+void MidiPlayer_MSC::play(Common::SeekableReadStream *stream) {
Common::StackLock lock(_mutex);
- _driver->setTimerCallback(NULL, NULL);
- _driver->close();
- delete _driver;
- _driver = 0;
- _parser->setMidiDriver(NULL);
- delete _parser;
-}
-void MidiPlayer_MSC::play(Common::SeekableReadStream *stream) {
- if (!stream) {
- stop();
+ stop();
+ if (!stream)
return;
- }
- stop();
int size = stream->size();
_midiData = (uint8 *)malloc(size);
if (_midiData) {
stream->read(_midiData, size);
delete stream;
- Common::StackLock lock(_mutex);
+ _parser = createParser_MSC();
_parser->loadMusic(_midiData, size);
_parser->setTrack(0);
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
_isLooping = true;
_isPlaying = true;
}
}
-void MidiPlayer_MSC::stop() {
- Audio::MidiPlayer::stop();
- free(_midiData);
- _midiData = 0;
-}
-
void MidiPlayer_MSC::pause(bool p) {
_paused = p;
setVolumeInternal(_paused ? 0 : _masterVolume);
}
-void MidiPlayer_MSC::updateTimer() {
- if (_paused) {
- return;
- }
-
+void MidiPlayer_MSC::onTimer() {
Common::StackLock lock(_mutex);
- if (_isPlaying) {
+
+ if (!_paused && _isPlaying && _parser) {
_parser->onTimer();
}
}
@@ -327,14 +302,8 @@ void MidiPlayer_MSC::send(uint32 b) {
sendToChannel(ch, b);
}
-void MidiPlayer_MSC::timerCallback(void *p) {
- MidiPlayer_MSC *player = (MidiPlayer_MSC *)p;
-
- player->updateTimer();
-}
-
-DosSoundMan_br::DosSoundMan_br(Parallaction_br *vm, MidiDriver *driver) : SoundMan_br(vm) {
- _midiPlayer = new MidiPlayer_MSC(driver);
+DosSoundMan_br::DosSoundMan_br(Parallaction_br *vm) : SoundMan_br(vm) {
+ _midiPlayer = new MidiPlayer_MSC();
assert(_midiPlayer);
}
diff --git a/engines/parallaction/sound_ns.cpp b/engines/parallaction/sound_ns.cpp
index 8f3f0c39e6..ba81314da6 100644
--- a/engines/parallaction/sound_ns.cpp
+++ b/engines/parallaction/sound_ns.cpp
@@ -42,74 +42,52 @@ namespace Parallaction {
class MidiPlayer : public Audio::MidiPlayer {
public:
- MidiPlayer(MidiDriver *driver);
- ~MidiPlayer();
+ MidiPlayer();
void play(Common::SeekableReadStream *stream);
- void stop();
void pause(bool p);
- void updateTimer();
+ virtual void onTimer();
private:
- static void timerCallback(void *p);
-
- uint8 *_midiData;
bool _paused;
};
-MidiPlayer::MidiPlayer(MidiDriver *driver)
- : _midiData(0), _paused(false) {
- assert(driver);
- _driver = driver;
+MidiPlayer::MidiPlayer()
+ : _paused(false) {
+
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
+ _driver = MidiDriver::createMidi(dev);
+ assert(_driver);
int ret = _driver->open();
if (ret == 0) {
- _parser = MidiParser::createParser_SMF();
- _parser->setMidiDriver(this);
- _parser->setTimerRate(_driver->getBaseTempo());
_driver->setTimerCallback(this, &timerCallback);
}
}
-MidiPlayer::~MidiPlayer() {
- stop();
-
+void MidiPlayer::play(Common::SeekableReadStream *stream) {
Common::StackLock lock(_mutex);
- _driver->setTimerCallback(NULL, NULL);
- _driver->close();
- delete _driver;
- _driver = 0;
- _parser->setMidiDriver(NULL);
- delete _parser;
-}
-void MidiPlayer::play(Common::SeekableReadStream *stream) {
- if (!stream) {
- stop();
+ stop();
+ if (!stream)
return;
- }
int size = stream->size();
-
_midiData = (uint8 *)malloc(size);
if (_midiData) {
stream->read(_midiData, size);
delete stream;
- Common::StackLock lock(_mutex);
+ _parser = MidiParser::createParser_SMF();
_parser->loadMusic(_midiData, size);
_parser->setTrack(0);
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
_isLooping = true;
_isPlaying = true;
}
}
-void MidiPlayer::stop() {
- Audio::MidiPlayer::stop();
- free(_midiData);
- _midiData = 0;
-}
-
void MidiPlayer::pause(bool p) {
_paused = p;
@@ -120,25 +98,16 @@ void MidiPlayer::pause(bool p) {
}
}
-void MidiPlayer::updateTimer() {
- if (_paused) {
- return;
- }
-
+void MidiPlayer::onTimer() {
Common::StackLock lock(_mutex);
- if (_isPlaying) {
+
+ if (!_paused && _isPlaying && _parser) {
_parser->onTimer();
}
}
-void MidiPlayer::timerCallback(void *p) {
- MidiPlayer *player = (MidiPlayer *)p;
-
- player->updateTimer();
-}
-
-DosSoundMan_ns::DosSoundMan_ns(Parallaction_ns *vm, MidiDriver *midiDriver) : SoundMan_ns(vm), _playing(false) {
- _midiPlayer = new MidiPlayer(midiDriver);
+DosSoundMan_ns::DosSoundMan_ns(Parallaction_ns *vm) : SoundMan_ns(vm), _playing(false) {
+ _midiPlayer = new MidiPlayer();
}
DosSoundMan_ns::~DosSoundMan_ns() {
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 93d21c32e0..e2e5ee9682 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -3154,10 +3154,9 @@ bool Console::cmdBreakpointKernel(int argc, const char **argv) {
}
bool Console::cmdBreakpointFunction(int argc, const char **argv) {
- // TODO/FIXME: Why does this accept 2 parameters (the high and the low part of the address)?"
if (argc != 3) {
DebugPrintf("Sets a breakpoint on the execution of the specified exported function.\n");
- DebugPrintf("Usage: %s <addr1> <addr2>\n", argv[0]);
+ DebugPrintf("Usage: %s <script number> <export number\n", argv[0]);
return true;
}
@@ -3166,6 +3165,7 @@ bool Console::cmdBreakpointFunction(int argc, const char **argv) {
A breakpoint set on an invalid method name will just never trigger. */
Breakpoint bp;
bp.type = BREAK_EXPORT;
+ // script number, export number
bp.address = (atoi(argv[1]) << 16 | atoi(argv[2]));
_debugState._breakpoints.push_back(bp);
diff --git a/engines/sci/debug.h b/engines/sci/debug.h
index d9959f0b7f..8ddbbd0d45 100644
--- a/engines/sci/debug.h
+++ b/engines/sci/debug.h
@@ -34,18 +34,18 @@ namespace Sci {
// These types are used both as identifiers and as elements of bitfields
enum BreakpointType {
/**
- * Break when selector is executed. data contains (char *) selector name
+ * Break when a selector is executed. Data contains (char *) selector name
* (in the format Object::Method)
*/
- BREAK_SELECTOREXEC = 1 << 0, // break when selector gets executed
- BREAK_SELECTORREAD = 1 << 1, // break when selector gets executed
- BREAK_SELECTORWRITE = 1 << 2, // break when selector gets executed
+ BREAK_SELECTOREXEC = 1 << 0, // break when a function selector is executed
+ BREAK_SELECTORREAD = 1 << 1, // break when a variable selector is read
+ BREAK_SELECTORWRITE = 1 << 2, // break when a variable selector is written
/**
- * Break when an exported function is called. data contains
+ * Break when an exported function is called. Data contains
* script_no << 16 | export_no.
*/
- BREAK_EXPORT = 1 << 3
+ BREAK_EXPORT = 1 << 3
};
struct Breakpoint {
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 24f3c96f62..7e75dbf000 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -270,26 +270,6 @@ static void validate_write_var(reg_t *r, reg_t *stack_base, int type, int max, i
#define PUSH32(a) (*(validate_stack_addr(s, (s->xs->sp)++)) = (a))
#define POP32() (*(validate_stack_addr(s, --(s->xs->sp))))
-bool SciEngine::checkExportBreakpoint(uint16 script, uint16 pubfunct) {
- if (_debugState._activeBreakpointTypes & BREAK_EXPORT) {
- uint32 bpaddress;
-
- bpaddress = (script << 16 | pubfunct);
-
- Common::List<Breakpoint>::const_iterator bp;
- for (bp = _debugState._breakpoints.begin(); bp != _debugState._breakpoints.end(); ++bp) {
- if (bp->type == BREAK_EXPORT && bp->address == bpaddress) {
- _console->DebugPrintf("Break on script %d, export %d\n", script, pubfunct);
- _debugState.debugging = true;
- _debugState.breakpointWasHit = true;
- return true;
- }
- }
- }
-
- return false;
-}
-
ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackPtr sp, reg_t calling_obj, uint16 argc, StackPtr argp) {
int seg = s->_segMan->getScriptSegment(script);
Script *scr = s->_segMan->getScriptIfLoaded(seg);
@@ -322,6 +302,111 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP
return add_exec_stack_entry(s->_executionStack, make_reg(seg, temp), sp, calling_obj, argc, argp, -1, pubfunct, -1, calling_obj, s->_executionStack.size()-1, seg);
}
+bool SciEngine::checkSelectorBreakpoint(BreakpointType breakpointType, reg_t send_obj, int selector) {
+ Common::String methodName = _gamestate->_segMan->getObjectName(send_obj);
+ methodName += ("::" + getKernel()->getSelectorName(selector));
+
+ Common::List<Breakpoint>::const_iterator bpIter;
+ for (bpIter = _debugState._breakpoints.begin(); bpIter != _debugState._breakpoints.end(); ++bpIter) {
+ if ((*bpIter).type == breakpointType && (*bpIter).name == methodName) {
+ _console->DebugPrintf("Break on %s (in [%04x:%04x])\n", methodName.c_str(), PRINT_REG(send_obj));
+ _debugState.debugging = true;
+ _debugState.breakpointWasHit = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SciEngine::checkExportBreakpoint(uint16 script, uint16 pubfunct) {
+ if (_debugState._activeBreakpointTypes & BREAK_EXPORT) {
+ uint32 bpaddress = (script << 16 | pubfunct);
+
+ Common::List<Breakpoint>::const_iterator bp;
+ for (bp = _debugState._breakpoints.begin(); bp != _debugState._breakpoints.end(); ++bp) {
+ if (bp->type == BREAK_EXPORT && bp->address == bpaddress) {
+ _console->DebugPrintf("Break on script %d, export %d\n", script, pubfunct);
+ _debugState.debugging = true;
+ _debugState.breakpointWasHit = true;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+void debugSelectorCall(reg_t send_obj, Selector selector, int argc, StackPtr argp, ObjVarRef &varp, reg_t funcp, SegManager *segMan, SelectorType selectorType) {
+ int activeBreakpointTypes = g_sci->_debugState._activeBreakpointTypes;
+ const char *objectName = segMan->getObjectName(send_obj);
+ const char *selectorName = g_sci->getKernel()->getSelectorName(selector).c_str();
+ Console *con = g_sci->getSciDebugger();
+
+#ifdef VM_DEBUG_SEND
+ debugN("Send to %04x:%04x (%s), selector %04x (%s):", PRINT_REG(send_obj),
+ s->_segMan->getObjectName(send_obj), selector,
+ g_sci->getKernel()->getSelectorName(selector).c_str());
+#endif // VM_DEBUG_SEND
+
+ switch (selectorType) {
+ case kSelectorNone:
+ break;
+ case kSelectorVariable:
+#ifdef VM_DEBUG_SEND
+ if (argc)
+ debugN("Varselector: Write %04x:%04x\n", PRINT_REG(argp[1]));
+ else
+ debugN("Varselector: Read\n");
+#endif // VM_DEBUG_SEND
+
+ // argc == 0: read selector
+ // argc == 1: write selector
+ // argc can be bigger than 1 in some cases, because of a script bug.
+ // Usually, these aren't fatal.
+ if ((activeBreakpointTypes & BREAK_SELECTORREAD) ||
+ (activeBreakpointTypes & BREAK_SELECTORWRITE) ||
+ argc > 1) {
+
+ reg_t selectorValue = *varp.getPointer(segMan);
+ if (!argc && (activeBreakpointTypes & BREAK_SELECTORREAD)) {
+ if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORREAD, send_obj, selector))
+ con->DebugPrintf("Read from selector (%s:%s): %04x:%04x\n",
+ objectName, selectorName,
+ PRINT_REG(selectorValue));
+ } else if (argc && (activeBreakpointTypes & BREAK_SELECTORWRITE)) {
+ if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORWRITE, send_obj, selector))
+ con->DebugPrintf("Write to selector (%s:%s): change %04x:%04x to %04x:%04x\n",
+ objectName, selectorName,
+ PRINT_REG(selectorValue), PRINT_REG(argp[1]));
+ }
+
+ if (argc > 1)
+ debug(kDebugLevelScripts, "Write to selector (%s:%s): change %04x:%04x to %04x:%04x, argc == %d\n",
+ objectName, selectorName,
+ PRINT_REG(selectorValue), PRINT_REG(argp[1]), argc);
+ }
+ break;
+ case kSelectorMethod:
+#ifndef VM_DEBUG_SEND
+ if (activeBreakpointTypes & BREAK_SELECTOREXEC) {
+ if (g_sci->checkSelectorBreakpoint(BREAK_SELECTOREXEC, send_obj, selector)) {
+#else
+ if (true) {
+ if (true) {
+#endif
+ con->DebugPrintf("%s::%s(", objectName, selectorName);
+ for (int i = 0; i < argc; i++) {
+ con->DebugPrintf("%04x:%04x", PRINT_REG(argp[i+1]));
+ if (i + 1 < argc)
+ con->DebugPrintf(", ");
+ }
+ con->DebugPrintf(") at %04x:%04x\n", PRINT_REG(funcp));
+ }
+ }
+ break;
+ } // switch
+}
+
static void _exec_varselectors(EngineState *s) {
// Executes all varselector read/write ops on the TOS
@@ -357,38 +442,21 @@ struct CallsStruct {
int type; /**< Same as ExecStack.type */
};
-bool SciEngine::checkSelectorBreakpoint(BreakpointType breakpointType, reg_t send_obj, int selector) {
- Common::String methodName = _gamestate->_segMan->getObjectName(send_obj);
- methodName += ("::" + getKernel()->getSelectorName(selector));
-
- Common::List<Breakpoint>::const_iterator bpIter;
- for (bpIter = _debugState._breakpoints.begin(); bpIter != _debugState._breakpoints.end(); ++bpIter) {
- if ((*bpIter).type == breakpointType && (*bpIter).name == methodName) {
- _console->DebugPrintf("Break on %s (in [%04x:%04x])\n", methodName.c_str(), PRINT_REG(send_obj));
- _debugState.debugging = true;
- _debugState.breakpointWasHit = true;
- return true;
- }
- }
- return false;
-}
-
ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPtr sp, int framesize, StackPtr argp) {
-// send_obj and work_obj are equal for anything but 'super'
-// Returns a pointer to the TOS exec_stack element
+ // send_obj and work_obj are equal for anything but 'super'
+ // Returns a pointer to the TOS exec_stack element
assert(s);
reg_t funcp;
- int selector;
+ Selector selector;
int argc;
- int origin = s->_executionStack.size()-1; // Origin: Used for debugging
+ int origin = s->_executionStack.size() - 1; // Origin: Used for debugging
+ int activeBreakpointTypes = g_sci->_debugState._activeBreakpointTypes;
// We return a pointer to the new active ExecStack
// The selector calls we catch are stored below:
Common::Stack<CallsStruct> sendCalls;
- int activeBreakpointTypes = g_sci->_debugState._activeBreakpointTypes;
-
while (framesize > 0) {
selector = argp->requireUint16();
argp++;
@@ -397,145 +465,49 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt
if (argc > 0x800) // More arguments than the stack could possibly accomodate for
error("send_selector(): More than 0x800 arguments to function call");
-#ifdef VM_DEBUG_SEND
- debugN("Send to %04x:%04x (%s), selector %04x (%s):", PRINT_REG(send_obj),
- s->_segMan->getObjectName(send_obj), selector,
- g_sci->getKernel()->getSelectorName(selector).c_str());
-#endif // VM_DEBUG_SEND
-
ObjVarRef varp;
- switch (lookupSelector(s->_segMan, send_obj, selector, &varp, &funcp)) {
+ CallsStruct call;
+ call.argp = argp;
+ call.argc = argc;
+ call.selector = selector;
+ SelectorType selectorType = lookupSelector(s->_segMan, send_obj, selector, &varp, &funcp);
+ if (activeBreakpointTypes || DebugMan.isDebugChannelEnabled(kDebugLevelScripts))
+ debugSelectorCall(send_obj, selector, argc, argp, varp, funcp, s->_segMan, selectorType);
+
+ switch (selectorType) {
case kSelectorNone:
error("Send to invalid selector 0x%x of object at %04x:%04x", 0xffff & selector, PRINT_REG(send_obj));
break;
-
case kSelectorVariable:
-
-#ifdef VM_DEBUG_SEND
- if (argc)
- debugN("Varselector: Write %04x:%04x\n", PRINT_REG(argp[1]));
- else
- debugN("Varselector: Read\n");
-#endif // VM_DEBUG_SEND
-
- // argc == 0: read selector
- // argc != 0: write selector
- if (!argc) {
- // read selector
- if (activeBreakpointTypes & BREAK_SELECTORREAD) {
- if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORREAD, send_obj, selector))
- debug("[read selector]\n");
- }
- } else {
- // write selector
- if (activeBreakpointTypes & BREAK_SELECTORWRITE) {
- if (g_sci->checkSelectorBreakpoint(BREAK_SELECTORWRITE, send_obj, selector)) {
- reg_t oldReg = *varp.getPointer(s->_segMan);
- reg_t newReg = argp[1];
- warning("[write to selector (%s:%s): change %04x:%04x to %04x:%04x]\n",
- s->_segMan->getObjectName(send_obj), g_sci->getKernel()->getSelectorName(selector).c_str(),
- PRINT_REG(oldReg), PRINT_REG(newReg));
- }
- }
- }
-
- if (argc > 1) {
- // argc can indeed be bigger than 1 in some cases, and it's usually the
- // result of a script bug. Usually these aren't fatal.
-
- const char *objectName = s->_segMan->getObjectName(send_obj);
-
- reg_t oldReg = *varp.getPointer(s->_segMan);
- reg_t newReg = argp[1];
- const char *selectorName = g_sci->getKernel()->getSelectorName(selector).c_str();
- debug(2, "send_selector(): argc = %d while modifying variable selector "
- "%x (%s) of object %04x:%04x (%s) from %04x:%04x to %04x:%04x",
- argc, selector, selectorName, PRINT_REG(send_obj),
- objectName, PRINT_REG(oldReg), PRINT_REG(newReg));
- }
-
- {
- CallsStruct call;
- call.address.var = varp; // register the call
- call.argp = argp;
- call.argc = argc;
- call.selector = selector;
- call.type = EXEC_STACK_TYPE_VARSELECTOR; // Register as a varselector
- sendCalls.push(call);
- }
-
+ call.address.var = varp; // register the call
+ call.type = EXEC_STACK_TYPE_VARSELECTOR; // Register as a varselector
break;
-
case kSelectorMethod:
-
-#ifndef VM_DEBUG_SEND
- if (activeBreakpointTypes & BREAK_SELECTOREXEC) {
- if (g_sci->checkSelectorBreakpoint(BREAK_SELECTOREXEC, send_obj, selector)) {
- debugN("[execute selector]");
-
- int displaySize = 0;
- for (int argNr = 1; argNr <= argc; argNr++) {
- if (argNr == 1)
- debugN(" - ");
- reg_t curParam = argp[argNr];
- if (curParam.isPointer()) {
- debugN("[%04x:%04x] ", PRINT_REG(curParam));
- displaySize += 12;
- } else {
- debugN("[%04x] ", curParam.offset);
- displaySize += 7;
- }
- if (displaySize > 50) {
- if (argNr < argc)
- debugN("...");
- break;
- }
- }
- debugN("\n");
- }
- }
-#else // VM_DEBUG_SEND
- if (activeBreakpointTypes & BREAK_SELECTOREXEC)
- g_sci->checkSelectorBreakpoint(BREAK_SELECTOREXEC, send_obj, selector);
- debugN("Funcselector(");
- for (int i = 0; i < argc; i++) {
- debugN("%04x:%04x", PRINT_REG(argp[i+1]));
- if (i + 1 < argc)
- debugN(", ");
- }
- debugN(") at %04x:%04x\n", PRINT_REG(funcp));
-#endif // VM_DEBUG_SEND
-
- {
- CallsStruct call;
- call.address.func = funcp; // register call
- call.argp = argp;
- call.argc = argc;
- call.selector = selector;
- call.type = EXEC_STACK_TYPE_CALL;
- call.sp = sp;
- sp = CALL_SP_CARRY; // Destroy sp, as it will be carried over
- sendCalls.push(call);
- }
-
+ call.address.func = funcp; // register call
+ call.type = EXEC_STACK_TYPE_CALL;
+ call.sp = sp;
+ sp = CALL_SP_CARRY; // Destroy sp, as it will be carried over
break;
} // switch (lookupSelector())
+ sendCalls.push(call);
+
framesize -= (2 + argc);
argp += argc + 1;
- }
+ } // while (framesize > 0)
// Iterate over all registered calls in the reverse order. This way, the first call is
// placed on the TOS; as soon as it returns, it will cause the second call to be executed.
while (!sendCalls.empty()) {
CallsStruct call = sendCalls.pop();
if (call.type == EXEC_STACK_TYPE_VARSELECTOR) // Write/read variable?
- add_exec_stack_varselector(s->_executionStack, work_obj, call.argc, call.argp,
- call.selector, call.address.var, origin);
- else
+ add_exec_stack_varselector(s->_executionStack, work_obj,
+ call.argc, call.argp, call.selector,
+ call.address.var, origin);
+ else // Invoke function
add_exec_stack_entry(s->_executionStack, call.address.func, call.sp, work_obj,
- call.argc, call.argp,
- call.selector, -1, -1, send_obj, origin, SCI_XS_CALLEE_LOCALS);
+ call.argc, call.argp, call.selector,
+ -1, -1, send_obj, origin, SCI_XS_CALLEE_LOCALS);
}
_exec_varselectors(s);
diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp
index 17c9f9fa0f..bd93f602f8 100644
--- a/engines/sci/engine/workarounds.cpp
+++ b/engines/sci/engine/workarounds.cpp
@@ -90,7 +90,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = {
{ GID_KQ6, 520, 520, 0, "rm520", "init", -1, 0, { WORKAROUND_FAKE, 0 } }, // going to boiling water trap on beast isle
{ GID_KQ6, -1, 903, 0, "controlWin", "open", -1, 4, { WORKAROUND_FAKE, 0 } }, // when opening the controls window (save, load etc)
{ GID_KQ6, -1, 907, 0, "tomato", "doVerb", -1, 2, { WORKAROUND_FAKE, 0 } }, // when looking at the rotten tomato in the inventory - bug #3059544
- { GID_KQ7, 30, 64996, 0, "User", "handleEvent", -1, 1, { WORKAROUND_FAKE, 0 } }, // called when pushing a keyboard key
+ { GID_KQ7, -1, 64996, 0, "User", "handleEvent", -1, 1, { WORKAROUND_FAKE, 0 } }, // called when pushing a keyboard key
{ GID_LAURABOW, 37, 0, 0, "CB1", "doit", -1, 1, { WORKAROUND_FAKE, 0 } }, // when going up the stairs (bug #3037694)
{ GID_LAURABOW, -1, 967, 0, "myIcon", "cycle", -1, 1, { WORKAROUND_FAKE, 0 } }, // having any portrait conversation coming up (initial bug #3034985)
{ GID_LAURABOW2, -1, 24, 0, "gcWin", "open", -1, 5, { WORKAROUND_FAKE, 0xf } }, // is used as priority for game menu
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp
index fbfd140e6b..e68f964dab 100644
--- a/engines/sci/graphics/frameout.cpp
+++ b/engines/sci/graphics/frameout.cpp
@@ -123,7 +123,10 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) {
if (it->planeRect.left < 0) {
it->planeOffsetX = -it->planeRect.left;
it->planeRect.left = 0;
+ } else {
+ it->planeOffsetX = 0;
}
+
if (it->planeRect.top < 0)
it->planeRect.top = 0;
// We get bad plane-bottom in sq6
diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp
index 89463badd0..d544dad26f 100644
--- a/engines/sci/graphics/screen.cpp
+++ b/engines/sci/graphics/screen.cpp
@@ -156,12 +156,14 @@ void GfxScreen::copyToScreen() {
}
void GfxScreen::copyFromScreen(byte *buffer) {
+ // TODO this ignores the pitch
Graphics::Surface *screen = g_system->lockScreen();
memcpy(buffer, screen->pixels, _displayPixels);
g_system->unlockScreen();
}
void GfxScreen::kernelSyncWithFramebuffer() {
+ // TODO this ignores the pitch
Graphics::Surface *screen = g_system->lockScreen();
memcpy(_displayScreen, screen->pixels, _displayPixels);
g_system->unlockScreen();
diff --git a/engines/sword25/gfx/image/pngloader.cpp b/engines/sword25/gfx/image/pngloader.cpp
index e2a8510c32..f6c00b6968 100644
--- a/engines/sword25/gfx/image/pngloader.cpp
+++ b/engines/sword25/gfx/image/pngloader.cpp
@@ -218,7 +218,7 @@ bool PNGLoader::doDecodeImage(const byte *fileDataPtr, uint fileSize, byte *&unc
Common::MemoryReadStream *fileStr = new Common::MemoryReadStream(fileDataPtr, fileSize, DisposeAfterUse::NO);
Graphics::PNG *png = new Graphics::PNG();
if (!png->read(fileStr)) // the fileStr pointer, and thus pFileData will be deleted after this is done
- error("Error while reading PNG image");
+ error("Error while reading PNG image");
Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
Graphics::Surface *pngSurface = png->getSurface(format);
diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp
index 0d2ffb5aee..ced3296e57 100644
--- a/engines/sword25/gfx/image/renderedimage.cpp
+++ b/engines/sword25/gfx/image/renderedimage.cpp
@@ -59,7 +59,7 @@ RenderedImage::RenderedImage(const Common::String &filename, bool &result) :
_backSurface = Kernel::getInstance()->getGfx()->getSurface();
- // Datei laden
+ // Load file
byte *pFileData;
uint fileSize;
pFileData = pPackage->getFile(filename, &fileSize);
@@ -68,7 +68,7 @@ RenderedImage::RenderedImage(const Common::String &filename, bool &result) :
return;
}
- // Bildeigenschaften bestimmen
+ // Determine image properties
int pitch;
if (!PNGLoader::imageProperties(pFileData, fileSize, _width, _height)) {
error("Could not read image properties.");
@@ -76,14 +76,14 @@ RenderedImage::RenderedImage(const Common::String &filename, bool &result) :
return;
}
- // Das Bild dekomprimieren
+ // Uncompress the image
if (!PNGLoader::decodeImage(pFileData, fileSize, _data, _width, _height, pitch)) {
error("Could not decode image.");
delete[] pFileData;
return;
}
- // Dateidaten freigeben
+ // Cleanup FileData
delete[] pFileData;
_doCleanup = true;
@@ -134,7 +134,7 @@ bool RenderedImage::fill(const Common::Rect *pFillRect, uint color) {
// -----------------------------------------------------------------------------
bool RenderedImage::setContent(const byte *pixeldata, uint size, uint offset, uint stride) {
- // Überprüfen, ob PixelData ausreichend viele Pixel enthält um ein Bild der Größe Width * Height zu erzeugen
+ // Check if PixelData contains enough pixel to create an image with image size equals width * height
if (size < static_cast<uint>(_width * _height * 4)) {
error("PixelData vector is too small to define a 32 bit %dx%d image.", _width, _height);
return false;
@@ -198,11 +198,11 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
srcImage.w = pPartRect->right - pPartRect->left;
srcImage.h = pPartRect->bottom - pPartRect->top;
- debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping,
+ debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping,
pPartRect->left, pPartRect->top, pPartRect->width(), pPartRect->height(), color, width, height);
} else {
- debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping, 0, 0,
+ debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping, 0, 0,
srcImage.w, srcImage.h, color, width, height);
}
@@ -324,7 +324,7 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe
ino += inoStep;
}
- g_system->copyRectToScreen((byte *)_backSurface->getBasePtr(posX, posY), _backSurface->pitch, posX, posY,
+ g_system->copyRectToScreen((byte *)_backSurface->getBasePtr(posX, posY), _backSurface->pitch, posX, posY,
img->w, img->h);
}
@@ -413,7 +413,7 @@ int *RenderedImage::scaleLine(int size, int srcSize) {
distCtr -= 100;
}
}
-
+
return v;
}
diff --git a/engines/sword25/gfx/image/renderedimage.h b/engines/sword25/gfx/image/renderedimage.h
index 0375c7acbe..e3f23747da 100644
--- a/engines/sword25/gfx/image/renderedimage.h
+++ b/engines/sword25/gfx/image/renderedimage.h
@@ -50,12 +50,12 @@ public:
RenderedImage(const Common::String &filename, bool &result);
/**
- @brief Erzeugt ein leeres BS_RenderedImage
+ @brief Creates an empty BS_RenderedImage
- @param Width die Breite des zu erzeugenden Bildes.
- @param Height die Höhe des zu erzeugenden Bildes
- @param Result gibt dem Aufrufer bekannt, ob der Konstruktor erfolgreich ausgeführt wurde. Wenn es nach dem Aufruf false enthalten sollte,
- dürfen keine Methoden am Objekt aufgerufen werden und das Objekt ist sofort zu zerstören.
+ @param Width The width of the image to be created.
+ @param Height The height of the image to be created
+ @param Result Informs the caller, whether the constructor is executed successfully. If it contains false
+ after the call, do not call methods on the object and destroy the object immediately.
*/
RenderedImage(uint width, uint height, bool &result);
RenderedImage();
@@ -84,25 +84,25 @@ public:
void replaceContent(byte *pixeldata, int width, int height);
virtual uint getPixel(int x, int y);
- virtual bool isBlitSource() const {
+ virtual bool isBlitSource() const {
return true;
}
- virtual bool isBlitTarget() const {
+ virtual bool isBlitTarget() const {
return false;
}
- virtual bool isScalingAllowed() const {
+ virtual bool isScalingAllowed() const {
return true;
}
- virtual bool isFillingAllowed() const {
+ virtual bool isFillingAllowed() const {
return false;
}
- virtual bool isAlphaAllowed() const {
+ virtual bool isAlphaAllowed() const {
return true;
}
- virtual bool isColorModulationAllowed() const {
+ virtual bool isColorModulationAllowed() const {
return true;
}
- virtual bool isSetContentAllowed() const {
+ virtual bool isSetContentAllowed() const {
return true;
}
diff --git a/engines/sword25/gfx/image/swimage.cpp b/engines/sword25/gfx/image/swimage.cpp
index ff06491b36..3b9b939eb3 100644
--- a/engines/sword25/gfx/image/swimage.cpp
+++ b/engines/sword25/gfx/image/swimage.cpp
@@ -47,7 +47,7 @@ SWImage::SWImage(const Common::String &filename, bool &result) :
PackageManager *pPackage = Kernel::getInstance()->getPackage();
assert(pPackage);
- // Datei laden
+ // Load file
byte *pFileData;
uint fileSize;
pFileData = pPackage->getFile(filename, &fileSize);
@@ -56,21 +56,21 @@ SWImage::SWImage(const Common::String &filename, bool &result) :
return;
}
- // Bildeigenschaften bestimmen
+ // Determine image properties
int pitch;
if (!PNGLoader::imageProperties(pFileData, fileSize, _width, _height)) {
error("Could not read image properties.");
return;
}
- // Das Bild dekomprimieren
+ // Uncompress the image
byte *pUncompressedData;
if (!PNGLoader::decodeImage(pFileData, fileSize, pUncompressedData, _width, _height, pitch)) {
error("Could not decode image.");
return;
}
- // Dateidaten freigeben
+ // Cleanup FileData
delete[] pFileData;
_imageDataPtr = (uint *)pUncompressedData;
diff --git a/engines/sword25/gfx/image/vectorimage.cpp b/engines/sword25/gfx/image/vectorimage.cpp
index 094e6a59a8..241e80bad3 100644
--- a/engines/sword25/gfx/image/vectorimage.cpp
+++ b/engines/sword25/gfx/image/vectorimage.cpp
@@ -47,15 +47,15 @@ namespace Sword25 {
#define BEZSMOOTHNESS 0.5
// -----------------------------------------------------------------------------
-// SWF Datentypen
+// SWF datatype
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
-// Bitstream Hilfsklasse
+// Bitstream helper class
// -----------------------------------------------------------------------------
-// Das Parsen von SWF-Dateien erfordert sowohl bitweises Auslesen als auch an
-// Bytegrenzen ausgerichtetes Lesen.
-// Diese Klasse ist speziell dafür ausgestattet.
+// The parsing of SWF files requires both bitwise readout and on Byte boundaries
+// oriented reading.
+// This class is specially equipped for this.
// -----------------------------------------------------------------------------
class VectorImage::SWFBitStream {
@@ -85,10 +85,10 @@ public:
}
inline int32 getSignedBits(uint bitCount) {
- // Bits einlesen
+ // readout bits
uint32 temp = getBits(bitCount);
- // Falls das Sign-Bit gesetzt ist, den Rest des Rückgabewertes mit 1-Bits auffüllen (Sign Extension)
+ // If the sign-bit is set, fill the rest of the return value with 1-bit (sign extension)
if (temp & 1 << (bitCount - 1))
return (0xffffffff << bitCount) | temp;
else
@@ -151,28 +151,28 @@ private:
// -----------------------------------------------------------------------------
-// Konstanten und Hilfsfunktionen
+// Constants and utility functions
// -----------------------------------------------------------------------------
namespace {
// -----------------------------------------------------------------------------
-// Konstanten
+// Constants
// -----------------------------------------------------------------------------
-const uint32 MAX_ACCEPTED_FLASH_VERSION = 3; // Die höchste Flash-Dateiversion, die vom Lader akzeptiert wird
+const uint32 MAX_ACCEPTED_FLASH_VERSION = 3; // The maximum flash file version that is accepted by the loader
// -----------------------------------------------------------------------------
-// Konvertiert SWF-Rechteckdaten in einem Bitstrom in Common::Rect-Objekte
+// Converts SWF rectangle data in a bit stream in Common::Rect objects
// -----------------------------------------------------------------------------
Common::Rect flashRectToBSRect(VectorImage::SWFBitStream &bs) {
bs.flushByte();
- // Feststellen mit wie vielen Bits die einzelnen Komponenten kodiert sind
+ // Determines how many bits of the single components are encoded
uint32 bitsPerValue = bs.getBits(5);
- // Die einzelnen Komponenten einlesen
+ // Readout the single components
int32 xMin = bs.getSignedBits(bitsPerValue);
int32 xMax = bs.getSignedBits(bitsPerValue);
int32 yMin = bs.getSignedBits(bitsPerValue);
@@ -182,7 +182,7 @@ Common::Rect flashRectToBSRect(VectorImage::SWFBitStream &bs) {
}
// -----------------------------------------------------------------------------
-// Berechnet die Bounding-Box eines BS_VectorImageElement
+// Calculate the bounding box of a BS_VectorImageElement
// -----------------------------------------------------------------------------
Common::Rect CalculateBoundingBox(const VectorImageElement &vectorImageElement) {
@@ -214,17 +214,17 @@ Common::Rect CalculateBoundingBox(const VectorImageElement &vectorImageElement)
// -----------------------------------------------------------------------------
-// Konstruktion
+// Construction
// -----------------------------------------------------------------------------
VectorImage::VectorImage(const byte *pFileData, uint fileSize, bool &success, const Common::String &fname) : _pixelData(0), _fname(fname) {
success = false;
- // Bitstream-Objekt erzeugen
- // Im Folgenden werden die Dateidaten aus diesem ausgelesen.
+ // Create bitstream object
+ // In the following the file data will be readout of the bitstream object.
SWFBitStream bs(pFileData, fileSize);
- // SWF-Signatur überprüfen
+ // Check SWF signature
uint32 signature[3];
signature[0] = bs.getByte();
signature[1] = bs.getByte();
@@ -236,37 +236,37 @@ VectorImage::VectorImage(const byte *pFileData, uint fileSize, bool &success, co
return;
}
- // Versionsangabe überprüfen
+ // Check the version
uint32 version = bs.getByte();
if (version > MAX_ACCEPTED_FLASH_VERSION) {
error("File is of version %d. Highest accepted version is %d.", version, MAX_ACCEPTED_FLASH_VERSION);
return;
}
- // Dateigröße auslesen und mit der tatsächlichen Größe vergleichen
+ // Readout filesize and compare with the actual size
uint32 storedFileSize = bs.getUInt32();
if (storedFileSize != fileSize) {
error("File is not a valid SWF-file");
return;
}
- // SWF-Maße auslesen
+ // readout SWF size
Common::Rect movieRect = flashRectToBSRect(bs);
- // Framerate und Frameanzahl auslesen
+ // Get frame rate and frame count
/* uint32 frameRate = */
bs.getUInt16();
/* uint32 frameCount = */
bs.getUInt16();
- // Tags parsen
- // Da wir uns nur für das erste DefineShape-Tag interessieren
+ // Parse tags
+ // Because we are only interested in the first DifneShape-Tag...
bool keepParsing = true;
while (keepParsing) {
- // Tags beginnen immer an Bytegrenzen
+ // Tags always begin on byte boundaries
bs.flushByte();
- // Tagtyp und Länge auslesen
+ // Readout tag type and length
uint16 tagTypeAndLength = bs.getUInt16();
uint32 tagType = tagTypeAndLength >> 6;
uint32 tagLength = tagTypeAndLength & 0x3f;
@@ -286,13 +286,13 @@ VectorImage::VectorImage(const byte *pFileData, uint fileSize, bool &success, co
success = parseDefineShape(3, bs);
return;
default:
- // Unbekannte Tags ignorieren
+ // Ignore unknown tags
bs.skipBytes(tagLength);
}
}
- // Die Ausführung darf nicht an dieser Stelle ankommen: Entweder es wird ein Shape gefunden, dann wird die Funktion mit vorher verlassen, oder
- // es wird keines gefunden, dann tritt eine Exception auf sobald über das Ende der Datei hinaus gelesen wird.
+ // The execution must not arrive at this point: Either a shape is found, then the function will be leaved before, or it is found none, then
+ // an exception occurs as soon as it is read beyond of the end of file.
assert(false);
}
@@ -336,13 +336,13 @@ ArtBpath *VectorImage::storeBez(ArtBpath *bez, int lineStyle, int fillStyle0, in
bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
/*uint32 shapeID = */bs.getUInt16();
- // Bounding Box auslesen
+ // readout bounding box
_boundingBox = flashRectToBSRect(bs);
- // Erstes Image-Element erzeugen
+ // create first image element
_elements.resize(1);
- // Styles einlesen
+ // read styles
uint numFillBits;
uint numLineBits;
if (!parseStyles(shapeType, bs, numFillBits, numLineBits))
@@ -352,7 +352,7 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
uint fillStyle0 = 0;
uint fillStyle1 = 0;
- // Shaperecord parsen
+ // parse shaperecord
// ------------------
double curX = 0;
@@ -367,7 +367,7 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
// Non-Edge Record
if (typeFlag == 0) {
- // Feststellen welche Parameter gesetzt werden
+ // Determines which parameters are set
uint32 stateNewStyles = bs.getBits(1);
uint32 stateLineStyle = bs.getBits(1);
uint32 stateFillStyle1 = bs.getBits(1);
@@ -378,10 +378,10 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
uint prevFillStyle0 = fillStyle0;
uint prevFillStyle1 = fillStyle1;
- // End der Shape-Definition erreicht?
+ // End of the shape definition is reached?
if (!stateNewStyles && !stateLineStyle && !stateFillStyle0 && !stateFillStyle1 && !stateMoveTo) {
endOfShapeDiscovered = true;
- // Parameter dekodieren
+ // Decode parameters
} else {
if (stateMoveTo) {
uint32 moveToBits = bs.getBits(5);
@@ -410,7 +410,7 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
numLineBits = 0;
}
- // Ein neuen Pfad erzeugen, es sei denn, es wurden nur neue Styles definiert
+ // Create a new path, unless there were only defined new styles
if (stateLineStyle || stateFillStyle0 || stateFillStyle1 || stateMoveTo) {
// Store previous curve if any
if (bezNodes) {
@@ -426,15 +426,15 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
}
if (stateNewStyles) {
- // An dieser Stelle werden in Flash die alten Style-Definitionen verworfen und mit den neuen überschrieben.
- // Es wird ein neues Element begonnen.
+ // The old style definitions will be discarded and overwritten with the new at this point in Flash.
+ // A new element will be started with a new element.
_elements.resize(_elements.size() + 1);
if (!parseStyles(shapeType, bs, numFillBits, numLineBits))
return false;
}
}
} else {
- // Edge Record
+ // Edge record
uint32 edgeFlag = bs.getBits(1);
uint32 numBits = bs.getBits(4) + 2;
@@ -499,7 +499,7 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
free(bez);
- // Bounding-Boxes der einzelnen Elemente berechnen
+ // Calculate the bounding boxes of each element
Common::Array<VectorImageElement>::iterator it = _elements.begin();
for (; it != _elements.end(); ++it)
it->_boundingBox = CalculateBoundingBox(*it);
@@ -513,16 +513,16 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
bool VectorImage::parseStyles(uint shapeType, SWFBitStream &bs, uint &numFillBits, uint &numLineBits) {
bs.flushByte();
- // Fillstyles parsen
+ // Parse fill styles
// -----------------
- // Anzahl an Fillstyles bestimmen
+ // Determine number of fill styles
uint fillStyleCount = bs.getByte();
if (fillStyleCount == 0xff)
fillStyleCount = bs.getUInt16();
- // Alle Fillstyles einlesen, falls ein Fillstyle mit Typ != 0 gefunden wird, wird das Parsen abgebrochen.
- // Es wird nur "solid fill" (Typ 0) unterstützt.
+ // Readout all fill styles. If a fill style with Typ != 0 is found, the parsing is aborted.
+ // Only "solid fill" (Typ 0) is supported.
_elements.back()._fillStyles.reserve(fillStyleCount);
for (uint i = 0; i < fillStyleCount; ++i) {
byte type = bs.getByte();
@@ -543,15 +543,15 @@ bool VectorImage::parseStyles(uint shapeType, SWFBitStream &bs, uint &numFillBit
_elements.back()._fillStyles.push_back(color);
}
- // Linestyles parsen
+ // Line styles parsen
// -----------------
- // Anzahl an Linestyles bestimmen
+ // Determine number of line styles
uint lineStyleCount = bs.getByte();
if (lineStyleCount == 0xff)
lineStyleCount = bs.getUInt16();
- // Alle Linestyles einlesen
+ // Readout all line styles
_elements.back()._lineStyles.reserve(lineStyleCount);
for (uint i = 0; i < lineStyleCount; ++i) {
double width = bs.getUInt16();
@@ -569,7 +569,7 @@ bool VectorImage::parseStyles(uint shapeType, SWFBitStream &bs, uint &numFillBit
_elements.back()._lineStyles.push_back(VectorImageElement::LineStyleType(width, color));
}
- // Bitbreite für die folgenden Styleindizes auslesen
+ // Readout the bit width for the following style indices
numFillBits = bs.getBits(4);
numLineBits = bs.getBits(4);
@@ -608,11 +608,11 @@ bool VectorImage::blit(int posX, int posY,
static int oldWidth = -2;
static int oldHeight = -2;
- // Falls Breite oder Höhe 0 sind, muss nichts dargestellt werden.
+ // If width or height to 0, nothing needs to be shown.
if (width == 0 || height == 0)
return true;
- // Feststellen, ob das alte Bild im Cache nicht wiederbenutzt werden kann und neu Berechnet werden muss
+ // Determine if the old image in the cache can not be reused and must be recalculated
if (!(oldThis == this && oldWidth == width && oldHeight == height)) {
render(width, height);
diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index 943beb474e..3b9833b418 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -388,37 +388,23 @@ void DeleteMidiBuffer() {
MidiMusicPlayer::MidiMusicPlayer() {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
- bool native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
+ _nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
//bool adlib = (MidiDriver::getMusicType(dev) == MT_ADLIB);
_driver = MidiDriver::createMidi(dev);
assert(_driver);
- if (native_mt32)
+ if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
int ret = _driver->open();
if (ret == 0) {
- if (native_mt32)
+ if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
- _driver->setTimerCallback(this, &onTimer);
+ _driver->setTimerCallback(this, &timerCallback);
}
-
- _xmidiParser = MidiParser::createParser_XMIDI();
-}
-
-MidiMusicPlayer::~MidiMusicPlayer() {
- _driver->setTimerCallback(NULL, NULL);
- stop();
- if (_driver) {
- _driver->close();
- delete _driver;
- _driver = 0;
- }
- _xmidiParser->setMidiDriver(NULL);
- delete _xmidiParser;
}
void MidiMusicPlayer::setVolume(int volume) {
@@ -441,15 +427,9 @@ void MidiMusicPlayer::send(uint32 b) {
}
}
-void MidiMusicPlayer::onTimer(void *refCon) {
- MidiMusicPlayer *music = (MidiMusicPlayer *)refCon;
- Common::StackLock lock(music->_mutex);
-
- if (music->_isPlaying)
- music->_parser->onTimer();
-}
-
void MidiMusicPlayer::playXMIDI(byte *midiData, uint32 size, bool loop) {
+ Common::StackLock lock(_mutex);
+
if (_isPlaying)
return;
@@ -467,8 +447,8 @@ void MidiMusicPlayer::playXMIDI(byte *midiData, uint32 size, bool loop) {
// Load XMID resource data
- if (_xmidiParser->loadMusic(midiData, size)) {
- MidiParser *parser = _xmidiParser;
+ MidiParser *parser = MidiParser::createParser_XMIDI();
+ if (parser->loadMusic(midiData, size)) {
parser->setTrack(0);
parser->setMidiDriver(this);
parser->setTimerRate(getBaseTempo());
@@ -479,6 +459,8 @@ void MidiMusicPlayer::playXMIDI(byte *midiData, uint32 size, bool loop) {
_isLooping = loop;
_isPlaying = true;
+ } else {
+ delete parser;
}
}
diff --git a/engines/tinsel/music.h b/engines/tinsel/music.h
index 9436c02032..af089caf24 100644
--- a/engines/tinsel/music.h
+++ b/engines/tinsel/music.h
@@ -64,7 +64,6 @@ void dumpMusic();
class MidiMusicPlayer : public Audio::MidiPlayer {
public:
MidiMusicPlayer();
- ~MidiMusicPlayer();
virtual void setVolume(int volume);
@@ -80,12 +79,6 @@ public:
// The original sets the "sequence timing" to 109 Hz, whatever that
// means. The default is 120.
uint32 getBaseTempo() { return _driver ? (109 * _driver->getBaseTempo()) / 120 : 0; }
-
-protected:
-
- static void onTimer(void *data);
-
- MidiParser *_xmidiParser;
};
class PCMMusicPlayer : public Audio::AudioStream {
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index ef0fe1c909..1b3173719f 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -859,8 +859,6 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc)
_midiMusic = new MidiMusicPlayer();
_pcmMusic = new PCMMusicPlayer();
- _musicVolume = ConfMan.getInt("music_volume");
-
_sound = new SoundManager(this);
_bmv = new BMVPlayer();
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index 009f6fe26d..5c7a1cdfb2 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -219,9 +219,6 @@ public:
RectList _clipRects;
private:
- //MidiMusicPlayer *_midiMusic;
- int _musicVolume;
-
void NextGameCycle();
void CreateConstProcesses();
void RestartGame();
diff --git a/engines/touche/midi.cpp b/engines/touche/midi.cpp
index 4349a29bf5..c89375d876 100644
--- a/engines/touche/midi.cpp
+++ b/engines/touche/midi.cpp
@@ -32,9 +32,21 @@
namespace Touche {
-MidiPlayer::MidiPlayer()
- : _driver(0), _parser(0), _midiData(0), _isLooping(false), _isPlaying(false), _masterVolume(0) {
- memset(_channelsTable, 0, sizeof(_channelsTable));
+static const uint8 _gmToRol[256] = {
+ 0x01, 0x02, 0x03, 0x08, 0x04, 0x05, 0x11, 0x14, 0x66, 0x66, 0x66, 0x62, 0x69, 0x68, 0x67, 0x26,
+ 0x09, 0x0A, 0x0B, 0x0E, 0x0F, 0x10, 0x10, 0x10, 0x3C, 0x3D, 0x3D, 0x3D, 0x3D, 0x3E, 0x3F, 0x3F,
+ 0x47, 0x41, 0x42, 0x48, 0x45, 0x46, 0x1D, 0x1E, 0x35, 0x36, 0x37, 0x39, 0x33, 0x34, 0x3A, 0x71,
+ 0x31, 0x32, 0x31, 0x32, 0x23, 0x23, 0x23, 0x7B, 0x59, 0x5B, 0x5F, 0x5A, 0x5D, 0x60, 0x19, 0x1A,
+ 0x4F, 0x50, 0x51, 0x52, 0x55, 0x56, 0x57, 0x53, 0x4B, 0x49, 0x4D, 0x4E, 0x6F, 0x6C, 0x6D, 0x6E,
+ 0x30, 0x19, 0x4E, 0x2B, 0x28, 0x23, 0x19, 0x30, 0x21, 0x25, 0x1C, 0x21, 0x24, 0x22, 0x21, 0x22,
+ 0x2A, 0x25, 0x24, 0x26, 0x2E, 0x22, 0x29, 0x21, 0x40, 0x40, 0x6A, 0x6A, 0x68, 0x10, 0x35, 0x10,
+ 0x7F, 0x6B, 0x69, 0x75, 0x76, 0x72, 0x74, 0x01, 0x01, 0x70, 0x01, 0x7D, 0x7C, 0x01, 0x01, 0x01
+};
+
+
+MidiPlayer::MidiPlayer() {
+
+ // FIXME: Necessary?
memset(_channelsVolume, 0, sizeof(_channelsVolume));
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
@@ -42,9 +54,6 @@ MidiPlayer::MidiPlayer()
_driver = MidiDriver::createMidi(dev);
int ret = _driver->open();
if (ret == 0) {
- _parser = MidiParser::createParser_SMF();
- _parser->setMidiDriver(this);
- _parser->setTimerRate(_driver->getBaseTempo());
_driver->setTimerCallback(this, &timerCallback);
if (_nativeMT32)
@@ -54,25 +63,18 @@ MidiPlayer::MidiPlayer()
}
}
-MidiPlayer::~MidiPlayer() {
- stop();
-
+void MidiPlayer::play(Common::ReadStream &stream, int size, bool loop) {
Common::StackLock lock(_mutex);
- _driver->setTimerCallback(NULL, NULL);
- _driver->close();
- delete _driver;
- _driver = 0;
- _parser->setMidiDriver(NULL);
- delete _parser;
-}
-void MidiPlayer::play(Common::ReadStream &stream, int size, bool loop) {
stop();
- _midiData = (uint8 *)malloc(size);
+ _midiData = (byte *)malloc(size);
if (_midiData) {
stream.read(_midiData, size);
- Common::StackLock lock(_mutex);
+ _parser = MidiParser::createParser_SMF();
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
+
_parser->loadMusic(_midiData, size);
_parser->setTrack(0);
_isLooping = loop;
@@ -80,31 +82,22 @@ void MidiPlayer::play(Common::ReadStream &stream, int size, bool loop) {
}
}
-void MidiPlayer::stop() {
- Common::StackLock lock(_mutex);
- if (_isPlaying) {
- _isPlaying = false;
- _parser->unloadMusic();
- free(_midiData);
- _midiData = 0;
- }
-}
-
-void MidiPlayer::updateTimer() {
- Common::StackLock lock(_mutex);
- if (_isPlaying) {
- _parser->onTimer();
- }
-}
-
void MidiPlayer::adjustVolume(int diff) {
setVolume(_masterVolume + diff);
}
void MidiPlayer::setVolume(int volume) {
+ // FIXME: This is almost identical to Audio::MidiPlayer::setVolume,
+ // the only difference is that this implementation will always
+ // transmit the volume change, even if the current _masterVolume
+ // equals the new master volume. This *could* make a difference in
+ // some situations.
+ // So, we should determine whether Touche requires this behavioral
+ // difference; and maybe also if other engines could benefit from it
+ // (as hypothetically, it might fix some subtle bugs?)
_masterVolume = CLIP(volume, 0, 255);
Common::StackLock lock(_mutex);
- for (int i = 0; i < NUM_CHANNELS; ++i) {
+ for (int i = 0; i < kNumChannels; ++i) {
if (_channelsTable[i]) {
_channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255);
}
@@ -112,52 +105,10 @@ void MidiPlayer::setVolume(int volume) {
}
void MidiPlayer::send(uint32 b) {
- byte volume, ch = (byte)(b & 0xF);
- switch (b & 0xFFF0) {
- case 0x07B0: // volume change
- volume = (byte)((b >> 16) & 0x7F);
- _channelsVolume[ch] = volume;
- volume = volume * _masterVolume / 255;
- b = (b & 0xFF00FFFF) | (volume << 16);
- break;
- case 0x7BB0: // all notes off
- if (!_channelsTable[ch]) {
- // channel not yet allocated, no need to send the event
- return;
- }
- break;
- default:
- if ((b & 0xF0) == 0xC0 && _nativeMT32) { // program change
- b = (b & 0xFFFF00FF) | (_gmToRol[(b >> 8) & 0x7F] << 8);
- }
- break;
+ if ((b & 0xF0) == 0xC0 && _nativeMT32) { // program change
+ b = (b & 0xFFFF00FF) | (_gmToRol[(b >> 8) & 0x7F] << 8);
}
- if (!_channelsTable[ch]) {
- _channelsTable[ch] = (ch == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
- }
- if (_channelsTable[ch]) {
- _channelsTable[ch]->send(b);
- }
-}
-
-void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) {
- switch (type) {
- case 0x2F: // end of Track
- if (_isLooping) {
- _parser->jumpToTick(0);
- } else {
- stop();
- }
- break;
- default:
-// warning("Unhandled meta event: %02x", type);
- break;
- }
-}
-
-void MidiPlayer::timerCallback(void *p) {
- MidiPlayer *player = (MidiPlayer *)p;
- player->updateTimer();
+ Audio::MidiPlayer::send(b);
}
} // Touche namespace
diff --git a/engines/touche/midi.h b/engines/touche/midi.h
index bc5adc6b5f..f0f55e64e6 100644
--- a/engines/touche/midi.h
+++ b/engines/touche/midi.h
@@ -29,7 +29,7 @@
#include "common/util.h"
#include "common/mutex.h"
-#include "audio/mididrv.h"
+#include "audio/midiplayer.h"
class MidiParser;
@@ -39,44 +39,16 @@ namespace Common {
namespace Touche {
-class MidiPlayer : public MidiDriver_BASE {
+class MidiPlayer : public Audio::MidiPlayer {
public:
-
- enum {
- NUM_CHANNELS = 16
- };
-
MidiPlayer();
- ~MidiPlayer();
void play(Common::ReadStream &stream, int size, bool loop = false);
- void stop();
- void updateTimer();
void adjustVolume(int diff);
void setVolume(int volume);
- int getVolume() const { return _masterVolume; }
- void setLooping(bool loop) { _isLooping = loop; }
// MidiDriver_BASE interface
virtual void send(uint32 b);
- virtual void metaEvent(byte type, byte *data, uint16 length);
-
-private:
-
- static void timerCallback(void *p);
-
- MidiDriver *_driver;
- MidiParser *_parser;
- uint8 *_midiData;
- bool _isLooping;
- bool _isPlaying;
- int _masterVolume;
- bool _nativeMT32;
- MidiChannel *_channelsTable[NUM_CHANNELS];
- uint8 _channelsVolume[NUM_CHANNELS];
- Common::Mutex _mutex;
-
- static const uint8 _gmToRol[];
};
} // namespace Touche
diff --git a/engines/touche/staticres.cpp b/engines/touche/staticres.cpp
index a377a6e45f..74aa7954de 100644
--- a/engines/touche/staticres.cpp
+++ b/engines/touche/staticres.cpp
@@ -1822,15 +1822,4 @@ int Graphics::_fontSize = Graphics::_engFontSize;
const uint8 *Graphics::_fontData = Graphics::_engFontData;
-const uint8 MidiPlayer::_gmToRol[] = {
- 0x01, 0x02, 0x03, 0x08, 0x04, 0x05, 0x11, 0x14, 0x66, 0x66, 0x66, 0x62, 0x69, 0x68, 0x67, 0x26,
- 0x09, 0x0A, 0x0B, 0x0E, 0x0F, 0x10, 0x10, 0x10, 0x3C, 0x3D, 0x3D, 0x3D, 0x3D, 0x3E, 0x3F, 0x3F,
- 0x47, 0x41, 0x42, 0x48, 0x45, 0x46, 0x1D, 0x1E, 0x35, 0x36, 0x37, 0x39, 0x33, 0x34, 0x3A, 0x71,
- 0x31, 0x32, 0x31, 0x32, 0x23, 0x23, 0x23, 0x7B, 0x59, 0x5B, 0x5F, 0x5A, 0x5D, 0x60, 0x19, 0x1A,
- 0x4F, 0x50, 0x51, 0x52, 0x55, 0x56, 0x57, 0x53, 0x4B, 0x49, 0x4D, 0x4E, 0x6F, 0x6C, 0x6D, 0x6E,
- 0x30, 0x19, 0x4E, 0x2B, 0x28, 0x23, 0x19, 0x30, 0x21, 0x25, 0x1C, 0x21, 0x24, 0x22, 0x21, 0x22,
- 0x2A, 0x25, 0x24, 0x26, 0x2E, 0x22, 0x29, 0x21, 0x40, 0x40, 0x6A, 0x6A, 0x68, 0x10, 0x35, 0x10,
- 0x7F, 0x6B, 0x69, 0x75, 0x76, 0x72, 0x74, 0x01, 0x01, 0x70, 0x01, 0x7D, 0x7C, 0x01, 0x01, 0x01
-};
-
} // namespace Touche