diff options
147 files changed, 1824 insertions, 1370 deletions
@@ -203,6 +203,10 @@ ScummVM Team Filippos Karapetis Joost Peters + Toltecs: + Benjamin Haisch + Filippos Karapetis + Tony: Arnaud Boutonne Paul Gilbert @@ -1,5 +1,5 @@ ScummVM -Copyright (C) 2001-2012 by the following: +Copyright (C) 2001-2013 by the following: If you have contributed to this project then you deserve to be on this list. Contact us (see: AUTHORS) and we'll add you. @@ -3,6 +3,7 @@ For a more comprehensive changelog of the latest experimental code, see: 1.6.0 (????-??-??) New Games: + - Added support for 3 Skulls of the Toltecs. - Added support for Eye of the Beholder. - Added support for Eye of the Beholder II: The Legend of Darkmoon. @@ -15,12 +16,26 @@ For a more comprehensive changelog of the latest experimental code, see: - Added Galician translation. - Added Finnish translation. - Added Belarusian translation. + - Using the mouse wheel on a slider widget now changes the value by the + smallest possible amount. This is more predictable than the old behaviour, + which was to change the value by "one pixel" which would sometimes not + change it at all. + - Updated MT-32 emulation code to latest munt project snapshot. Cine: - Improved audio support for Amiga and AtariST versions of Future Wars. Now music fades out slowly instead of stopping immediately. Sound effects are now properly panned, when requested by the game. +Drascula: + - Resolved multiple UI issues with the original save/load screen. + - Added advanced savegame functionality, including savegame timestamps and + thumbnails and the ability to load and delete savegames from the launcher. + It's now possible to use the ScummvM save/load dialogs. + - The F7 key (previously unmapped) now always shows the ScummVM load screen. + The F10 key displays either the original save/load screen, or the ScummVM + save screen, if the user has selected to use the ScummVM save/load dialogs. + Dreamweb: - Now that the game is freeware, there is a small extra help text showing the available commands in the in-game terminals when the player uses the @@ -29,6 +44,13 @@ For a more comprehensive changelog of the latest experimental code, see: protection, this extra line can be toggled by the ScummVM copy protection command line option. + Groovie: + - Simplified the movie speed options, and added a custom option for The 7th + Guest. Movie options are now "normal" and "fast", with the latter changing + the movie speed in T7G to match the faster movie speed of the iOS version. + The game entry might need to be readded in the launcher for the new setting + to appear. + SAGA: - Added music support for the Macintosh version of I Have No Mouth and, I Must Scream. @@ -2161,8 +2161,11 @@ keywords: The 7th Guest adds the following non-standard keyword: - t7g_speed string Video playback speed (normal, tweaked, - im_an_ios) + fast_movie_speed bool If true, movies are played at an increased + speed, matching the speed of the iOS version. + Movies without sound are still played at their + normal speed, to avoid music synchronization + issues 8.2) Custom game options that can be toggled via the GUI diff --git a/audio/softsynth/mt32.cpp b/audio/softsynth/mt32.cpp index 186118262f..e2f1f36f2c 100644 --- a/audio/softsynth/mt32.cpp +++ b/audio/softsynth/mt32.cpp @@ -25,6 +25,7 @@ #ifdef USE_MT32EMU #include "audio/softsynth/mt32/mt32emu.h" +#include "audio/softsynth/mt32/ROMInfo.h" #include "audio/softsynth/emumidi.h" #include "audio/musicplugin.h" @@ -47,6 +48,57 @@ #include "graphics/palette.h" #include "graphics/font.h" +#include "gui/message.h" + +static void drawMessage(int offset, const Common::String &text); + +namespace MT32Emu { + +class ReportHandlerScummVM : public ReportHandler { +friend class Synth; + +public: + virtual ~ReportHandlerScummVM() {} + +protected: + + // Callback for debug messages, in vprintf() format + void printDebug(const char *fmt, va_list list) { + char buf[512]; + + vsnprintf(buf, 512, fmt, list); + buf[70] = 0; // Truncate to a reasonable length + + drawMessage(1, buf); + } + + // Callbacks for reporting various errors and information + void onErrorControlROM() { + GUI::MessageDialog dialog("MT32emu: Init Error - Missing or invalid Control ROM image", "OK"); + dialog.runModal(); + error("MT32emu: Init Error - Missing or invalid Control ROM image"); + } + void onErrorPCMROM() { + GUI::MessageDialog dialog("MT32emu: Init Error - Missing PCM ROM image", "OK"); + dialog.runModal(); + error("MT32emu: Init Error - Missing PCM ROM image"); + } + void showLCDMessage(const char *message) { + g_system->displayMessageOnOSD(message); + } + void onDeviceReset() {} + void onDeviceReconfig() {} + void onNewReverbMode(Bit8u /* mode */) {} + void onNewReverbTime(Bit8u /* time */) {} + void onNewReverbLevel(Bit8u /* level */) {} + void onPartStateChanged(int /* partNum */, bool /* isActive */) {} + void onPolyStateChanged(int /* partNum */) {} + void onPartialStateChanged(int /* partialNum */, int /* oldPartialPhase */, int /* newPartialPhase */) {} + void onProgramChanged(int /* partNum */, char * /* patchName */) {} +}; + +} // end of namespace MT32Emu + class MidiChannel_MT32 : public MidiChannel_MPU401 { void effectLevel(byte value) { } void chorusLevel(byte value) { } @@ -57,6 +109,10 @@ private: MidiChannel_MT32 _midiChannels[16]; uint16 _channelMask; MT32Emu::Synth *_synth; + MT32Emu::ReportHandlerScummVM *_reportHandler; + const MT32Emu::ROMImage *_controlROM, *_pcmROM; + Common::File *_controlFile, *_pcmFile; + void deleteMuntStructures(); int _outputRate; @@ -84,59 +140,6 @@ public: int getRate() const { return _outputRate; } }; -static int eatSystemEvents() { - Common::Event event; - Common::EventManager *eventMan = g_system->getEventManager(); - while (eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_QUIT: - return 1; - default: - break; - } - } - return 0; -} - -static void drawProgress(float progress) { - const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kGUIFont)); - Graphics::Surface *screen = g_system->lockScreen(); - - assert(screen); - assert(screen->pixels); - - Graphics::PixelFormat screenFormat = g_system->getScreenFormat(); - - int16 w = g_system->getWidth() / 7 * 5; - int16 h = font.getFontHeight(); - int16 x = g_system->getWidth() / 7; - int16 y = g_system->getHeight() / 2 - h / 2; - - Common::Rect r(x, y, x + w, y + h); - - uint32 col; - - if (screenFormat.bytesPerPixel > 1) - col = screenFormat.RGBToColor(0, 171, 0); - else - col = 1; - - screen->frameRect(r, col); - - r.grow(-1); - r.setWidth(uint16(progress * w)); - - if (screenFormat.bytesPerPixel > 1) - col = screenFormat.RGBToColor(171, 0, 0); - else - col = 2; - - screen->fillRect(r, col); - - g_system->unlockScreen(); - g_system->updateScreen(); -} - static void drawMessage(int offset, const Common::String &text) { const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kGUIFont)); Graphics::Surface *screen = g_system->lockScreen(); @@ -170,63 +173,6 @@ static void drawMessage(int offset, const Common::String &text) { g_system->updateScreen(); } -static Common::File *MT32_OpenFile(void *userData, const char *filename) { - Common::File *file = new Common::File(); - if (!file->open(filename)) { - delete file; - return NULL; - } - return file; -} - -static void MT32_PrintDebug(void *userData, const char *fmt, va_list list) { - if (((MidiDriver_MT32 *)userData)->_initializing) { - char buf[512]; - - vsnprintf(buf, 512, fmt, list); - buf[70] = 0; // Truncate to a reasonable length - - drawMessage(1, buf); - } - - //vdebug(0, fmt, list); // FIXME: Use a higher debug level -} - -static int MT32_Report(void *userData, MT32Emu::ReportType type, const void *reportData) { - switch (type) { - case MT32Emu::ReportType_lcdMessage: - g_system->displayMessageOnOSD((const char *)reportData); - break; - case MT32Emu::ReportType_errorControlROM: - error("Failed to load MT32_CONTROL.ROM"); - break; - case MT32Emu::ReportType_errorPCMROM: - error("Failed to load MT32_PCM.ROM"); - break; - case MT32Emu::ReportType_progressInit: - if (((MidiDriver_MT32 *)userData)->_initializing) { - drawProgress(*((const float *)reportData)); - return eatSystemEvents(); - } - break; - case MT32Emu::ReportType_availableSSE: - debug(1, "MT32emu: SSE is available"); - break; - case MT32Emu::ReportType_usingSSE: - debug(1, "MT32emu: using SSE"); - break; - case MT32Emu::ReportType_available3DNow: - debug(1, "MT32emu: 3DNow! is available"); - break; - case MT32Emu::ReportType_using3DNow: - debug(1, "MT32emu: using 3DNow!"); - break; - default: - break; - } - return 0; -} - //////////////////////////////////////// // // MidiDriver_MT32 @@ -239,6 +185,7 @@ MidiDriver_MT32::MidiDriver_MT32(Audio::Mixer *mixer) : MidiDriver_Emulated(mixe for (i = 0; i < ARRAYSIZE(_midiChannels); ++i) { _midiChannels[i].init(this, i); } + _reportHandler = NULL; _synth = NULL; // A higher baseFreq reduces the length used in generateSamples(), // and means that the timer callback will be called more often. @@ -252,30 +199,35 @@ MidiDriver_MT32::MidiDriver_MT32(Audio::Mixer *mixer) : MidiDriver_Emulated(mixe } MidiDriver_MT32::~MidiDriver_MT32() { + deleteMuntStructures(); +} + +void MidiDriver_MT32::deleteMuntStructures() { delete _synth; + _synth = NULL; + delete _reportHandler; + _reportHandler = NULL; + + if (_controlROM) + MT32Emu::ROMImage::freeROMImage(_controlROM); + _controlROM = NULL; + if (_pcmROM) + MT32Emu::ROMImage::freeROMImage(_pcmROM); + _pcmROM = NULL; + + delete _controlFile; + _controlFile = NULL; + delete _pcmFile; + _pcmFile = NULL; } int MidiDriver_MT32::open() { - MT32Emu::SynthProperties prop; - if (_isOpen) return MERR_ALREADY_OPEN; MidiDriver_Emulated::open(); - - memset(&prop, 0, sizeof(prop)); - prop.sampleRate = getRate(); - prop.useReverb = true; - prop.useDefaultReverb = false; - prop.reverbType = 0; - prop.reverbTime = 5; - prop.reverbLevel = 3; - prop.userData = this; - prop.printDebug = MT32_PrintDebug; - prop.report = MT32_Report; - prop.openFile = MT32_OpenFile; - - _synth = new MT32Emu::Synth(); + _reportHandler = new MT32Emu::ReportHandlerScummVM(); + _synth = new MT32Emu::Synth(_reportHandler); Graphics::PixelFormat screenFormat = g_system->getScreenFormat(); @@ -291,7 +243,15 @@ int MidiDriver_MT32::open() { _initializing = true; drawMessage(-1, _s("Initializing MT-32 Emulator")); - if (!_synth->open(prop)) + _controlFile = new Common::File(); + if (!_controlFile->open("MT32_CONTROL.ROM")) + error("Error opening MT32_CONTROL.ROM"); + _pcmFile = new Common::File(); + if (!_pcmFile->open("MT32_PCM.ROM")) + error("Error opening MT32_PCM.ROM"); + _controlROM = MT32Emu::ROMImage::makeROMImage(_controlFile); + _pcmROM = MT32Emu::ROMImage::makeROMImage(_pcmFile); + if (!_synth->open(*_controlROM, *_pcmROM)) return MERR_DEVICE_NOT_AVAILABLE; double gain = (double)ConfMan.getInt("midi_gain") / 100.0; @@ -352,8 +312,7 @@ void MidiDriver_MT32::close() { _mixer->stopHandle(_mixerSoundHandle); _synth->close(); - delete _synth; - _synth = NULL; + deleteMuntStructures(); } void MidiDriver_MT32::generateSamples(int16 *data, int len) { diff --git a/audio/softsynth/mt32/AReverbModel.cpp b/audio/softsynth/mt32/AReverbModel.cpp index ec24394e71..595b286a31 100644 --- a/audio/softsynth/mt32/AReverbModel.cpp +++ b/audio/softsynth/mt32/AReverbModel.cpp @@ -48,7 +48,7 @@ static const Bit32u MODE_0_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; -static const Bit32u MODE_0_LEVELS[] = {0, 10*3, 10*5, 10*7, 11*9, 11*12, 11*15, 13*15}; +static const Bit32u MODE_0_LEVELS[] = {10*1, 10*3, 10*5, 10*7, 11*9, 11*12, 11*15, 13*15}; static const Bit32u MODE_0_LPF_AMP = 6; static const Bit32u MODE_1_ALLPASSES[] = {1324, 809, 176}; @@ -60,7 +60,7 @@ static const Bit32u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98, 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; -static const Bit32u MODE_1_LEVELS[] = {0, 10*3, 11*5, 11*7, 11*9, 11*12, 11*15, 14*15}; +static const Bit32u MODE_1_LEVELS[] = {10*1, 10*3, 11*5, 11*7, 11*9, 11*12, 11*15, 14*15}; static const Bit32u MODE_1_LPF_AMP = 6; static const Bit32u MODE_2_ALLPASSES[] = {969, 644, 157}; @@ -72,7 +72,7 @@ static const Bit32u MODE_2_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0, 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0, 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0}; -static const Bit32u MODE_2_LEVELS[] = {0, 10*3, 11*5, 11*7, 11*9, 11*12, 12*15, 14*15}; +static const Bit32u MODE_2_LEVELS[] = {10*1, 10*3, 11*5, 11*7, 11*9, 11*12, 12*15, 14*15}; static const Bit32u MODE_2_LPF_AMP = 8; static const AReverbSettings REVERB_MODE_0_SETTINGS = {MODE_0_ALLPASSES, MODE_0_COMBS, MODE_0_OUTL, MODE_0_OUTR, MODE_0_COMB_FACTOR, MODE_0_COMB_FEEDBACK, MODE_0_LEVELS, MODE_0_LPF_AMP}; @@ -165,9 +165,7 @@ AReverbModel::~AReverbModel() { close(); } -void AReverbModel::open(unsigned int /*sampleRate*/) { - // FIXME: filter sizes must be multiplied by sample rate to 32000Hz ratio - // IIR filter values depend on sample rate as well +void AReverbModel::open() { allpasses = new AllpassFilter*[NUM_ALLPASSES]; for (Bit32u i = 0; i < NUM_ALLPASSES; i++) { allpasses[i] = new AllpassFilter(currentSettings.allpassSizes[i]); @@ -218,10 +216,12 @@ void AReverbModel::setParameters(Bit8u time, Bit8u level) { // FIXME: wetLevel definitely needs ramping when changed // Although, most games don't set reverb level during MIDI playback if (combs == NULL) return; + level &= 7; + time &= 7; for (Bit32u i = 0; i < NUM_COMBS; i++) { - combs[i]->setFeedbackFactor(currentSettings.decayTimes[(i << 3) + (time & 7)] / 256.0f); + combs[i]->setFeedbackFactor(currentSettings.decayTimes[(i << 3) + time] / 256.0f); } - wetLevel = 0.5f * lpfAmp * currentSettings.wetLevels[(level & 7)] / 256.0f; + wetLevel = (level == 0 && time == 0) ? 0.0f : 0.5f * lpfAmp * currentSettings.wetLevels[level] / 256.0f; } bool AReverbModel::isActive() const { diff --git a/audio/softsynth/mt32/AReverbModel.h b/audio/softsynth/mt32/AReverbModel.h index d70e9ee14f..be1ca4916b 100644 --- a/audio/softsynth/mt32/AReverbModel.h +++ b/audio/softsynth/mt32/AReverbModel.h @@ -75,7 +75,7 @@ class AReverbModel : public ReverbModel { public: AReverbModel(const ReverbMode mode); ~AReverbModel(); - void open(unsigned int sampleRate); + void open(); void close(); void setParameters(Bit8u time, Bit8u level); void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples); diff --git a/audio/softsynth/mt32/BReverbModel.cpp b/audio/softsynth/mt32/BReverbModel.cpp index b5f4467c20..2570424187 100644 --- a/audio/softsynth/mt32/BReverbModel.cpp +++ b/audio/softsynth/mt32/BReverbModel.cpp @@ -241,9 +241,7 @@ BReverbModel::~BReverbModel() { close(); } -void BReverbModel::open(unsigned int /*sampleRate*/) { - // FIXME: filter sizes must be multiplied by sample rate to 32000Hz ratio - // IIR filter values depend on sample rate as well +void BReverbModel::open() { if (currentSettings.numberOfAllpasses > 0) { allpasses = new AllpassFilter*[currentSettings.numberOfAllpasses]; for (Bit32u i = 0; i < currentSettings.numberOfAllpasses; i++) { diff --git a/audio/softsynth/mt32/BReverbModel.h b/audio/softsynth/mt32/BReverbModel.h index 7096ae04ae..f728d1a99c 100644 --- a/audio/softsynth/mt32/BReverbModel.h +++ b/audio/softsynth/mt32/BReverbModel.h @@ -100,7 +100,7 @@ class BReverbModel : public ReverbModel { public: BReverbModel(const ReverbMode mode); ~BReverbModel(); - void open(unsigned int sampleRate); + void open(); void close(); void setParameters(Bit8u time, Bit8u level); void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples); diff --git a/audio/softsynth/mt32/DelayReverb.cpp b/audio/softsynth/mt32/DelayReverb.cpp index 77521b4a01..bf925f8419 100644 --- a/audio/softsynth/mt32/DelayReverb.cpp +++ b/audio/softsynth/mt32/DelayReverb.cpp @@ -45,9 +45,10 @@ static const Bit32u REVERB_FEEDBACK67 = 0x60; static const Bit32u REVERB_FEEDBACK = 0x68; static const float LPF_VALUE = 0x68 / 256.0f; +static const Bit32u BUFFER_SIZE = 16384; + DelayReverb::DelayReverb() { buf = NULL; - sampleRate = 0; setParameters(0, 0); } @@ -55,27 +56,22 @@ DelayReverb::~DelayReverb() { delete[] buf; } -void DelayReverb::open(unsigned int newSampleRate) { - if (newSampleRate != sampleRate || buf == NULL) { - sampleRate = newSampleRate; - +void DelayReverb::open() { + if (buf == NULL) { delete[] buf; - // If we ever need a speedup, set bufSize to EXP2F(ceil(log2(bufSize))) and use & instead of % to find buf indexes - bufSize = 16384 * sampleRate / 32000; - buf = new float[bufSize]; + buf = new float[BUFFER_SIZE]; recalcParameters(); // mute buffer bufIx = 0; if (buf != NULL) { - for (unsigned int i = 0; i < bufSize; i++) { + for (unsigned int i = 0; i < BUFFER_SIZE; i++) { buf[i] = 0.0f; } } } - // FIXME: IIR filter value depends on sample rate as well } void DelayReverb::close() { @@ -92,11 +88,11 @@ void DelayReverb::setParameters(Bit8u newTime, Bit8u newLevel) { void DelayReverb::recalcParameters() { // Number of samples between impulse and eventual appearance on the left channel - delayLeft = REVERB_TIMINGS[time][0] * sampleRate / 32000; + delayLeft = REVERB_TIMINGS[time][0]; // Number of samples between impulse and eventual appearance on the right channel - delayRight = REVERB_TIMINGS[time][1] * sampleRate / 32000; + delayRight = REVERB_TIMINGS[time][1]; // Number of samples between a response and that response feeding back/echoing - delayFeedback = REVERB_TIMINGS[time][2] * sampleRate / 32000; + delayFeedback = REVERB_TIMINGS[time][2]; if (level < 3 || time < 6) { feedback = REVERB_FEEDBACK / 256.0f; @@ -113,10 +109,10 @@ void DelayReverb::process(const float *inLeft, const float *inRight, float *outL for (unsigned int sampleIx = 0; sampleIx < numSamples; sampleIx++) { // The ring buffer write index moves backwards; reads are all done with positive offsets. - Bit32u bufIxPrev = (bufIx + 1) % bufSize; - Bit32u bufIxLeft = (bufIx + delayLeft) % bufSize; - Bit32u bufIxRight = (bufIx + delayRight) % bufSize; - Bit32u bufIxFeedback = (bufIx + delayFeedback) % bufSize; + Bit32u bufIxPrev = (bufIx + 1) % BUFFER_SIZE; + Bit32u bufIxLeft = (bufIx + delayLeft) % BUFFER_SIZE; + Bit32u bufIxRight = (bufIx + delayRight) % BUFFER_SIZE; + Bit32u bufIxFeedback = (bufIx + delayFeedback) % BUFFER_SIZE; // Attenuated input samples and feedback response are directly added to the current ring buffer location float lpfIn = amp * (inLeft[sampleIx] + inRight[sampleIx]) + feedback * buf[bufIxFeedback]; @@ -127,7 +123,7 @@ void DelayReverb::process(const float *inLeft, const float *inRight, float *outL outLeft[sampleIx] = buf[bufIxLeft]; outRight[sampleIx] = buf[bufIxRight]; - bufIx = (bufSize + bufIx - 1) % bufSize; + bufIx = (BUFFER_SIZE + bufIx - 1) % BUFFER_SIZE; } } @@ -136,7 +132,7 @@ bool DelayReverb::isActive() const { float *b = buf; float max = 0.001f; - for (Bit32u i = 0; i < bufSize; i++) { + for (Bit32u i = 0; i < BUFFER_SIZE; i++) { if ((*b < -max) || (*b > max)) return true; b++; } diff --git a/audio/softsynth/mt32/DelayReverb.h b/audio/softsynth/mt32/DelayReverb.h index e967ddc49c..1abb49f128 100644 --- a/audio/softsynth/mt32/DelayReverb.h +++ b/audio/softsynth/mt32/DelayReverb.h @@ -25,10 +25,7 @@ private: Bit8u time; Bit8u level; - unsigned int sampleRate; - Bit32u bufSize; Bit32u bufIx; - float *buf; Bit32u delayLeft; @@ -43,7 +40,7 @@ private: public: DelayReverb(); ~DelayReverb(); - void open(unsigned int sampleRate); + void open(); void close(); void setParameters(Bit8u time, Bit8u level); void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples); diff --git a/audio/softsynth/mt32/FreeverbModel.cpp b/audio/softsynth/mt32/FreeverbModel.cpp index d9bd17e62e..2ed302fddc 100644 --- a/audio/softsynth/mt32/FreeverbModel.cpp +++ b/audio/softsynth/mt32/FreeverbModel.cpp @@ -35,9 +35,7 @@ FreeverbModel::~FreeverbModel() { delete freeverb; } -void FreeverbModel::open(unsigned int /*sampleRate*/) { - // FIXME: scaleTuning must be multiplied by sample rate to 32000Hz ratio - // IIR filter values depend on sample rate as well +void FreeverbModel::open() { if (freeverb == NULL) { freeverb = new revmodel(scaleTuning); } diff --git a/audio/softsynth/mt32/FreeverbModel.h b/audio/softsynth/mt32/FreeverbModel.h index 925b2dbf96..bf1102b14a 100644 --- a/audio/softsynth/mt32/FreeverbModel.h +++ b/audio/softsynth/mt32/FreeverbModel.h @@ -32,7 +32,7 @@ class FreeverbModel : public ReverbModel { public: FreeverbModel(float useScaleTuning, float useFiltVal, float useWet, Bit8u useRoom, float useDamp); ~FreeverbModel(); - void open(unsigned int sampleRate); + void open(); void close(); void setParameters(Bit8u time, Bit8u level); void process(const float *inLeft, const float *inRight, float *outLeft, float *outRight, unsigned long numSamples); diff --git a/audio/softsynth/mt32/Part.cpp b/audio/softsynth/mt32/Part.cpp index 88d42dbbd4..852319be70 100644 --- a/audio/softsynth/mt32/Part.cpp +++ b/audio/softsynth/mt32/Part.cpp @@ -209,6 +209,7 @@ void RhythmPart::setTimbre(TimbreParam * /*timbre*/) { void Part::setTimbre(TimbreParam *timbre) { *timbreTemp = *timbre; + synth->newTimbreSet(partNum, timbre->common.name); } unsigned int RhythmPart::getAbsTimbreNum() const { @@ -537,6 +538,8 @@ void Part::playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhyt #if MT32EMU_MONITOR_PARTIALS > 1 synth->printPartialUsage(); #endif + synth->partStateChanged(partNum, true); + synth->polyStateChanged(partNum); } void Part::allNotesOff() { @@ -619,6 +622,10 @@ void Part::partialDeactivated(Poly *poly) { if (!poly->isActive()) { activePolys.remove(poly); freePolys.push_front(poly); + synth->polyStateChanged(partNum); + } + if (activePartialCount == 0) { + synth->partStateChanged(partNum, false); } } diff --git a/audio/softsynth/mt32/Partial.cpp b/audio/softsynth/mt32/Partial.cpp index a6d164f218..a4d1ab03fa 100644 --- a/audio/softsynth/mt32/Partial.cpp +++ b/audio/softsynth/mt32/Partial.cpp @@ -85,6 +85,7 @@ void Partial::deactivate() { pair->pair = NULL; } } + synth->partialStateChanged(this, tva->getPhase(), TVA_PHASE_DEAD); #if MT32EMU_MONITOR_PARTIALS > 2 synth->printDebug("[+%lu] [Partial %d] Deactivated", sampleNum, debugPartialNum); synth->printPartialUsage(sampleNum); @@ -232,12 +233,12 @@ unsigned long Partial::generateSamples(float *partialBuf, unsigned long length) #if MT32EMU_ACCURATE_WG == 1 float amp = EXP2F((32772 - ampRampVal / 2048) / -2048.0f); - float freq = EXP2F(pitch / 4096.0f - 16.0f) * 32000.0f; + float freq = EXP2F(pitch / 4096.0f - 16.0f) * SAMPLE_RATE; #else static const float ampFactor = EXP2F(32772 / -2048.0f); float amp = EXP2I(ampRampVal >> 10) * ampFactor; - static const float freqFactor = EXP2F(-16.0f) * 32000.0f; + static const float freqFactor = EXP2F(-16.0f) * SAMPLE_RATE; float freq = EXP2I(pitch) * freqFactor; #endif @@ -251,7 +252,7 @@ unsigned long Partial::generateSamples(float *partialBuf, unsigned long length) break; } Bit32u pcmAddr = pcmWave->addr; - float positionDelta = freq * 2048.0f / synth->myProp.sampleRate; + float positionDelta = freq * 2048.0f / SAMPLE_RATE; // Linear interpolation float firstSample = synth->pcmROMData[pcmAddr + intPCMPosition]; @@ -283,8 +284,12 @@ unsigned long Partial::generateSamples(float *partialBuf, unsigned long length) // res corresponds to a value set in an LA32 register Bit8u res = patchCache->srcPartial.tvf.resonance + 1; - // Using tiny exact table for computation of EXP2F(1.0f - (32 - res) / 4.0f) - float resAmp = tables.resAmpMax[res]; + float resAmp; + { + // resAmp = EXP2F(1.0f - (32 - res) / 4.0f); + static const float resAmpFactor = EXP2F(-7); + resAmp = EXP2I(res << 10) * resAmpFactor; + } // The cutoffModifier may not be supposed to be directly added to the cutoff - // it may for example need to be multiplied in some way. @@ -296,7 +301,7 @@ unsigned long Partial::generateSamples(float *partialBuf, unsigned long length) } // Wave length in samples - float waveLen = synth->myProp.sampleRate / freq; + float waveLen = SAMPLE_RATE / freq; // Init cosineLen float cosineLen = 0.5f * waveLen; @@ -316,23 +321,26 @@ unsigned long Partial::generateSamples(float *partialBuf, unsigned long length) relWavePos -= waveLen; } + // Ratio of positive segment to wave length float pulseLen = 0.5f; if (pulseWidthVal > 128) { - pulseLen += tables.pulseLenFactor[pulseWidthVal - 128]; + // pulseLen = EXP2F((64 - pulseWidthVal) / 64); + static const float pulseLenFactor = EXP2F(-192 / 64); + pulseLen = EXP2I((256 - pulseWidthVal) << 6) * pulseLenFactor; } pulseLen *= waveLen; - float lLen = pulseLen - cosineLen; + float hLen = pulseLen - cosineLen; // Ignore pulsewidths too high for given freq - if (lLen < 0.0f) { - lLen = 0.0f; + if (hLen < 0.0f) { + hLen = 0.0f; } // Ignore pulsewidths too high for given freq and cutoff - float hLen = waveLen - lLen - 2 * cosineLen; - if (hLen < 0.0f) { - hLen = 0.0f; + float lLen = waveLen - hLen - 2 * cosineLen; + if (lLen < 0.0f) { + lLen = 0.0f; } // Correct resAmp for cutoff in range 50..66 diff --git a/audio/softsynth/mt32/ROMInfo.cpp b/audio/softsynth/mt32/ROMInfo.cpp new file mode 100644 index 0000000000..514bc23496 --- /dev/null +++ b/audio/softsynth/mt32/ROMInfo.cpp @@ -0,0 +1,111 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +//#include <cstring> +#include "ROMInfo.h" + +namespace MT32Emu { + +// Known ROMs +static const ROMInfo CTRL_MT32_V1_04 = {65536, "5a5cb5a77d7d55ee69657c2f870416daed52dea7", ROMInfo::Control, "ctrl_mt32_1_04", "MT-32 Control v1.04", ROMInfo::Full, NULL, NULL}; +static const ROMInfo CTRL_MT32_V1_05 = {65536, "e17a3a6d265bf1fa150312061134293d2b58288c", ROMInfo::Control, "ctrl_mt32_1_05", "MT-32 Control v1.05", ROMInfo::Full, NULL, NULL}; +static const ROMInfo CTRL_MT32_V1_06 = {65536, "a553481f4e2794c10cfe597fef154eef0d8257de", ROMInfo::Control, "ctrl_mt32_1_06", "MT-32 Control v1.06", ROMInfo::Full, NULL, NULL}; +static const ROMInfo CTRL_MT32_V1_07 = {65536, "b083518fffb7f66b03c23b7eb4f868e62dc5a987", ROMInfo::Control, "ctrl_mt32_1_07", "MT-32 Control v1.07", ROMInfo::Full, NULL, NULL}; +static const ROMInfo CTRL_MT32_BLUER = {65536, "7b8c2a5ddb42fd0732e2f22b3340dcf5360edf92", ROMInfo::Control, "ctrl_mt32_bluer", "MT-32 Control BlueRidge", ROMInfo::Full, NULL, NULL}; + +static const ROMInfo CTRL_CM32L_V1_00 = {65536, "73683d585cd6948cc19547942ca0e14a0319456d", ROMInfo::Control, "ctrl_cm32l_1_00", "CM-32L/LAPC-I Control v1.00", ROMInfo::Full, NULL, NULL}; +static const ROMInfo CTRL_CM32L_V1_02 = {65536, "a439fbb390da38cada95a7cbb1d6ca199cd66ef8", ROMInfo::Control, "ctrl_cm32l_1_02", "CM-32L/LAPC-I Control v1.02", ROMInfo::Full, NULL, NULL}; + +static const ROMInfo PCM_MT32 = {524288, "f6b1eebc4b2d200ec6d3d21d51325d5b48c60252", ROMInfo::PCM, "pcm_mt32", "MT-32 PCM ROM", ROMInfo::Full, NULL, NULL}; +static const ROMInfo PCM_CM32L = {1048576, "289cc298ad532b702461bfc738009d9ebe8025ea", ROMInfo::PCM, "pcm_cm32l", "CM-32L/CM-64/LAPC-I PCM ROM", ROMInfo::Full, NULL, NULL}; + +static const ROMInfo * const ROM_INFOS[] = { + &CTRL_MT32_V1_04, + &CTRL_MT32_V1_05, + &CTRL_MT32_V1_06, + &CTRL_MT32_V1_07, + &CTRL_MT32_BLUER, + &CTRL_CM32L_V1_00, + &CTRL_CM32L_V1_02, + &PCM_MT32, + &PCM_CM32L, + NULL}; + +const ROMInfo* ROMInfo::getROMInfo(Common::File *file) { + size_t fileSize = file->size(); + // We haven't added the SHA1 checksum code in ScummVM, as the file size + // suffices for our needs for now. + //const char *fileDigest = file->getSHA1(); + for (int i = 0; ROM_INFOS[i] != NULL; i++) { + const ROMInfo *romInfo = ROM_INFOS[i]; + if (fileSize == romInfo->fileSize /*&& !strcmp(fileDigest, romInfo->sha1Digest)*/) { + return romInfo; + } + } + return NULL; +} + +void ROMInfo::freeROMInfo(const ROMInfo *romInfo) { + (void) romInfo; +} + +static int getROMCount() { + int count; + for(count = 0; ROM_INFOS[count] != NULL; count++) { + } + return count; +} + +const ROMInfo** ROMInfo::getROMInfoList(unsigned int types, unsigned int pairTypes) { + const ROMInfo **romInfoList = new const ROMInfo*[getROMCount() + 1]; + const ROMInfo **currentROMInList = romInfoList; + for(int i = 0; ROM_INFOS[i] != NULL; i++) { + const ROMInfo *romInfo = ROM_INFOS[i]; + if ((types & (1 << romInfo->type)) && (pairTypes & (1 << romInfo->pairType))) { + *currentROMInList++ = romInfo; + } + } + *currentROMInList = NULL; + return romInfoList; +} + +void ROMInfo::freeROMInfoList(const ROMInfo **romInfoList) { + delete[] romInfoList; +} + +const ROMImage* ROMImage::makeROMImage(Common::File *file) { + ROMImage *romImage = new ROMImage; + romImage->file = file; + romImage->romInfo = ROMInfo::getROMInfo(romImage->file); + return romImage; +} + +void ROMImage::freeROMImage(const ROMImage *romImage) { + ROMInfo::freeROMInfo(romImage->romInfo); + delete romImage; +} + + +Common::File* ROMImage::getFile() const { + return file; +} + +const ROMInfo* ROMImage::getROMInfo() const { + return romInfo; +} + +} diff --git a/audio/softsynth/mt32/ROMInfo.h b/audio/softsynth/mt32/ROMInfo.h new file mode 100644 index 0000000000..2ffd2b72c6 --- /dev/null +++ b/audio/softsynth/mt32/ROMInfo.h @@ -0,0 +1,77 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MT32EMU_ROMINFO_H +#define MT32EMU_ROMINFO_H + +//#include <cstddef> +#include "common/file.h" + +namespace MT32Emu { + +// Defines vital info about ROM file to be used by synth and applications + +struct ROMInfo { +public: + size_t fileSize; + const char *sha1Digest; + enum Type {PCM, Control, Reverb} type; + const char *shortName; + const char *description; + enum PairType {Full, FirstHalf, SecondHalf, Mux0, Mux1} pairType; + ROMInfo *pairROMInfo; + void *controlROMInfo; + + // Returns a ROMInfo struct by inspecting the size and the SHA1 hash + static const ROMInfo* getROMInfo(Common::File *file); + + // Currently no-op + static void freeROMInfo(const ROMInfo *romInfo); + + // Allows retrieving a NULL-terminated list of ROMInfos for a range of types and pairTypes + // (specified by bitmasks) + // Useful for GUI/console app to output information on what ROMs it supports + static const ROMInfo** getROMInfoList(unsigned int types, unsigned int pairTypes); + + // Frees the list of ROMInfos given + static void freeROMInfoList(const ROMInfo **romInfos); +}; + +// Synth::open() is to require a full control ROMImage and a full PCM ROMImage to work + +class ROMImage { +private: + Common::File *file; + const ROMInfo *romInfo; + +public: + + // Creates a ROMImage object given a ROMInfo and a File. Keeps a reference + // to the File and ROMInfo given, which must be freed separately by the user + // after the ROMImage is freed + static const ROMImage* makeROMImage(Common::File *file); + + // Must only be done after all Synths using the ROMImage are deleted + static void freeROMImage(const ROMImage *romImage); + + Common::File *getFile() const; + const ROMInfo *getROMInfo() const; +}; + +} + +#endif diff --git a/audio/softsynth/mt32/Synth.cpp b/audio/softsynth/mt32/Synth.cpp index 9b5518b207..7f4ba44999 100644 --- a/audio/softsynth/mt32/Synth.cpp +++ b/audio/softsynth/mt32/Synth.cpp @@ -142,11 +142,19 @@ Bit8u Synth::calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum) { return checksum; } -Synth::Synth() { +Synth::Synth(ReportHandler *useReportHandler) { isOpen = false; reverbEnabled = true; reverbOverridden = false; + if (useReportHandler == NULL) { + reportHandler = new ReportHandler; + isDefaultReportHandler = true; + } else { + reportHandler = useReportHandler; + isDefaultReportHandler = false; + } + #if MT32EMU_USE_REVERBMODEL == 1 reverbModels[REVERB_MODE_ROOM] = new AReverbModel(REVERB_MODE_ROOM); reverbModels[REVERB_MODE_HALL] = new AReverbModel(REVERB_MODE_HALL); @@ -178,31 +186,49 @@ Synth::~Synth() { for (int i = 0; i < 4; i++) { delete reverbModels[i]; } + if (isDefaultReportHandler) { + delete reportHandler; + } } -int Synth::report(ReportType type, const void *data) { - if (myProp.report != NULL) { - return myProp.report(myProp.userData, type, data); +void ReportHandler::showLCDMessage(const char *data) { + printf("WRITE-LCD: %s", data); + printf("\n"); +} + +void ReportHandler::printDebug(const char *fmt, va_list list) { + vprintf(fmt, list); + printf("\n"); +} + +void Synth::partStateChanged(int partNum, bool isPartActive) { + reportHandler->onPartStateChanged(partNum, isPartActive); +} + +void Synth::polyStateChanged(int partNum) { + reportHandler->onPolyStateChanged(partNum); +} + +void Synth::partialStateChanged(const Partial * const partial, int oldPartialPhase, int newPartialPhase) { + for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) { + if (getPartial(i) == partial) { + reportHandler->onPartialStateChanged(i, oldPartialPhase, newPartialPhase); + break; + } } - return 0; } -unsigned int Synth::getSampleRate() const { - return myProp.sampleRate; +void Synth::newTimbreSet(int partNum, char patchName[]) { + reportHandler->onProgramChanged(partNum, patchName); } void Synth::printDebug(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - if (myProp.printDebug != NULL) { - myProp.printDebug(myProp.userData, fmt, ap); - } else { #if MT32EMU_DEBUG_SAMPLESTAMPS > 0 - printf("[%u] ", renderedSampleCount); + reportHandler->printDebug("[%u] ", renderedSampleCount); #endif - vprintf(fmt, ap); - printf("\n"); - } + reportHandler->printDebug(fmt, ap); va_end(ap); } @@ -252,80 +278,60 @@ void Synth::setReverbOutputGain(float newReverbOutputGain) { reverbOutputGain = newReverbOutputGain; } -Common::File *Synth::openFile(const char *filename) { - if (myProp.openFile != NULL) { - return myProp.openFile(myProp.userData, filename); - } - char pathBuf[2048]; - if (myProp.baseDir != NULL) { - strcpy(&pathBuf[0], myProp.baseDir); - strcat(&pathBuf[0], filename); - filename = pathBuf; - } - Common::File *file = new Common::File(); - if (!file->open(filename)) { - delete file; - return NULL; - } - return file; -} - -void Synth::closeFile(Common::File *file) { - if (myProp.closeFile != NULL) { - myProp.closeFile(myProp.userData, file); - } else { - file->close(); - delete file; - } -} - -LoadResult Synth::loadControlROM(const char *filename) { - Common::File *file = openFile(filename); // ROM File - if (file == NULL) { - return LoadResult_NotFound; - } - size_t fileSize = file->size(); - if (fileSize != CONTROL_ROM_SIZE) { - printDebug("Control ROM file %s size mismatch: %i", filename, fileSize); +bool Synth::loadControlROM(const ROMImage &controlROMImage) { + if (&controlROMImage == NULL) return false; + Common::File *file = controlROMImage.getFile(); + const ROMInfo *controlROMInfo = controlROMImage.getROMInfo(); + if ((controlROMInfo == NULL) + || (controlROMInfo->type != ROMInfo::Control) + || (controlROMInfo->pairType != ROMInfo::Full)) { + return false; } +#if MT32EMU_MONITOR_INIT + printDebug("Found Control ROM: %s, %s", controlROMInfo->shortName, controlROMInfo->description); +#endif file->read(controlROMData, CONTROL_ROM_SIZE); - if (file->err()) { - closeFile(file); - return LoadResult_Unreadable; - } - closeFile(file); // Control ROM successfully loaded, now check whether it's a known type controlROMMap = NULL; for (unsigned int i = 0; i < sizeof(ControlROMMaps) / sizeof(ControlROMMaps[0]); i++) { if (memcmp(&controlROMData[ControlROMMaps[i].idPos], ControlROMMaps[i].idBytes, ControlROMMaps[i].idLen) == 0) { controlROMMap = &ControlROMMaps[i]; - return LoadResult_OK; + return true; } } - printDebug("%s does not match a known control ROM type", filename); - return LoadResult_Invalid; +#if MT32EMU_MONITOR_INIT + printDebug("Control ROM failed to load"); +#endif + return false; } -LoadResult Synth::loadPCMROM(const char *filename) { - Common::File *file = openFile(filename); // ROM File - if (file == NULL) { - return LoadResult_NotFound; +bool Synth::loadPCMROM(const ROMImage &pcmROMImage) { + if (&pcmROMImage == NULL) return false; + Common::File *file = pcmROMImage.getFile(); + const ROMInfo *pcmROMInfo = pcmROMImage.getROMInfo(); + if ((pcmROMInfo == NULL) + || (pcmROMInfo->type != ROMInfo::PCM) + || (pcmROMInfo->pairType != ROMInfo::Full)) { + return false; } +#if MT32EMU_MONITOR_INIT + printDebug("Found PCM ROM: %s, %s", pcmROMInfo->shortName, pcmROMInfo->description); +#endif size_t fileSize = file->size(); - if (fileSize < (size_t)(2 * pcmROMSize)) { - printDebug("PCM ROM file is too short (expected %d, got %d)", 2 * pcmROMSize, fileSize); - closeFile(file); - return LoadResult_Invalid; - } - if (file->err()) { - closeFile(file); - return LoadResult_Unreadable; + if (fileSize != (2 * pcmROMSize)) { +#if MT32EMU_MONITOR_INIT + printDebug("PCM ROM file has wrong size (expected %d, got %d)", 2 * pcmROMSize, fileSize); +#endif + return false; } - LoadResult rc = LoadResult_OK; - for (unsigned int i = 0; i < pcmROMSize; i++) { - Bit8u s = file->readByte(); - Bit8u c = file->readByte(); + + byte *buffer = new byte[file->size()]; + file->read(buffer, file->size()); + const byte *fileData = buffer; + for (size_t i = 0; i < pcmROMSize; i++) { + Bit8u s = *(fileData++); + Bit8u c = *(fileData++); int order[16] = {0, 9, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 8}; @@ -351,16 +357,18 @@ LoadResult Synth::loadPCMROM(const char *filename) { pcmROMData[i] = lin; } - closeFile(file); - return rc; + + delete[] buffer; + + return true; } bool Synth::initPCMList(Bit16u mapAddress, Bit16u count) { ControlROMPCMStruct *tps = (ControlROMPCMStruct *)&controlROMData[mapAddress]; for (int i = 0; i < count; i++) { - unsigned int rAddr = tps[i].pos * 0x800; - int rLenExp = (tps[i].len & 0x70) >> 4; - int rLen = 0x800 << rLenExp; + size_t rAddr = tps[i].pos * 0x800; + size_t rLenExp = (tps[i].len & 0x70) >> 4; + size_t rLen = 0x800 << rLenExp; if (rAddr + rLen > pcmROMSize) { printDebug("Control ROM error: Wave map entry %d points to invalid PCM address 0x%04X, length 0x%04X", i, rAddr, rLen); return false; @@ -422,12 +430,11 @@ bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, int count, int startTi return true; } -bool Synth::open(SynthProperties &useProp) { +bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage) { if (isOpen) { return false; } prerenderReadIx = prerenderWriteIx = 0; - myProp = useProp; #if MT32EMU_MONITOR_INIT printDebug("Initialising Constant Tables"); #endif @@ -436,11 +443,6 @@ bool Synth::open(SynthProperties &useProp) { reverbModels[i]->open(useProp.sampleRate); } #endif - if (useProp.baseDir != NULL) { - char *baseDirCopy = new char[strlen(useProp.baseDir) + 1]; - strcpy(baseDirCopy, useProp.baseDir); - myProp.baseDir = baseDirCopy; - } // This is to help detect bugs memset(&mt32ram, '?', sizeof(mt32ram)); @@ -448,12 +450,10 @@ bool Synth::open(SynthProperties &useProp) { #if MT32EMU_MONITOR_INIT printDebug("Loading Control ROM"); #endif - if (loadControlROM("CM32L_CONTROL.ROM") != LoadResult_OK) { - if (loadControlROM("MT32_CONTROL.ROM") != LoadResult_OK) { - printDebug("Init Error - Missing or invalid MT32_CONTROL.ROM"); - //report(ReportType_errorControlROM, &errno); - return false; - } + if (!loadControlROM(controlROMImage)) { + printDebug("Init Error - Missing or invalid Control ROM image"); + reportHandler->onErrorControlROM(); + return false; } initMemoryRegions(); @@ -467,12 +467,10 @@ bool Synth::open(SynthProperties &useProp) { #if MT32EMU_MONITOR_INIT printDebug("Loading PCM ROM"); #endif - if (loadPCMROM("CM32L_PCM.ROM") != LoadResult_OK) { - if (loadPCMROM("MT32_PCM.ROM") != LoadResult_OK) { - printDebug("Init Error - Missing MT32_PCM.ROM"); - //report(ReportType_errorPCMROM, &errno); - return false; - } + if (!loadPCMROM(pcmROMImage)) { + printDebug("Init Error - Missing PCM ROM image"); + reportHandler->onErrorPCMROM(); + return false; } #if MT32EMU_MONITOR_INIT @@ -601,9 +599,6 @@ void Synth::close() { parts[i] = NULL; } - delete[] myProp.baseDir; - myProp.baseDir = NULL; - delete[] pcmWaves; delete[] pcmROMData; @@ -1190,7 +1185,7 @@ void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u le case MR_System: region->write(0, off, data, len); - report(ReportType_devReconfig, NULL); + reportHandler->onDeviceReconfig(); // FIXME: We haven't properly confirmed any of this behaviour // In particular, we tend to reset things such as reverb even if the write contained // the same parameters as were already set, which may be wrong. @@ -1228,7 +1223,7 @@ void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u le #if MT32EMU_MONITOR_SYSEX > 0 printDebug("WRITE-LCD: %s", buf); #endif - report(ReportType_lcdMessage, buf); + reportHandler->showLCDMessage(buf); break; case MR_Reset: reset(); @@ -1256,9 +1251,9 @@ void Synth::refreshSystemReverbParameters() { #endif return; } - report(ReportType_newReverbMode, &mt32ram.system.reverbMode); - report(ReportType_newReverbTime, &mt32ram.system.reverbTime); - report(ReportType_newReverbLevel, &mt32ram.system.reverbLevel); + reportHandler->onNewReverbMode(mt32ram.system.reverbMode); + reportHandler->onNewReverbTime(mt32ram.system.reverbTime); + reportHandler->onNewReverbLevel(mt32ram.system.reverbLevel); ReverbModel *newReverbModel = reverbModels[mt32ram.system.reverbMode]; #if MT32EMU_REDUCE_REVERB_MEMORY @@ -1266,7 +1261,7 @@ void Synth::refreshSystemReverbParameters() { if (reverbModel != NULL) { reverbModel->close(); } - newReverbModel->open(myProp.sampleRate); + newReverbModel->open(); } #endif reverbModel = newReverbModel; @@ -1321,7 +1316,7 @@ void Synth::reset() { #if MT32EMU_MONITOR_SYSEX > 0 printDebug("RESET"); #endif - report(ReportType_devReset, NULL); + reportHandler->onDeviceReset(); partialManager->deactivateAll(); mt32ram = mt32default; for (int i = 0; i < 9; i++) { diff --git a/audio/softsynth/mt32/Synth.h b/audio/softsynth/mt32/Synth.h index 2534b7af35..91375c0fc0 100644 --- a/audio/softsynth/mt32/Synth.h +++ b/audio/softsynth/mt32/Synth.h @@ -26,6 +26,7 @@ class TableInitialiser; class Partial; class PartialManager; class Part; +class ROMImage; /** * Methods for emulating the connection between the LA32 and the DAC, which involves @@ -57,71 +58,6 @@ enum DACInputMode { DACInputMode_GENERATION2 }; -enum ReportType { - // Errors - ReportType_errorControlROM = 1, - ReportType_errorPCMROM, - ReportType_errorSampleRate, - - // Progress - ReportType_progressInit, - - // HW spec - ReportType_availableSSE, - ReportType_available3DNow, - ReportType_usingSSE, - ReportType_using3DNow, - - // General info - ReportType_lcdMessage, - ReportType_devReset, - ReportType_devReconfig, - ReportType_newReverbMode, - ReportType_newReverbTime, - ReportType_newReverbLevel -}; - -enum LoadResult { - LoadResult_OK, - LoadResult_NotFound, - LoadResult_Unreadable, - LoadResult_Invalid -}; - -struct SynthProperties { - // Sample rate to use in mixing - unsigned int sampleRate; - - // Deprecated - ignored. Use Synth::setReverbEnabled() instead. - bool useReverb; - // Deprecated - ignored. Use Synth::setReverbOverridden() instead. - bool useDefaultReverb; - // Deprecated - ignored. Use Synth::playSysex*() to configure reverb instead. - unsigned char reverbType; - // Deprecated - ignored. Use Synth::playSysex*() to configure reverb instead. - unsigned char reverbTime; - // Deprecated - ignored. Use Synth::playSysex*() to configure reverb instead. - unsigned char reverbLevel; - // The name of the directory in which the ROM and data files are stored (with trailing slash/backslash) - // Not used if "openFile" is set. May be NULL in any case. - const char *baseDir; - // This is used as the first argument to all callbacks - void *userData; - // Callback for reporting various errors and information. May be NULL - int (*report)(void *userData, ReportType type, const void *reportData); - // Callback for debug messages, in vprintf() format - void (*printDebug)(void *userData, const char *fmt, va_list list); - // Callback for providing an implementation of File, opened and ready for use - // May be NULL, in which case a default implementation will be used. - Common::File *(*openFile)(void *userData, const char *filename); - // Callback for closing a File. May be NULL, in which case the File will automatically be close()d/deleted. - void (*closeFile)(void *userData, Common::File *file); -}; - -// This is the specification of the Callback routine used when calling the RecalcWaveforms -// function -typedef void (*recalcStatusCallback)(int percDone); - typedef void (*FloatToBit16sFunc)(Bit16s *target, const float *source, Bit32u len, float outputGain); const Bit8u SYSEX_MANUFACTURER_ROLAND = 0x41; @@ -285,7 +221,7 @@ class ReverbModel { public: virtual ~ReverbModel() {} // After construction or a close(), open() will be called at least once before any other call (with the exception of close()). - virtual void open(unsigned int sampleRate) = 0; + virtual void open() = 0; // May be called multiple times without an open() in between. virtual void close() = 0; virtual void setParameters(Bit8u time, Bit8u level) = 0; @@ -293,6 +229,32 @@ public: virtual bool isActive() const = 0; }; +class ReportHandler { +friend class Synth; + +public: + virtual ~ReportHandler() {} + +protected: + + // Callback for debug messages, in vprintf() format + virtual void printDebug(const char *fmt, va_list list); + + // Callbacks for reporting various errors and information + virtual void onErrorControlROM() {} + virtual void onErrorPCMROM() {} + virtual void showLCDMessage(const char *message); + virtual void onDeviceReset() {} + virtual void onDeviceReconfig() {} + virtual void onNewReverbMode(Bit8u /* mode */) {} + virtual void onNewReverbTime(Bit8u /* time */) {} + virtual void onNewReverbLevel(Bit8u /* level */) {} + virtual void onPartStateChanged(int /* partNum */, bool /* isActive */) {} + virtual void onPolyStateChanged(int /* partNum */) {} + virtual void onPartialStateChanged(int /* partialNum */, int /* oldPartialPhase */, int /* newPartialPhase */) {} + virtual void onProgramChanged(int /* partNum */, char * /* patchName */) {} +}; + class Synth { friend class Part; friend class RhythmPart; @@ -322,7 +284,7 @@ private: const ControlROMMap *controlROMMap; Bit8u controlROMData[CONTROL_ROM_SIZE]; float *pcmROMData; - unsigned int pcmROMSize; // This is in 16-bit samples, therefore half the number of bytes in the ROM + size_t pcmROMSize; // This is in 16-bit samples, therefore half the number of bytes in the ROM Bit8s chantable[32]; @@ -343,6 +305,9 @@ private: bool isOpen; + bool isDefaultReportHandler; + ReportHandler *reportHandler; + PartialManager *partialManager; Part *parts[9]; @@ -375,8 +340,6 @@ private: int prerenderReadIx; int prerenderWriteIx; - SynthProperties myProp; - bool prerender(); void copyPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u pos, Bit32u len); void checkPrerender(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u &pos, Bit32u &len); @@ -390,8 +353,8 @@ private: void writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, const Bit8u *data); void readMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, Bit8u *data); - LoadResult loadControlROM(const char *filename); - LoadResult loadPCMROM(const char *filename); + bool loadControlROM(const ROMImage &controlROMImage); + bool loadPCMROM(const ROMImage &pcmROMImage); bool initPCMList(Bit16u mapAddress, Bit16u count); bool initTimbres(Bit16u mapAddress, Bit16u offset, int timbreCount, int startTimbre, bool compressed); @@ -405,24 +368,25 @@ private: void refreshSystem(); void reset(); - unsigned int getSampleRate() const; - void printPartialUsage(unsigned long sampleOffset = 0); -protected: - int report(ReportType type, const void *reportData); - Common::File *openFile(const char *filename); - void closeFile(Common::File *file); + + void partStateChanged(int partNum, bool isPartActive); + void polyStateChanged(int partNum); + void partialStateChanged(const Partial * const partial, int oldPartialPhase, int newPartialPhase); + void newTimbreSet(int partNum, char patchName[]); void printDebug(const char *fmt, ...); public: static Bit8u calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum); - Synth(); + // Optionally sets callbacks for reporting various errors, information and debug messages + Synth(ReportHandler *useReportHandler = NULL); ~Synth(); // Used to initialise the MT-32. Must be called before any other function. // Returns true if initialization was sucessful, otherwise returns false. - bool open(SynthProperties &useProp); + // controlROMImage and pcmROMImage represent Control and PCM ROM images for use by synth. + bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage); // Closes the MT-32 and deallocates any memory used by the synthesizer void close(void); diff --git a/audio/softsynth/mt32/TVA.cpp b/audio/softsynth/mt32/TVA.cpp index c581259a38..7aadd64522 100644 --- a/audio/softsynth/mt32/TVA.cpp +++ b/audio/softsynth/mt32/TVA.cpp @@ -30,10 +30,13 @@ namespace MT32Emu { static Bit8u biasLevelToAmpSubtractionCoeff[13] = {255, 187, 137, 100, 74, 54, 40, 29, 21, 15, 10, 5, 0}; TVA::TVA(const Partial *usePartial, LA32Ramp *useAmpRamp) : - partial(usePartial), ampRamp(useAmpRamp), system_(&usePartial->getSynth()->mt32ram.system) { + partial(usePartial), ampRamp(useAmpRamp), system_(&usePartial->getSynth()->mt32ram.system), phase(TVA_PHASE_DEAD) { } void TVA::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) { + if (newPhase != phase) { + partial->getSynth()->partialStateChanged(partial, phase, newPhase); + } target = newTarget; phase = newPhase; ampRamp->startRamp(newTarget, newIncrement); @@ -43,6 +46,9 @@ void TVA::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) { } void TVA::end(int newPhase) { + if (newPhase != phase) { + partial->getSynth()->partialStateChanged(partial, phase, newPhase); + } phase = newPhase; playing = false; #if MT32EMU_MONITOR_TVA >= 1 diff --git a/audio/softsynth/mt32/TVP.cpp b/audio/softsynth/mt32/TVP.cpp index 32a6067841..5dc4ca6b66 100644 --- a/audio/softsynth/mt32/TVP.cpp +++ b/audio/softsynth/mt32/TVP.cpp @@ -47,12 +47,11 @@ static Bit16u keyToPitchTable[] = { TVP::TVP(const Partial *usePartial) : partial(usePartial), system_(&usePartial->getSynth()->mt32ram.system) { - unsigned int sampleRate = usePartial->getSynth()->myProp.sampleRate; // We want to do processing 4000 times per second. FIXME: This is pretty arbitrary. - maxCounter = sampleRate / 4000; + maxCounter = SAMPLE_RATE / 4000; // The timer runs at 500kHz. We only need to bother updating it every maxCounter samples, before we do processing. // This is how much to increment it by every maxCounter samples. - processTimerIncrement = 500000 * maxCounter / sampleRate; + processTimerIncrement = 500000 * maxCounter / SAMPLE_RATE; } static Bit16s keyToPitch(unsigned int key) { diff --git a/audio/softsynth/mt32/Tables.cpp b/audio/softsynth/mt32/Tables.cpp index b6e63840bc..5353a74079 100644 --- a/audio/softsynth/mt32/Tables.cpp +++ b/audio/softsynth/mt32/Tables.cpp @@ -72,24 +72,12 @@ Tables::Tables() { //synth->printDebug("%d: %d", i, pulseWidth100To255[i]); } - // Ratio of negative segment to wave length - for (int i = 0; i < 128; i++) { - // Formula determined from sample analysis. - float pt = 0.5f / 127.0f * i; - pulseLenFactor[i] = (1.241857812f - pt) * pt; // seems to be 2 ^ (5 / 16) = 1.241857812f - } - // The LA32 chip presumably has such a table inside as the internal computaions seem to be performed using fixed point math with 12-bit fractions for (int i = 0; i < 4096; i++) { exp2[i] = EXP2F(i / 4096.0f); } // found from sample analysis - for (int i = 0; i < 32; i++) { - resAmpMax[i] = EXP2F(1.0f - (32 - i) / 4.0f); - } - - // found from sample analysis resAmpFadeFactor[7] = 1.0f / 8.0f; resAmpFadeFactor[6] = 2.0f / 8.0f; resAmpFadeFactor[5] = 3.0f / 8.0f; diff --git a/audio/softsynth/mt32/Tables.h b/audio/softsynth/mt32/Tables.h index a63eaf6d26..c3e80e7e9b 100644 --- a/audio/softsynth/mt32/Tables.h +++ b/audio/softsynth/mt32/Tables.h @@ -20,7 +20,9 @@ namespace MT32Emu { -// Sample rate to use in mixing +// Sample rate to use in mixing. With the progress of development, we've found way too many thing dependent. +// In order to achieve further advance in emulation accuracy, sample rate made fixed throughout the emulator. +// The output from the synth is supposed to be resampled to convert the sample rate. const unsigned int SAMPLE_RATE = 32000; const int MIDDLEC = 60; @@ -55,8 +57,6 @@ public: Bit8u pulseWidth100To255[101]; float exp2[4096]; - float pulseLenFactor[128]; - float resAmpMax[32]; float resAmpFadeFactor[8]; float sinf10[5120]; }; diff --git a/audio/softsynth/mt32/module.mk b/audio/softsynth/mt32/module.mk index c0ee363c04..ed6b0d33ed 100644 --- a/audio/softsynth/mt32/module.mk +++ b/audio/softsynth/mt32/module.mk @@ -10,6 +10,7 @@ MODULE_OBJS := \ Partial.o \ PartialManager.o \ Poly.o \ + ROMInfo.o \ Synth.o \ TVA.o \ TVF.o \ diff --git a/audio/softsynth/mt32/mt32emu.h b/audio/softsynth/mt32/mt32emu.h index a5a72b01ca..ae5f4955b1 100644 --- a/audio/softsynth/mt32/mt32emu.h +++ b/audio/softsynth/mt32/mt32emu.h @@ -71,8 +71,6 @@ // 1: Use precise float math. Use this setting to achieve more accurate wave generator. If your system performs better with this setting, it is really notable. :) #define MT32EMU_ACCURATE_WG 0 -#define MT32EMU_USE_EXTINT 0 - // Configuration // The maximum number of partials playing simultaneously #define MT32EMU_MAX_PARTIALS 32 @@ -117,6 +115,7 @@ const unsigned int MAX_PRERENDER_SAMPLES = 1024; #include "TVF.h" #include "Partial.h" #include "Part.h" +#include "ROMInfo.h" #include "Synth.h" #endif diff --git a/backends/platform/android/android.mk b/backends/platform/android/android.mk index 0651fc796e..f498c671de 100644 --- a/backends/platform/android/android.mk +++ b/backends/platform/android/android.mk @@ -50,7 +50,7 @@ JAVACFLAGS = -source 1.5 -target 1.5 ANDROID_JAR = $(ANDROID_SDK)/platforms/android-14/android.jar -PATH_BUILD = build.tmp +PATH_BUILD = ./build.tmp PATH_BUILD_ASSETS = $(PATH_BUILD)/assets PATH_BUILD_CLASSES_MAIN_TOP = $(PATH_BUILD)/classes.main PATH_BUILD_CLASSES_PLUGIN_TOP = $(PATH_BUILD)/classes.plugin @@ -128,7 +128,7 @@ $(FILE_RESOURCES_MAIN): $(FILE_MANIFEST) $(RESOURCES) $(ANDROID_JAR) $(DIST_FILE work_dir=`pwd`; \ for i in $(PATH_BUILD_ASSETS)/*.zip; do \ echo "recompress $$i"; \ - cd $$work_dir; \ + cd "$$work_dir"; \ $(RM) -rf $(PATH_BUILD_ASSETS)/tmp; \ $(MKDIR) $(PATH_BUILD_ASSETS)/tmp; \ unzip -q $$i -d $(PATH_BUILD_ASSETS)/tmp; \ diff --git a/backends/platform/symbian/README b/backends/platform/symbian/README index 31bc3d8fce..58cbc7814a 100644 --- a/backends/platform/symbian/README +++ b/backends/platform/symbian/README @@ -1,7 +1,7 @@ ScummVM - ScummVM ported to EPOC/SymbianOS - Copyright (C) 2008-2012 ScummVM Team + Copyright (C) 2008-2013 ScummVM Team Copyright (C) 2003-2008 Lars 'AnotherGuest' Persson Copyright (C) 2002-2008 Jurgen 'SumthinWicked' Braam diff --git a/backends/platform/symbian/S60/ScummVM_S60.mmp.in b/backends/platform/symbian/S60/ScummVM_S60.mmp.in index 81068ba073..28bd11dec6 100644 --- a/backends/platform/symbian/S60/ScummVM_S60.mmp.in +++ b/backends/platform/symbian/S60/ScummVM_S60.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/S60/ScummVM_S60_App.mmp b/backends/platform/symbian/S60/ScummVM_S60_App.mmp index e00987e2ad..38d6f19590 100644 --- a/backends/platform/symbian/S60/ScummVM_S60_App.mmp +++ b/backends/platform/symbian/S60/ScummVM_S60_App.mmp @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in b/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in index ccf38818dc..93636aca25 100644 --- a/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in +++ b/backends/platform/symbian/S60v3/ScummVM_A0000658_S60v3.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in b/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in index 0162061284..c09934a46d 100644 --- a/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in +++ b/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/S80/ScummVM_S80.mmp.in b/backends/platform/symbian/S80/ScummVM_S80.mmp.in index 7987ccd639..d9b9a5c948 100644 --- a/backends/platform/symbian/S80/ScummVM_S80.mmp.in +++ b/backends/platform/symbian/S80/ScummVM_S80.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/S80/ScummVM_S80_App.mmp b/backends/platform/symbian/S80/ScummVM_S80_App.mmp index b66bef7518..30b1c3f58b 100644 --- a/backends/platform/symbian/S80/ScummVM_S80_App.mmp +++ b/backends/platform/symbian/S80/ScummVM_S80_App.mmp @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/S90/Scummvm_S90.mmp.in b/backends/platform/symbian/S90/Scummvm_S90.mmp.in index d803ce5647..790dca14f0 100644 --- a/backends/platform/symbian/S90/Scummvm_S90.mmp.in +++ b/backends/platform/symbian/S90/Scummvm_S90.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/S90/Scummvm_S90_App.mmp b/backends/platform/symbian/S90/Scummvm_S90_App.mmp index 0d8d2b8710..cf17f103ef 100644 --- a/backends/platform/symbian/S90/Scummvm_S90_App.mmp +++ b/backends/platform/symbian/S90/Scummvm_S90_App.mmp @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/UIQ2/ScummVM.rss b/backends/platform/symbian/UIQ2/ScummVM.rss index a6ba4021e4..bfdd07e898 100644 --- a/backends/platform/symbian/UIQ2/ScummVM.rss +++ b/backends/platform/symbian/UIQ2/ScummVM.rss @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/backends/platform/symbian/UIQ3/ScummVM.rss b/backends/platform/symbian/UIQ3/ScummVM.rss index 00ed4e3b5c..b7f0a17113 100644 --- a/backends/platform/symbian/UIQ3/ScummVM.rss +++ b/backends/platform/symbian/UIQ3/ScummVM.rss @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss b/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss index 00ed4e3b5c..b7f0a17113 100644 --- a/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss +++ b/backends/platform/symbian/UIQ3/ScummVM_A0000658.rss @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in b/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in index 9e419ad6d9..255bc0f862 100644 --- a/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in +++ b/backends/platform/symbian/UIQ3/ScummVM_A0000658_UIQ3.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2009 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2009 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in b/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in index 41452127ca..83d782d1a6 100644 --- a/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in +++ b/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss b/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss index 9af9a33a75..47e7c44642 100644 --- a/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss +++ b/backends/platform/symbian/UIQ3/scummvm_A0000658_loc.rss @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_agi.mmp.in b/backends/platform/symbian/mmp/scummvm_agi.mmp.in index 7d197f786f..892ed57732 100644 --- a/backends/platform/symbian/mmp/scummvm_agi.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_agi.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_agos.mmp.in b/backends/platform/symbian/mmp/scummvm_agos.mmp.in index 587d1f0b69..d3bc84ed51 100644 --- a/backends/platform/symbian/mmp/scummvm_agos.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_agos.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_base.mmp.in b/backends/platform/symbian/mmp/scummvm_base.mmp.in index 05cf526233..d6dfafd014 100644 --- a/backends/platform/symbian/mmp/scummvm_base.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_base.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_cine.mmp.in b/backends/platform/symbian/mmp/scummvm_cine.mmp.in index 79806eb8c2..cb7143b837 100644 --- a/backends/platform/symbian/mmp/scummvm_cine.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_cine.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_cruise.mmp.in b/backends/platform/symbian/mmp/scummvm_cruise.mmp.in index 53d52c80e7..c26e93dedc 100644 --- a/backends/platform/symbian/mmp/scummvm_cruise.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_cruise.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_draci.mmp.in b/backends/platform/symbian/mmp/scummvm_draci.mmp.in index 9a7c87c963..52f862bc6f 100644 --- a/backends/platform/symbian/mmp/scummvm_draci.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_draci.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_drascula.mmp.in b/backends/platform/symbian/mmp/scummvm_drascula.mmp.in index fcd7ce7585..9ea02fefe8 100644 --- a/backends/platform/symbian/mmp/scummvm_drascula.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_drascula.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_gob.mmp.in b/backends/platform/symbian/mmp/scummvm_gob.mmp.in index 23f110bc7d..906d54b487 100644 --- a/backends/platform/symbian/mmp/scummvm_gob.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_gob.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_groovie.mmp.in b/backends/platform/symbian/mmp/scummvm_groovie.mmp.in index 6bdeb06b10..e7f70bc110 100644 --- a/backends/platform/symbian/mmp/scummvm_groovie.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_groovie.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_hugo.mmp.in b/backends/platform/symbian/mmp/scummvm_hugo.mmp.in index 69888bb0ee..13dd7efa1e 100644 --- a/backends/platform/symbian/mmp/scummvm_hugo.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_hugo.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_kyra.mmp.in b/backends/platform/symbian/mmp/scummvm_kyra.mmp.in index 4a2a87216e..5772bfaad0 100644 --- a/backends/platform/symbian/mmp/scummvm_kyra.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_kyra.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in b/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in index 27ec0b2148..b8db95ea0c 100644 --- a/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_lastexpress.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_lure.mmp.in b/backends/platform/symbian/mmp/scummvm_lure.mmp.in index 20b938a83f..84c3eecd5e 100644 --- a/backends/platform/symbian/mmp/scummvm_lure.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_lure.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_m4.mmp.in b/backends/platform/symbian/mmp/scummvm_m4.mmp.in index fafd5e1e5f..e69b40ceb0 100644 --- a/backends/platform/symbian/mmp/scummvm_m4.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_m4.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_made.mmp.in b/backends/platform/symbian/mmp/scummvm_made.mmp.in index 4d5ab6cc33..b52d9cc6cb 100644 --- a/backends/platform/symbian/mmp/scummvm_made.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_made.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in b/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in index 3fc7c4ca5b..5f7bd4e144 100644 --- a/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_mohawk.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in b/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in index 05578b5994..f8ee389577 100644 --- a/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_parallaction.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_queen.mmp.in b/backends/platform/symbian/mmp/scummvm_queen.mmp.in index bfc0a2f760..f507f482f9 100644 --- a/backends/platform/symbian/mmp/scummvm_queen.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_queen.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_saga.mmp.in b/backends/platform/symbian/mmp/scummvm_saga.mmp.in index 831f02bdb6..cd158556dc 100644 --- a/backends/platform/symbian/mmp/scummvm_saga.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_saga.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_sci.mmp.in b/backends/platform/symbian/mmp/scummvm_sci.mmp.in index 705f8d0c43..5749c66e10 100644 --- a/backends/platform/symbian/mmp/scummvm_sci.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_sci.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_scumm.mmp.in b/backends/platform/symbian/mmp/scummvm_scumm.mmp.in index 6b2ad35594..c07725e002 100644 --- a/backends/platform/symbian/mmp/scummvm_scumm.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_scumm.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_sky.mmp.in b/backends/platform/symbian/mmp/scummvm_sky.mmp.in index 5fdfb56320..b5048106dc 100644 --- a/backends/platform/symbian/mmp/scummvm_sky.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_sky.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_sword1.mmp.in b/backends/platform/symbian/mmp/scummvm_sword1.mmp.in index 075968cf98..578839e8c4 100644 --- a/backends/platform/symbian/mmp/scummvm_sword1.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_sword1.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_sword2.mmp.in b/backends/platform/symbian/mmp/scummvm_sword2.mmp.in index 32ab259ee4..23a055c99c 100644 --- a/backends/platform/symbian/mmp/scummvm_sword2.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_sword2.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in b/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in index 61c50bd307..58bfa4c337 100644 --- a/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_teenagent.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in b/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in index 375d948190..4cdd0bd774 100644 --- a/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_tinsel.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_toon.mmp.in b/backends/platform/symbian/mmp/scummvm_toon.mmp.in index d105156107..00f84d2bec 100644 --- a/backends/platform/symbian/mmp/scummvm_toon.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_toon.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_touche.mmp.in b/backends/platform/symbian/mmp/scummvm_touche.mmp.in index 36588e051f..e59dd0cd00 100644 --- a/backends/platform/symbian/mmp/scummvm_touche.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_touche.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_tsage.mmp.in b/backends/platform/symbian/mmp/scummvm_tsage.mmp.in index fb9b075435..cd4aa158dc 100644 --- a/backends/platform/symbian/mmp/scummvm_tsage.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_tsage.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/mmp/scummvm_tucker.mmp.in b/backends/platform/symbian/mmp/scummvm_tucker.mmp.in index f8954e6d21..0ff8eb9920 100644 --- a/backends/platform/symbian/mmp/scummvm_tucker.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_tucker.mmp.in @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/res/ScummVmAif.rss b/backends/platform/symbian/res/ScummVmAif.rss index 3e7a86a3bc..fab2cadbb8 100644 --- a/backends/platform/symbian/res/ScummVmAif.rss +++ b/backends/platform/symbian/res/ScummVmAif.rss @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/res/scummvm.rss b/backends/platform/symbian/res/scummvm.rss index 361f831e3c..7e667f1cf3 100644 --- a/backends/platform/symbian/res/scummvm.rss +++ b/backends/platform/symbian/res/scummvm.rss @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/res/scummvm_A0000658.rss b/backends/platform/symbian/res/scummvm_A0000658.rss index 14d591c990..3325d72249 100644 --- a/backends/platform/symbian/res/scummvm_A0000658.rss +++ b/backends/platform/symbian/res/scummvm_A0000658.rss @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/backends/platform/symbian/src/ScummVm.hrh b/backends/platform/symbian/src/ScummVm.hrh index a84664f995..c43a9da118 100644 --- a/backends/platform/symbian/src/ScummVm.hrh +++ b/backends/platform/symbian/src/ScummVm.hrh @@ -2,7 +2,7 @@ * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer - * Copyright (C) 2005-2012 The ScummVM project + * Copyright (C) 2005-2013 The ScummVM project * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT diff --git a/base/commandLine.cpp b/base/commandLine.cpp index 44007c494a..7f88dc0b63 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -145,7 +145,7 @@ static const char HELP_STRING[] = static const char *s_appName = "scummvm"; -static void usage(const char *s, ...) GCC_PRINTF(1, 2); +static void NORETURN_PRE usage(const char *s, ...) GCC_PRINTF(1, 2) NORETURN_POST; static void usage(const char *s, ...) { char buf[STRINGBUFLEN]; @@ -314,8 +314,11 @@ void registerDefaults() { Common::String parseCommandLine(Common::StringMap &settings, int argc, const char * const *argv) { const char *s, *s2; + if (!argv) + return Common::String(); + // argv[0] contains the name of the executable. - if (argv && argv[0]) { + if (argv[0]) { s = strrchr(argv[0], '/'); s_appName = s ? (s+1) : argv[0]; } @@ -579,8 +582,7 @@ static void listGames() { "-------------------- ------------------------------------------------------\n"); const EnginePlugin::List &plugins = EngineMan.getPlugins(); - EnginePlugin::List::const_iterator iter = plugins.begin(); - for (iter = plugins.begin(); iter != plugins.end(); ++iter) { + for (EnginePlugin::List::const_iterator iter = plugins.begin(); iter != plugins.end(); ++iter) { GameList list = (**iter)->getSupportedGames(); for (GameList::iterator v = list.begin(); v != list.end(); ++v) { printf("%-20s %s\n", v->gameid().c_str(), v->description().c_str()); diff --git a/devtools/credits.pl b/devtools/credits.pl index 3c97e6ab0b..ff3b37a5da 100755 --- a/devtools/credits.pl +++ b/devtools/credits.pl @@ -687,6 +687,11 @@ begin_credits("Credits"); add_person("Joost Peters", "joostp", ""); end_section(); + begin_section("Toltecs"); + add_person("Benjamin Haisch", "john_doe", ""); + add_person("Filippos Karapetis", "[md5]", ""); + end_section(); + begin_section("Tony"); add_person("Arnaud Boutonné", "Strangerke", ""); add_person("Paul Gilbert", "dreammaster", ""); diff --git a/dists/debian/copyright b/dists/debian/copyright index 318c06f62b..1cccd01a07 100644 --- a/dists/debian/copyright +++ b/dists/debian/copyright @@ -7,7 +7,7 @@ It was downloaded from <http://www.scummvm.org/>. Upstream Authors: see `/usr/share/doc/scummvm/AUTHORS'. -Scummvm is Copyright © 2002-2012 The ScummVM Project +Scummvm is Copyright © 2002-2013 The ScummVM Project This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the diff --git a/dists/macosx/Info.plist b/dists/macosx/Info.plist index d8c28f6a08..43d7c37bc5 100644 --- a/dists/macosx/Info.plist +++ b/dists/macosx/Info.plist @@ -28,7 +28,7 @@ <key>CFBundleExecutable</key> <string>scummvm</string> <key>CFBundleGetInfoString</key> - <string>1.6.0git, Copyright 2001-2012 The ScummVM team</string> + <string>1.6.0git, Copyright 2001-2013 The ScummVM team</string> <key>CFBundleIconFile</key> <string>scummvm.icns</string> <key>CFBundleIdentifier</key> @@ -46,7 +46,7 @@ <key>NSPrincipalClass</key> <string>NSApplication</string> <key>NSHumanReadableCopyright</key> - <string>Copyright 2001-2012 The ScummVM team</string> + <string>Copyright 2001-2013 The ScummVM team</string> <key>SUFeedURL</key> <string>http://www.scummvm.org/appcasts/macosx/release.xml</string> <key>SUPublicDSAKeyFile</key> diff --git a/dists/macosx/Info.plist.in b/dists/macosx/Info.plist.in index ff010bee07..b810b7ea5a 100644 --- a/dists/macosx/Info.plist.in +++ b/dists/macosx/Info.plist.in @@ -28,7 +28,7 @@ <key>CFBundleExecutable</key> <string>scummvm</string> <key>CFBundleGetInfoString</key> - <string>@VERSION@, Copyright 2001-2012 The ScummVM team</string> + <string>@VERSION@, Copyright 2001-2013 The ScummVM team</string> <key>CFBundleIconFile</key> <string>scummvm.icns</string> <key>CFBundleIdentifier</key> @@ -46,7 +46,7 @@ <key>NSPrincipalClass</key> <string>NSApplication</string> <key>NSHumanReadableCopyright</key> - <string>Copyright 2001-2012 The ScummVM team</string> + <string>Copyright 2001-2013 The ScummVM team</string> <key>SUFeedURL</key> <string>http://www.scummvm.org/appcasts/macosx/release.xml</string> <key>SUPublicDSAKeyFile</key> diff --git a/dists/scummvm.rc b/dists/scummvm.rc index 8527c668c8..45924f724d 100644 --- a/dists/scummvm.rc +++ b/dists/scummvm.rc @@ -72,7 +72,7 @@ BEGIN VALUE "FileDescription", "http://www.scummvm.org/\0" VALUE "FileVersion", "1.6.0git\0" VALUE "InternalName", "scummvm\0" - VALUE "LegalCopyright", "Copyright © 2001-2012 The ScummVM Team\0" + VALUE "LegalCopyright", "Copyright © 2001-2013 The ScummVM Team\0" VALUE "LegalTrademarks", "'SCUMM', and all SCUMM games are a TM of LucasArts. Simon The Sorcerer is a TM of AdventureSoft. Beneath a Steel Sky and Broken Sword are a TM of Revolution. Flight of the Amazon Queen is a TM of John Passfield and Steve Stamatiadis. \0" VALUE "OriginalFilename", "scummvm.exe\0" VALUE "ProductName", "ScummVM\0" diff --git a/dists/scummvm.rc.in b/dists/scummvm.rc.in index a874b98514..3be699f84b 100644 --- a/dists/scummvm.rc.in +++ b/dists/scummvm.rc.in @@ -69,7 +69,7 @@ BEGIN VALUE "FileDescription", "http://www.scummvm.org/\0" VALUE "FileVersion", "@VERSION@\0" VALUE "InternalName", "scummvm\0" - VALUE "LegalCopyright", "Copyright © 2001-2012 The ScummVM Team\0" + VALUE "LegalCopyright", "Copyright © 2001-2013 The ScummVM Team\0" VALUE "LegalTrademarks", "'SCUMM', and all SCUMM games are a TM of LucasArts. Simon The Sorcerer is a TM of AdventureSoft. Beneath a Steel Sky and Broken Sword are a TM of Revolution. Flight of the Amazon Queen is a TM of John Passfield and Steve Stamatiadis. \0" VALUE "OriginalFilename", "scummvm.exe\0" VALUE "ProductName", "ScummVM\0" diff --git a/dists/win32/ScummVM.iss b/dists/win32/ScummVM.iss index adea759110..fa0f760f59 100644 --- a/dists/win32/ScummVM.iss +++ b/dists/win32/ScummVM.iss @@ -1,5 +1,5 @@ [Setup] -AppCopyright=2012 +AppCopyright=2013 AppName=ScummVM AppVerName=ScummVM Git AppPublisher=The ScummVM Team diff --git a/dists/win32/migration.bat b/dists/win32/migration.bat index 2bba7baef4..b4b00c02cc 100644 --- a/dists/win32/migration.bat +++ b/dists/win32/migration.bat @@ -4,7 +4,7 @@ :: This script will copy any saved games located in the :: old default location, to the new default location. :: -:: (c) 2012 ScummVM Team +:: (c) 2012-2013 ScummVM Team :: @echo off diff --git a/dists/win32/scummvm.nsi b/dists/win32/scummvm.nsi index 795eb660b6..fb4787a172 100644 --- a/dists/win32/scummvm.nsi +++ b/dists/win32/scummvm.nsi @@ -76,7 +76,7 @@ Name ScummVM !define COMPANY "ScummVM Team" !define URL "http://scummvm.org/" !define DESCRIPTION "ScummVM Installer. Look! A three headed monkey (TM)!" -!define COPYRIGHT "Copyright © 2001-2012 The ScummVM Team" +!define COPYRIGHT "Copyright © 2001-2013 The ScummVM Team" ######################################################################################### # Installer configuration diff --git a/dists/win32/scummvm.nsi.in b/dists/win32/scummvm.nsi.in index 340024e6a1..9f8bd1dad2 100644 --- a/dists/win32/scummvm.nsi.in +++ b/dists/win32/scummvm.nsi.in @@ -76,7 +76,7 @@ Name ScummVM !define COMPANY "ScummVM Team" !define URL "http://scummvm.org/" !define DESCRIPTION "ScummVM Installer. Look! A three headed monkey (TM)!" -!define COPYRIGHT "Copyright © 2001-2012 The ScummVM Team" +!define COPYRIGHT "Copyright © 2001-2013 The ScummVM Team" ######################################################################################### # Installer configuration diff --git a/engines/drascula/animation.cpp b/engines/drascula/animation.cpp index 43799f7944..53cba9a7a4 100644 --- a/engines/drascula/animation.cpp +++ b/engines/drascula/animation.cpp @@ -42,7 +42,6 @@ void DrasculaEngine::updateAnim(int y, int destX, int destY, int width, int heig } } -// This is the game's introduction sequence void DrasculaEngine::animation_1_1() { debug(4, "animation_1_1()"); @@ -92,12 +91,8 @@ void DrasculaEngine::animation_1_1() { playFLI("scrollb.bin", 9); - if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()) - break; clearRoom(); playSound(5); - if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()) - break; if (animate("scr2.bin", 17)) break; stopSound(); @@ -194,8 +189,6 @@ void DrasculaEngine::animation_1_1() { if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()) break; talk_drascula(3); - if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()) - break; if (animate("lib.bin", 16)) break; if (animate("lib2.bin", 16)) @@ -211,8 +204,6 @@ void DrasculaEngine::animation_1_1() { loadPic("plan1.alg", screenSurface, HALF_PAL); updateScreen(); talk_solo(_textd[5], "d5.als"); - if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()) - break; if (animate("lib2.bin", 16)) break; clearRoom(); @@ -220,8 +211,6 @@ void DrasculaEngine::animation_1_1() { updateScreen(); pause(20); talk_solo(_textd[6], "d6.als"); - if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()) - break; if (animate("lib2.bin", 16)) break; clearRoom(); @@ -255,8 +244,6 @@ void DrasculaEngine::animation_1_1() { break; playMusic(11); talk_drascula(10); - if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()) - break; if (animate("rayo1.bin", 16)) break; playSound(5); @@ -372,7 +359,6 @@ void DrasculaEngine::animation_1_1() { loadPic(99, backSurface); } -// John falls in love with BJ, who is then abducted by Drascula void DrasculaEngine::animation_2_1() { debug(4, "animation_2_1()"); @@ -384,9 +370,6 @@ void DrasculaEngine::animation_2_1() { term_int = 0; while (!shouldQuit()) { - if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()) - break; - if (animate("ag.bin", 14)) break; @@ -456,13 +439,8 @@ void DrasculaEngine::animation_2_1() { curY = 95; trackProtagonist = 1; hare_se_ve = 1; - if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()) - break; loadPic("97g.alg", extraSurface); - if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()) - break; - if (animate("lev.bin", 15)) break; @@ -520,8 +498,6 @@ void DrasculaEngine::animation_2_1() { break; talk_bj(12); gotoObject(157, 98 + curHeight); - if ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()) - break; if (animate("bes.bin", 16)) break; playMusic(11); @@ -563,7 +539,6 @@ void DrasculaEngine::animation_2_1() { } } -// John Hacker talks with the bartender to book a room void DrasculaEngine::animation_3_1() { debug(4, "animation_3_1()"); @@ -574,7 +549,6 @@ void DrasculaEngine::animation_3_1() { loadPic(97, extraSurface); } -// John Hacker talks with the pianist void DrasculaEngine::animation_4_1() { debug(4, "animation_4_1()"); @@ -676,26 +650,39 @@ void DrasculaEngine::animation_4_2() { pause(5); talk_hacker(57); pause(6); - talk_blind(2); - pause(4); - talk_hacker(58); - talk_blind(3); - delay(14); - talk_hacker(59); - talk_blind(4); - talk_hacker(60); - talk_blind(5); - talk_hacker(61); - talk_blind(6); - talk_hacker(62); - talk_blind(7); - talk_hacker(63); - talk_blind(8); - copyBackground(); - updateScreen(); - _system->delayMillis(1000); - talk_hacker(64); - talk_blind(9); + + if (flags[4] == 0) { // first time + talk_blind(2); + pause(4); + talk_hacker(58); + talk_blind(3); + delay(14); + talk_hacker(59); + talk_blind(4); + talk_hacker(60); + talk_blind(5); + talk_hacker(61); + talk_blind(6); + talk_hacker(62); + talk_blind(7); + talk_hacker(63); + talk_blind(8); + copyBackground(); + updateScreen(); + _system->delayMillis(1000); + talk_hacker(64); + talk_blind(9); + + flags[4] = 1; // talked to the blind man + } else { // second time + _system->delayMillis(1000); + talk_blind(10); + talk_hacker(65); + + flags[33] = 1; + } + + flags[9] = 0; copyBackground(); updateScreen(); @@ -711,9 +698,6 @@ void DrasculaEngine::animation_4_2() { loadPic(97, extraSurface); loadPic(99, backSurface); selectVerb(kVerbNone); - - flags[9] = 0; - flags[4] = 1; } void DrasculaEngine::animation_14_2() { @@ -798,17 +782,22 @@ void DrasculaEngine::animation_16_2() { return; } - delay(3000); + uint32 now = _system->getMillis(); + while (_system->getMillis() - now < 3000 * 2) { + delay(50); + if (getScan() != 0) { + asco(); + return; + } + } if (i < 4) { fadeToBlack(1); - + clearRoom(); if (getScan() != 0) { asco(); return; } - - clearRoom(); } } @@ -818,6 +807,7 @@ void DrasculaEngine::animation_16_2() { for (int l = 1; l < 200; l++) { copyBackground(0, 0, 0, l, 320, 200 - l, drawSurface3, screenSurface); copyBackground(0, 200 - l, 0, 0, 320, l, bgSurface, screenSurface); + delay(10); updateScreen(); if (getScan() != 0) { asco(); @@ -867,6 +857,20 @@ void DrasculaEngine::animation_20_2() { void DrasculaEngine::animation_23_2() { debug(4, "animation_23_2()"); + int p_x, p_y; + int maxN; + int animX, animY; + + // Animation offsets - without earplugs + int x1[] = {1, 38, 75, 112, 75, 112, 75, 112, 149, 112, 149, 112, 149, 186, 223, 260, + 1, 38, 75, 112, 149, 112, 149, 112, 149, 112, 149, 186, 223, 260, 260, 260, 260, 223}; + int y1[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 1, 1, 1, 1}; + + // Animation offsets - with earplugs + int x2[] = {1, 35, 69, 103, 137, 171, 205, 239, 273, 1, 35, 69, 103, 137}; + int y2[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 73, 73, 73, 73, 73}; + loadPic("an24.alg", frontSurface); flags[21] = 1; @@ -893,10 +897,41 @@ void DrasculaEngine::animation_23_2() { trackVonBraun = 1; talk_vonBraun(18, kVonBraunNormal); - if (flags[29] == 0) - animation_23_joined(); - else - animation_23_joined2(); + if (flags[29] == 0) { + // John isn't wearing earplugs + p_x = curX + 2; + p_y = curY - 3; + maxN = 34; + animX = 36; + animY = 74; + + loadPic("an23.alg", backSurface); + } else { + // John is wearing earplugs + p_x = curX + 4; + p_y = curY; + maxN = 14; + animX = 33; + animY = 71; + + pause(50); + + loadPic("an23_2.alg", backSurface); + } + + for (int n = 0; n < maxN; n++) { + copyRect(p_x, p_y, p_x, p_y, animX, animY, bgSurface, screenSurface); + if (flags[29] == 0) + copyRect(x1[n], y1[n], p_x, p_y, animX, animY, backSurface, screenSurface); + else + copyRect(x2[n], y2[n], p_x, p_y, animX, animY, backSurface, screenSurface); + updateRefresh(); + updateScreen(p_x, p_y, p_x, p_y, animX, animY, screenSurface); + updateEvents(); + pause(5); + } + + loadPic(99, backSurface); trackVonBraun = 2; animation_25_2(); @@ -921,52 +956,6 @@ void DrasculaEngine::animation_23_2() { breakOut = 1; } -void DrasculaEngine::animation_23_joined() { - debug(4, "animation_23_joined()"); - - int p_x = curX + 2, p_y = curY - 3; - int x[] = {1, 38, 75, 112, 75, 112, 75, 112, 149, 112, 149, 112, 149, 186, 223, 260, - 1, 38, 75, 112, 149, 112, 149, 112, 149, 112, 149, 186, 223, 260, 260, 260, 260, 223}; - int y[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 76, 76, 76, 76, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 1, 1, 1, 1}; - - loadPic("an23.alg", backSurface); - - for (int n = 0; n < 34; n++) { - copyRect(p_x, p_y, p_x, p_y, 36, 74, bgSurface, screenSurface); - copyRect(x[n], y[n], p_x, p_y, 36, 74, backSurface, screenSurface); - updateRefresh(); - updateScreen(p_x, p_y, p_x, p_y, 36, 74, screenSurface); - updateEvents(); - pause(5); - } - - loadPic(99, backSurface); -} - -void DrasculaEngine::animation_23_joined2() { - debug(4, "animation_23_joined2()"); - - int p_x = curX + 4, p_y = curY; - int x[] = {1, 35, 69, 103, 137, 171, 205, 239, 273, 1, 35, 69, 103, 137}; - int y[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 73, 73, 73, 73, 73}; - - pause(50); - - loadPic("an23_2.alg", backSurface); - - for (int n = 0; n < 14; n++) { - copyRect(p_x, p_y, p_x, p_y, 33, 71, bgSurface, screenSurface); - copyRect(x[n], y[n], p_x, p_y, 33, 71, backSurface, screenSurface); - updateRefresh(); - updateScreen(p_x,p_y, p_x,p_y, 33,71, screenSurface); - updateEvents(); - pause(5); - } - - loadPic(99, backSurface); -} - void DrasculaEngine::animation_25_2() { debug(4, "animation_25_2()"); @@ -1091,31 +1080,11 @@ void DrasculaEngine::animation_35_2() { fadeToBlack(2); } -// Use cross on Yoda void DrasculaEngine::animation_2_3() { debug(4, "animation_2_3()"); flags[0] = 1; playMusic(13); - animation_3_3(); - playMusic(13); - animation_4_3(); - flags[1] = 1; - updateRoom(); - updateScreen(120, 0, 120, 0, 200, 200, screenSurface); - animation_5_3(); - flags[0] = 0; - flags[1] = 1; - - loadPic(96, frontSurface); - loadPic(97, extraSurface); - loadPic(99, backSurface); - - gotoObject(332, 127); -} - -void DrasculaEngine::animation_3_3() { - debug(4, "animation_3_3()"); int px = curX - 20, py = curY - 1; @@ -1129,12 +1098,11 @@ void DrasculaEngine::animation_3_3() { updateAnim(75, px, py, 71, 72, 4, extraSurface, 3, true); updateAnim(2, px, py, 71, 72, 4, backSurface, 3, true); updateAnim(75, px, py, 71, 72, 4, backSurface, 3, true); -} -void DrasculaEngine::animation_4_3() { - debug(4, "animation_4_3()"); + playMusic(13); - int px = 120, py = 63; + px = 120; + py = 63; loadPic("any_1.alg", frontSurface); loadPic("any_2.alg", extraSurface); @@ -1146,12 +1114,13 @@ void DrasculaEngine::animation_4_3() { updateAnim(91, px, py, 77, 89, 4, extraSurface, 3, true); updateAnim(1, px, py, 77, 89, 4, backSurface, 3, true); updateAnim(91, px, py, 77, 89, 4, backSurface, 3, true); -} -void DrasculaEngine::animation_5_3() { - debug(4, "animation_5_3()"); + flags[1] = 1; + updateRoom(); + updateScreen(120, 0, 120, 0, 200, 200, screenSurface); - int px = curX - 20, py = curY - 1; + px = curX - 20; + py = curY - 1; loadPic("an3y_1.alg", frontSurface); loadPic("an3y_2.alg", extraSurface); @@ -1163,6 +1132,15 @@ void DrasculaEngine::animation_5_3() { updateAnim(75, px, py, 71, 72, 4, extraSurface, 3, true); updateAnim(2, px, py, 71, 72, 4, backSurface, 3, true); updateAnim(75, px, py, 71, 72, 4, backSurface, 3, true); + + flags[0] = 0; + flags[1] = 1; + + loadPic(96, frontSurface); + loadPic(97, extraSurface); + loadPic(99, backSurface); + + gotoObject(332, 127); } void DrasculaEngine::animation_6_3() { @@ -1197,8 +1175,8 @@ void DrasculaEngine::animation_6_3() { updateScreen(); } -void DrasculaEngine::animation_ray() { - debug(4, "animation_ray()"); +void DrasculaEngine::animation_castle() { + debug(4, "animation_castle()"); loadPic("anr_1.alg", frontSurface, HALF_PAL); loadPic("anr_2.alg", extraSurface); @@ -1365,18 +1343,6 @@ void DrasculaEngine::animation_5_5(){ loadPic(49, bgSurface, HALF_PAL); } -void DrasculaEngine::animation_11_5() { - debug(4, "animation_11_5()"); - - flags[9] = 1; - if (flags[2] == 1 && flags[3] == 1 && flags[4] == 1) - animation_12_5(); - else { - flags[9] = 0; - talk(33); - } -} - void DrasculaEngine::animation_12_5() { debug(4, "animation_12_5()"); @@ -1426,7 +1392,7 @@ void DrasculaEngine::animation_12_5() { loadPic("3an11_1.alg", backSurface); for (frame = 0; frame < 8; frame++) { - if (frame == 2 || frame == 4 || frame == 8 || frame==10) + if (frame == 2 || frame == 4 || frame == 8 || frame == 10) setPalette((byte *)&bgPalette1); else if (frame == 1 || frame == 5 || frame == 7 || frame == 9) setPalette((byte *)&bgPalette2); @@ -1465,7 +1431,8 @@ void DrasculaEngine::animation_12_5() { flags[1] = 1; - animation_13_5(); + animation_12_5_frankenstein(); + playSound(1); hiccup(12); finishSound(); @@ -1487,13 +1454,11 @@ void DrasculaEngine::animation_12_5() { enterRoom(57); } -void DrasculaEngine::animation_13_5() { - debug(4, "animation_13_5()"); - +void DrasculaEngine::animation_12_5_frankenstein() { int frank_x = 199; - int frame = 0; int frus_x[] = {1, 46, 91, 136, 181, 226, 271}; int frus_y[] = {1, 1, 1, 1, 1, 1, 1, 89}; + int frame = 0; loadPic("auxfr.alg", backSurface); @@ -1898,27 +1863,6 @@ void DrasculaEngine::animation_24_2() { loadPic("an24.alg", frontSurface); - animation_32_2(); - - flags[21] = 1; - - talk_vonBraun(22, kVonBraunNormal); - - if (flags[22] == 0) - converse(4); - else - converse(5); - - exitRoom(0); - flags[21] = 0; - flags[24] = 0; - trackVonBraun = 1; - vonBraunX = 120; -} - -void DrasculaEngine::animation_32_2() { - debug(4, "animation_32_2()"); - loadPic("an32_1.alg", drawSurface3); loadPic("an32_2.alg", backSurface); @@ -1939,6 +1883,21 @@ void DrasculaEngine::animation_32_2() { } loadPic("aux18.alg", drawSurface3); + + flags[21] = 1; + + talk_vonBraun(22, kVonBraunNormal); + + if (flags[22] == 0) + converse(4); + else + converse(5); + + exitRoom(0); + flags[21] = 0; + flags[24] = 0; + trackVonBraun = 1; + vonBraunX = 120; } void DrasculaEngine::animation_34_2() { @@ -2126,55 +2085,6 @@ void DrasculaEngine::animation_6_2() { flags[9] = 0; } -void DrasculaEngine::animation_33_2() { - debug(4, "animation_33_2()"); - - stopMusic(); - flags[9] = 1; - - pause(12); - talk(60); - pause(8); - - clearRoom(); - loadPic("ciego1.alg", bgSurface, HALF_PAL); // ciego = blind - loadPic("ciego2.alg", drawSurface3); - loadPic("ciego3.alg", extraSurface); - loadPic("ciego4.alg", backSurface); - loadPic("ciego5.alg", frontSurface); - - copyBackground(); - updateScreen(); - - pause(10); - - talk_blind(1); - pause(5); - talk_hacker(57); - pause(6); - _system->delayMillis(1000); - talk_blind(10); - talk_hacker(65); - - copyBackground(); - updateScreen(); - - pause(14); - - clearRoom(); - - playMusic(roomMusic); - loadPic(9, bgSurface, HALF_PAL); - loadPic("aux9.alg", drawSurface3); - loadPic(96, frontSurface); - loadPic(97, extraSurface); - loadPic(99, backSurface); - selectVerb(kVerbNone); - - flags[33] = 1; - flags[9] = 0; -} - void DrasculaEngine::animation_1_4() { debug(4, "animation_1_4()"); diff --git a/engines/drascula/console.cpp b/engines/drascula/console.cpp index d2fd32f2e5..426b2ade67 100644 --- a/engines/drascula/console.cpp +++ b/engines/drascula/console.cpp @@ -46,7 +46,6 @@ bool Console::Cmd_Room(int argc, const char **argv) { _vm->selectVerb(kVerbNone); _vm->clearRoom(); _vm->loadPic(roomNum, _vm->bgSurface, HALF_PAL); - _vm->selectionMade = 0; return false; } diff --git a/engines/drascula/converse.cpp b/engines/drascula/converse.cpp index 7abbb3214b..d045d683fc 100644 --- a/engines/drascula/converse.cpp +++ b/engines/drascula/converse.cpp @@ -167,7 +167,6 @@ void DrasculaEngine::converse(int index) { // no need to delete the stream, since TextResourceParser takes ownership // delete stream; - if (currentChapter == 2 && !strcmp(fileName, "op_5.cal") && flags[38] == 1 && flags[33] == 1) { strcpy(phrase3, _text[405]); strcpy(sound3, "405.als"); diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp index 598af5acff..e1f69e2158 100644 --- a/engines/drascula/detection.cpp +++ b/engines/drascula/detection.cpp @@ -21,10 +21,13 @@ */ #include "base/plugins.h" +#include "common/file.h" +#include "common/translation.h" #include "engines/advancedDetector.h" #include "engines/savestate.h" -#include "common/file.h" + +#include "graphics/thumbnail.h" #include "drascula/drascula.h" @@ -263,81 +266,123 @@ static const DrasculaGameDescription gameDescriptions[] = { { AD_TABLE_END_MARKER } }; -} // End of namespace Drascula +static const ExtraGuiOption drasculaExtraGuiOption = { + _s("Use original save/load screens"), + _s("Use the original save/load screens, instead of the ScummVM ones"), + "originalsaveload", + false +}; + +SaveStateDescriptor loadMetaData(Common::ReadStream *s, int slot, bool setPlayTime); class DrasculaMetaEngine : public AdvancedMetaEngine { public: DrasculaMetaEngine() : AdvancedMetaEngine(Drascula::gameDescriptions, sizeof(Drascula::DrasculaGameDescription), drasculaGames) { _singleid = "drascula"; - _guioptions = GUIO2(GUIO_NOMIDI, GUIO_NOLAUNCHLOAD); + _guioptions = GUIO1(GUIO_NOMIDI); + } + + virtual const char *getName() const { + return "Drascula"; } - virtual bool hasFeature(MetaEngineFeature f) const { - return (f == kSupportsListSaves); + virtual const char *getOriginalCopyright() const { + return "Drascula Engine (C) 2000 Alcachofa Soft, (C) 1996 Digital Dreams Multimedia, (C) 1994 Emilio de Paz"; } - virtual SaveStateList listSaves(const char *target) const { - Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); - Common::String pattern = Common::String::format("%s??", target); + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const; + virtual bool hasFeature(MetaEngineFeature f) const; + virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const; + virtual SaveStateList listSaves(const char *target) const; + virtual int getMaximumSaveSlot() const; + virtual void removeSaveState(const char *target, int slot) const; + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; +}; - // Get list of savefiles for target game - Common::StringArray filenames = saveFileMan->listSavefiles(pattern); - Common::Array<int> slots; - for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { +bool DrasculaMetaEngine::hasFeature(MetaEngineFeature f) const { + return + (f == kSupportsListSaves) || + (f == kSupportsLoadingDuringStartup) || + (f == kSupportsDeleteSave) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportThumbnail) || + (f == kSavesSupportCreationDate) || + (f == kSavesSupportPlayTime); +} - // Obtain the last 2 digits of the filename, since they correspond to the save slot - int slotNum = atoi(file->c_str() + file->size() - 2); +const ExtraGuiOptions DrasculaMetaEngine::getExtraGuiOptions(const Common::String &target) const { + ExtraGuiOptions options; + options.push_back(drasculaExtraGuiOption); + return options; +} - // Ensure save slot is within valid range - if (slotNum >= 1 && slotNum <= 10) { - slots.push_back(slotNum); +SaveStateList DrasculaMetaEngine::listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray filenames; + Common::String pattern = target; + pattern += ".???"; + + filenames = saveFileMan->listSavefiles(pattern); + sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..) + + SaveStateList saveList; + int slotNum = 0; + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + // Obtain the last 3 digits of the filename, since they correspond to the save slot + slotNum = atoi(file->c_str() + file->size() - 3); + + if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) { + Common::InSaveFile *in = saveFileMan->openForLoading(*file); + if (in) { + SaveStateDescriptor desc = loadMetaData(in, slotNum, false); + if (desc.getSaveSlot() != slotNum) { + // invalid + delete in; + continue; + } + saveList.push_back(desc); + delete in; } } + } - // Sort save slot ids - Common::sort<int>(slots.begin(), slots.end()); - - // Load save index - Common::String fileEpa = Common::String::format("%s.epa", target); - Common::InSaveFile *epa = saveFileMan->openForLoading(fileEpa); - - // Get savegame names from index - Common::String saveDesc; - SaveStateList saveList; - int line = 1; - for (uint i = 0; i < slots.size(); i++) { - // ignore lines corresponding to unused saveslots - for (; line < slots[i]; line++) - epa->readLine(); + return saveList; +} - // copy the name in the line corresponding to the save slot and truncate to 22 characters - saveDesc = Common::String(epa->readLine().c_str(), 22); +SaveStateDescriptor DrasculaMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + char fileName[MAXPATHLEN]; + sprintf(fileName, "%s.%03d", target, slot); - // handle cases where the save directory and save index are detectably out of sync - if (saveDesc == "*") - saveDesc = "No name specified."; + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName); - // increment line number to keep it in sync with slot number - line++; + SaveStateDescriptor desc; + // Do not allow save slot 0 (used for auto-saving) to be deleted or + // overwritten. + desc.setDeletableFlag(slot != 0); + desc.setWriteProtectedFlag(slot == 0); - // Insert savegame name into list - saveList.push_back(SaveStateDescriptor(slots[i], saveDesc)); + if (in) { + desc = Drascula::loadMetaData(in, slot, false); + if (desc.getSaveSlot() != slot) { + delete in; + return SaveStateDescriptor(); } - delete epa; - return saveList; - } + Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in); + desc.setThumbnail(thumbnail); - virtual const char *getName() const { - return "Drascula"; + delete in; } - virtual const char *getOriginalCopyright() const { - return "Drascula Engine (C) 2000 Alcachofa Soft, (C) 1996 Digital Dreams Multimedia, (C) 1994 Emilio de Paz"; - } + return desc; +} - virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; -}; +int DrasculaMetaEngine::getMaximumSaveSlot() const { return 999; } + +void DrasculaMetaEngine::removeSaveState(const char *target, int slot) const { + Common::String fileName = Common::String::format("%s.%03d", target, slot); + g_system->getSavefileManager()->removeSavefile(fileName); +} bool DrasculaMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { const Drascula::DrasculaGameDescription *gd = (const Drascula::DrasculaGameDescription *)desc; @@ -347,8 +392,10 @@ bool DrasculaMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD return gd != 0; } +} // End of namespace Drascula + #if PLUGIN_ENABLED_DYNAMIC(DRASCULA) - REGISTER_PLUGIN_DYNAMIC(DRASCULA, PLUGIN_TYPE_ENGINE, DrasculaMetaEngine); + REGISTER_PLUGIN_DYNAMIC(DRASCULA, PLUGIN_TYPE_ENGINE, Drascula::DrasculaMetaEngine); #else - REGISTER_PLUGIN_STATIC(DRASCULA, PLUGIN_TYPE_ENGINE, DrasculaMetaEngine); + REGISTER_PLUGIN_STATIC(DRASCULA, PLUGIN_TYPE_ENGINE, Drascula::DrasculaMetaEngine); #endif diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp index 1b3c4038f0..7733a0fd6b 100644 --- a/engines/drascula/drascula.cpp +++ b/engines/drascula/drascula.cpp @@ -87,6 +87,7 @@ DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam _textmisc = 0; _textd1 = 0; _talkSequences = 0; + _currentSaveSlot = 0; _color = 0; blinking = 0; @@ -187,6 +188,8 @@ Common::Error DrasculaEngine::run() { if (!loadDrasculaDat()) return Common::kUnknownError; + checkForOldSaveGames(); + setupRoomsTable(); loadArchives(); @@ -195,6 +198,13 @@ Common::Error DrasculaEngine::run() { currentChapter = 1; // values from 1 to 6 will start each part of game loadedDifferentChapter = 0; + setTotalPlayTime(0); + + // Check if a save is loaded from the launcher + int directSaveSlotLoading = ConfMan.getInt("save_slot"); + if (directSaveSlotLoading >= 0) { + loadGame(directSaveSlotLoading); + } checkCD(); @@ -233,7 +243,6 @@ Common::Error DrasculaEngine::run() { framesWithoutAction = 0; term_int = 0; musicStopped = 0; - selectionMade = 0; globalSpeed = 0; curExcuseLook = 0; curExcuseAction = 0; @@ -246,7 +255,6 @@ Common::Error DrasculaEngine::run() { allocMemory(); _subtitlesDisabled = !ConfMan.getBool("subtitles"); - selectionMade = 0; if (currentChapter != 3) loadPic(96, frontSurface, COMPLETE_PAL); @@ -261,7 +269,7 @@ Common::Error DrasculaEngine::run() { loadPic(96, frontSurface); } else if (currentChapter == 4) { if (loadedDifferentChapter == 0) - animation_ray(); + animation_castle(); loadPic(96, frontSurface); clearRoom(); } else if (currentChapter == 5) { @@ -295,6 +303,7 @@ Common::Error DrasculaEngine::run() { strcpy(iconName[i + 1], _textverbs[i]); assignPalette(defaultPalette); + if (!runCurrentChapter()) { endChapter(); break; @@ -359,7 +368,7 @@ bool DrasculaEngine::runCurrentChapter() { trackProtagonist = 1; objExit = 104; if (loadedDifferentChapter != 0) { - if (!loadGame(saveName)) { + if (!loadGame(_currentSaveSlot)) { return true; } } else { @@ -368,6 +377,8 @@ bool DrasculaEngine::runCurrentChapter() { curY = 56; gotoObject(65, 145); } + + // REMINDER: This is a good place to debug animations } else if (currentChapter == 2) { addObject(kItemPhone); trackProtagonist = 3; @@ -375,7 +386,7 @@ bool DrasculaEngine::runCurrentChapter() { if (loadedDifferentChapter == 0) enterRoom(14); else { - if (!loadGame(saveName)) { + if (!loadGame(_currentSaveSlot)) { return true; } } @@ -393,7 +404,7 @@ bool DrasculaEngine::runCurrentChapter() { if (loadedDifferentChapter == 0) enterRoom(20); else { - if (!loadGame(saveName)) { + if (!loadGame(_currentSaveSlot)) { return true; } } @@ -410,7 +421,7 @@ bool DrasculaEngine::runCurrentChapter() { curX = 235; curY = 164; } else { - if (!loadGame(saveName)) { + if (!loadGame(_currentSaveSlot)) { return true; } } @@ -429,7 +440,7 @@ bool DrasculaEngine::runCurrentChapter() { if (loadedDifferentChapter == 0) { enterRoom(45); } else { - if (!loadGame(saveName)) { + if (!loadGame(_currentSaveSlot)) { return true; } } @@ -443,7 +454,7 @@ bool DrasculaEngine::runCurrentChapter() { enterRoom(58); animation_1_6(); } else { - if (!loadGame(saveName)) { + if (!loadGame(_currentSaveSlot)) { return true; } loadPic("auxdr.alg", drawSurface2); @@ -596,13 +607,23 @@ bool DrasculaEngine::runCurrentChapter() { selectVerb(kVerbTalk); } else if (key == Common::KEYCODE_F6 && !_menuScreen) { selectVerb(kVerbMove); - } else if (key == Common::KEYCODE_F9) { - volumeControls(); - } else if (key == Common::KEYCODE_F10) { - if (!saveLoadScreen()) + } else if (key == Common::KEYCODE_F7) { + // ScummVM load screen + if (!scummVMSaveLoadDialog(false)) return true; } else if (key == Common::KEYCODE_F8) { selectVerb(kVerbNone); + } else if (key == Common::KEYCODE_F9) { + volumeControls(); + } else if (key == Common::KEYCODE_F10) { + if (!ConfMan.getBool("originalsaveload")) { + // ScummVM save screen + scummVMSaveLoadDialog(true); + } else { + // Original save/load screen + if (!saveLoadScreen()) + return true; + } } else if (key == Common::KEYCODE_v) { _subtitlesDisabled = true; ConfMan.setBool("subtitles", !_subtitlesDisabled); @@ -628,17 +649,14 @@ bool DrasculaEngine::runCurrentChapter() { } if (leftMouseButton != 0 || rightMouseButton != 0 || key != 0) - if (currentChapter != 3) - framesWithoutAction = 0; + framesWithoutAction = 0; if (framesWithoutAction == 15000) { screenSaver(); - if (currentChapter != 3) - framesWithoutAction = 0; + framesWithoutAction = 0; } - if (currentChapter != 3) - framesWithoutAction++; + framesWithoutAction++; } return false; diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h index 2d1954e3ca..3259fa63bc 100644 --- a/engines/drascula/drascula.h +++ b/engines/drascula/drascula.h @@ -36,6 +36,8 @@ #include "common/system.h" #include "common/util.h" +#include "engines/savestate.h" + #include "audio/mixer.h" #include "engines/engine.h" @@ -453,11 +455,9 @@ public: int term_int; int currentChapter; int loadedDifferentChapter; - char saveName[13]; + int _currentSaveSlot; int _color; int musicStopped; - char select[23]; - int selectionMade; int mouseX; int mouseY; int leftMouseButton; @@ -494,9 +494,16 @@ public: void selectVerb(int); void updateVolume(Audio::Mixer::SoundType soundType, int prevVolume); void volumeControls(); + bool saveLoadScreen(); + bool scummVMSaveLoadDialog(bool isSave); + Common::String enterName(Common::String &selectedName); void loadSaveNames(); - void saveSaveNames(); + void saveGame(int slot, Common::String &desc); + bool loadGame(int slot); + void checkForOldSaveGames(); + void convertSaveGame(int slot, Common::String &desc); + void print_abc(const char *, int, int); void delay(int ms); bool confirmExit(); @@ -550,7 +557,6 @@ public: void updateMusic(); int musicStatus(); void updateRoom(); - bool loadGame(const char *); void updateDoor(int); void setPaletteBase(int darkness); void updateVisible(); @@ -568,7 +574,6 @@ public: void showCursor(); void hideCursor(); bool isCursorVisible(); - void enterName(); bool soundIsActive(); void waitFrameSSN(); void mixVideo(byte *OldScreen, byte *NewScreen, uint16 oldPitch); @@ -589,7 +594,6 @@ public: void quadrant_2(); void quadrant_3(); void quadrant_4(); - void saveGame(const char *gameName); void increaseFrameNum(); int whichObject(); bool checkMenuFlags(); @@ -650,63 +654,56 @@ public: bool room_62(int); bool room_102(int); - void animation_1_1(); - void animation_2_1(); - void animation_3_1(); - void animation_4_1(); - // - void animation_2_2(); - void animation_4_2(); - void animation_5_2(); - void animation_6_2(); - void animation_7_2(); - void animation_11_2(); - void animation_12_2(); - void animation_13_2(); - void animation_14_2(); void asco(); - void animation_16_2(); - void animation_20_2(); - void animation_23_2(); - void animation_23_joined(); - void animation_23_joined2(); - void animation_24_2(); - void animation_25_2(); - void animation_26_2(); - void animation_27_2(); - void animation_29_2(); - void animation_31_2(); - void animation_32_2(); - void animation_33_2(); - void animation_34_2(); - void animation_35_2(); - void animation_36_2(); + + void animation_1_1(); // Game introduction + void animation_2_1(); // John falls in love with BJ, who is then abducted by Drascula + void animation_3_1(); // John talks with the bartender to book a room + void animation_4_1(); // John talks with the pianist + // + void animation_2_2(); // John enters the chapel via the window + void animation_4_2(); // John talks with the blind man (closeup) + void animation_5_2(); // John breaks the chapel window with the pike + void animation_6_2(); // The blind man (closeup) thanks John for giving him money and hands him the sickle + void animation_7_2(); // John uses the sickle + void animation_11_2(); // The drunk man says "they're all dead, thanks *hic*" + void animation_12_2(); // Conversation screen - John talks to the pianist after BJ is abducted by Drascula + void animation_13_2(); // ??? + void animation_14_2(); // The glass box falls from the ceiling + void animation_16_2(); // The drunk tells us about Von Braun + void animation_20_2(); // Von Braun tells John that he needs to have special skills to fight vampires + void animation_23_2(); // Von Braun tests John's reactions to scratching noises + void animation_24_2(); // Conversation screen - John talks with Von Braun + void animation_25_2(); // The glass box is lifted back to the ceiling + void animation_26_2(); // John gives the book to the pianist and gets his earplugs in return + void animation_27_2(); // Von Braun admits that John is ready to fight vampires and gives him his money back + void animation_29_2(); // Von Braun tells John what ingredients he needs for the brew + void animation_31_2(); // Von Braun obtains the items needed for the brew from John and creates it + void animation_34_2(); // John kicks an object + void animation_35_2(); // John jumps into the well + void animation_36_2(); // John asks the bartender about the pianist // - void animation_2_3(); - void animation_3_3(); - void animation_4_3(); - void animation_5_3(); - void animation_6_3(); - void animation_ray(); + void animation_2_3(); // John uses the cross with the Frankenstein-zombie ("yoda") and destroys him + void animation_6_3(); // Frankenstein is blocking John's path // - void animation_1_4(); - void animation_5_4(); - void animation_6_4(); - void animation_7_4(); - void animation_8_4(); + void animation_castle(); // Chapter 4 start - Drascula's castle exterior, lightning strikes + void animation_1_4(); // Conversation screen - John talks with Igor + void animation_5_4(); // John enters Igor's room dressed as Drascula + void animation_6_4(); // Igor says that he's going for supper + void animation_7_4(); // John removes Drascula's disguise + void animation_8_4(); // Secret passage behind bookcase is revealed // - void animation_1_5(); - void animation_5_5(); - void animation_11_5(); - void animation_12_5(); - void animation_13_5(); - void animation_14_5(); + void animation_1_5(); // John finds BJ + void animation_5_5(); // ??? + void animation_12_5(); // Frankenstein comes to life + void animation_12_5_frankenstein(); + void animation_14_5(); // John finds out that an object is empty // - void animation_1_6(); - void animation_5_6(); - void animation_6_6(); - void animation_9_6(); - void animation_19_6(); + void animation_1_6(); // ??? + void animation_5_6(); // John is tied to the table. Drascula and Igor lower the pendulum + void animation_6_6(); // John uses the pendulum to break free + void animation_9_6(); // Game ending - John uses the cross on Drascula and reads BJ's letter + void animation_19_6(); // Someone pops up from behind a door when trying to open it void update_1_pre(); void update_2(); @@ -778,7 +775,7 @@ private: RoomUpdate *_roomPreUpdates, *_roomUpdates; RoomTalkAction *_roomActions; TalkSequenceCommand *_talkSequences; - char _saveNames[10][23]; + Common::String _saveNames[10]; char **loadTexts(Common::File &in); void freeTexts(char **ptr); diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp index 590561f0bd..3bdf724670 100644 --- a/engines/drascula/graphics.cpp +++ b/engines/drascula/graphics.cpp @@ -668,7 +668,7 @@ bool DrasculaEngine::animate(const char *animationFile, int FPS) { } delete stream; - return ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE)); + return ((term_int == 1) || (getScan() == Common::KEYCODE_ESCAPE) || shouldQuit()); } } // End of namespace Drascula diff --git a/engines/drascula/interface.cpp b/engines/drascula/interface.cpp index 4b8db63bb7..b116562e7d 100644 --- a/engines/drascula/interface.cpp +++ b/engines/drascula/interface.cpp @@ -153,52 +153,6 @@ void DrasculaEngine::clearMenu() { } } -void DrasculaEngine::enterName() { - Common::KeyCode key; - flushKeyBuffer(); - int v = 0, h = 0; - char select2[23]; - strcpy(select2, " "); - while (!shouldQuit()) { - select2[v] = '-'; - copyBackground(115, 14, 115, 14, 176, 9, bgSurface, screenSurface); - print_abc(select2, 117, 15); - updateScreen(); - - key = getScan(); - - if (key != 0) { - if (key >= 0 && key <= 0xFF && isAlpha(key)) - select2[v] = tolower(key); - else if ((key >= Common::KEYCODE_0 && key <= Common::KEYCODE_9) || key == Common::KEYCODE_SPACE) - select2[v] = key; - else if (key == Common::KEYCODE_ESCAPE) - break; - else if (key == Common::KEYCODE_RETURN) { - select2[v] = '\0'; - h = 1; - break; - } else if (key == Common::KEYCODE_BACKSPACE) - select2[v] = '\0'; - else - v--; - - if (key == Common::KEYCODE_BACKSPACE) - v--; - else - v++; - } - if (v == 22) - v = 21; - else if (v == -1) - v = 0; - } - if (h == 1) { - strcpy(select, select2); - selectionMade = 1; - } -} - bool DrasculaEngine::checkMenuFlags() { int n = whichObject(); if (n != 0) { diff --git a/engines/drascula/rooms.cpp b/engines/drascula/rooms.cpp index 9f725b6d76..ffac20acc8 100644 --- a/engines/drascula/rooms.cpp +++ b/engines/drascula/rooms.cpp @@ -374,16 +374,16 @@ bool DrasculaEngine::room_8(int fl) { } bool DrasculaEngine::room_9(int fl) { - if (pickedObject == kVerbTalk && fl == 51 && flags[4] == 0) + // Talking with the blind man + if (pickedObject == kVerbTalk && fl == 51) { animation_4_2(); - else if (pickedObject == kVerbTalk && fl == 51 && flags[4] == 1) - animation_33_2(); - else if (pickedObject == 7 && fl == 51) { + } else if (pickedObject == 7 && fl == 51) { animation_6_2(); removeObject(kItemMoney); - pickObject(14);} - else + pickObject(14); + } else { hasAnswer = 0; + } return true; } @@ -837,9 +837,9 @@ bool DrasculaEngine::room_35(int fl) { } bool DrasculaEngine::room_49(int fl) { - if (pickedObject == kVerbTalk && fl ==51) + if (pickedObject == kVerbTalk && fl == 51) converse(9); - else if ((pickedObject == 8 && fl == 51) || (pickedObject == 8 && fl == 203)) + else if (pickedObject == 8 && (fl == 51 || fl == 203)) animation_5_5(); else hasAnswer = 0; @@ -852,7 +852,13 @@ bool DrasculaEngine::room_53(int fl) { pickObject(16); visible[3] = 0; } else if (pickedObject == kVerbMove && fl == 123) { - animation_11_5(); + flags[9] = 1; + if (flags[2] == 1 && flags[3] == 1 && flags[4] == 1) { + animation_12_5(); + } else { + flags[9] = 0; + talk(33); + } } else if (pickedObject == 12 && fl == 52) { flags[3] = 1; talk(401); @@ -1649,7 +1655,7 @@ bool DrasculaEngine::room(int rN, int fl) { } } - // We did not find any parser, let default one work + // We did not find any parser, let the default one work hasAnswer = 0; } diff --git a/engines/drascula/saveload.cpp b/engines/drascula/saveload.cpp index 35e3821dc4..ba4148fb76 100644 --- a/engines/drascula/saveload.cpp +++ b/engines/drascula/saveload.cpp @@ -21,218 +21,270 @@ */ #include "common/textconsole.h" +#include "common/translation.h" + +#include "engines/savestate.h" +#include "graphics/thumbnail.h" +#include "gui/message.h" +#include "gui/saveload.h" #include "drascula/drascula.h" namespace Drascula { -/** - * Loads the save names from the EPA index file. - * - * TODO: We should move the save names in their respective save files and get - * rid of this completely. A good example is the sword1 engine, which also used - * to have an index file for its saves, that has been removed. - * sword1 contains code that converts the old index-based saves into the new - * format without the index file, so we could apply this idea to drascula as - * well. - */ -void DrasculaEngine::loadSaveNames() { - Common::InSaveFile *sav; - Common::String fileEpa = Common::String::format("%s.epa", _targetName.c_str()); - - // Create and initialize the index file, if it doesn't exist - if (!(sav = _saveFileMan->openForLoading(fileEpa))) { - Common::OutSaveFile *epa; - if (!(epa = _saveFileMan->openForSaving(fileEpa))) - error("Can't open %s file", fileEpa.c_str()); - for (int n = 0; n < NUM_SAVES; n++) - epa->writeString("*\n"); - epa->finalize(); - delete epa; - if (!(sav = _saveFileMan->openForLoading(fileEpa))) { - error("Can't open %s file", fileEpa.c_str()); - } +#define MAGIC_HEADER 0xD6A55A57 // (D)rascula (GA)me (S)cummVM (SA)ve (ST)ate +#define SAVEGAME_VERSION 1 + +void DrasculaEngine::checkForOldSaveGames() { + Common::String indexFileName = Common::String::format("%s.epa", _targetName.c_str()); + Common::InSaveFile *indexFile = _saveFileMan->openForLoading(indexFileName); + + // Check for the existence of an old index file + if (!indexFile) { + delete indexFile; + return; } - // Load the index file - for (int n = 0; n < NUM_SAVES; n++) { - strncpy(_saveNames[n], sav->readLine().c_str(), 23); - _saveNames[n][22] = '\0'; // make sure the savegame name is 0-terminated + GUI::MessageDialog dialog0( + _("ScummVM found that you have old savefiles for Drascula that should be converted.\n" + "The old save game format is no longer supported, so you will not be able to load your games if you don't convert them.\n\n" + "Press OK to convert them now, otherwise you will be asked again the next time you start the game.\n"), _("OK"), _("Cancel")); + + int choice = dialog0.runModal(); + if (choice == GUI::kMessageCancel) + return; + + // Convert every save slot we find in the index file to the new format + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::String pattern = Common::String::format("%s??", _targetName.c_str()); + + // Get list of savefiles for target game + Common::StringArray filenames = saveFileMan->listSavefiles(pattern); + Common::Array<int> slots; + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + // Obtain the last 2 digits of the filename, since they correspond to the save slot + int slotNum = atoi(file->c_str() + file->size() - 2); + + // Ensure save slot is within valid range + if (slotNum >= 1 && slotNum <= 10) { + slots.push_back(slotNum); + } } - delete sav; -} -/** - * Saves the save names into the EPA index file. - * - * TODO: We should move the save names in their respective save files and get - * rid of this completely. A good example is the sword1 engine, which also used - * to have an index file for its saves, that has been removed. - * sword1 contains code that converts the old index-based saves into the new - * format without the index file, so we could apply this idea to drascula as - * well. - */ -void DrasculaEngine::saveSaveNames() { - Common::OutSaveFile *tsav; - Common::String fileEpa = Common::String::format("%s.epa", _targetName.c_str()); + // Sort save slot ids + Common::sort<int>(slots.begin(), slots.end()); - if (!(tsav = _saveFileMan->openForSaving(fileEpa))) { - error("Can't open %s file", fileEpa.c_str()); - } - for (int n = 0; n < NUM_SAVES; n++) { - tsav->writeString(_saveNames[n]); - tsav->writeString("\n"); + // Get savegame names from index + Common::String saveDesc; + + int line = 1; + for (uint i = 0; i < slots.size(); i++) { + // Ignore lines corresponding to unused saveslots + for (; line < slots[i]; line++) + indexFile->readLine(); + + // Copy the name in the line corresponding to the save slot + saveDesc = indexFile->readLine(); + + // Handle cases where the save directory and save index are detectably out of sync + if (saveDesc == "*") + saveDesc = "No name specified."; + + // Increment line number to keep it in sync with slot number + line++; + + // Convert savegame + convertSaveGame(slots[i], saveDesc); } - tsav->finalize(); - delete tsav; -} -bool DrasculaEngine::saveLoadScreen() { - Common::String file; - int n, n2, num_sav = 0, y = 27; + delete indexFile; - clearRoom(); + // Remove index file + _saveFileMan->removeSavefile(indexFileName); +} - loadSaveNames(); +SaveStateDescriptor loadMetaData(Common::ReadStream *s, int slot, bool setPlayTime) { + uint32 sig = s->readUint32BE(); + byte version = s->readByte(); - loadPic("savescr.alg", bgSurface, HALF_PAL); + SaveStateDescriptor desc(-1, ""); // init to an invalid save slot - color_abc(kColorLightGreen); + if (sig != MAGIC_HEADER || version > SAVEGAME_VERSION) + return desc; - select[0] = 0; + // Save is valid, set its slot number + desc.setSaveSlot(slot); - _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); - setCursor(kCursorCrosshair); + Common::String name; + byte size = s->readByte(); + for (int i = 0; i < size; ++i) + name += s->readByte(); + desc.setDescription(name); - while (!shouldQuit()) { - y = 27; - copyBackground(); - for (n = 0; n < NUM_SAVES; n++) { - print_abc(_saveNames[n], 116, y); - y = y + 9; - } - print_abc(select, 117, 15); - updateScreen(); - y = 27; + uint32 saveDate = s->readUint32LE(); + int day = (saveDate >> 24) & 0xFF; + int month = (saveDate >> 16) & 0xFF; + int year = saveDate & 0xFFFF; + desc.setSaveDate(year, month, day); - updateEvents(); + uint16 saveTime = s->readUint16LE(); + int hour = (saveTime >> 8) & 0xFF; + int minutes = saveTime & 0xFF; + desc.setSaveTime(hour, minutes); - if (leftMouseButton == 1) { - delay(50); - for (n = 0; n < NUM_SAVES; n++) { - if (mouseX > 115 && mouseY > y + (9 * n) && mouseX < 115 + 175 && mouseY < y + 10 + (9 * n)) { - strcpy(select, _saveNames[n]); - - if (strcmp(select, "*") != 0) - selectionMade = 1; - else { - enterName(); - strcpy(_saveNames[n], select); - if (selectionMade == 1) { - file = Common::String::format("%s%02d", _targetName.c_str(), n + 1); - saveGame(file.c_str()); - saveSaveNames(); - } - } + uint32 playTime = s->readUint32LE(); + desc.setPlayTime(playTime * 1000); + if (setPlayTime) + g_engine->setTotalPlayTime(playTime * 1000); - print_abc(select, 117, 15); - y = 27; - for (n2 = 0; n2 < NUM_SAVES; n2++) { - print_abc(_saveNames[n2], 116, y); - y = y + 9; - } - if (selectionMade == 1) { - file = Common::String::format("%s%02d", _targetName.c_str(), n + 1); - } - num_sav = n; - } - } + return desc; +} - if (mouseX > 117 && mouseY > 15 && mouseX < 295 && mouseY < 24 && selectionMade == 1) { - enterName(); - strcpy(_saveNames[num_sav], select); - print_abc(select, 117, 15); - y = 27; - for (n2 = 0; n2 < NUM_SAVES; n2++) { - print_abc(_saveNames[n2], 116, y); - y = y + 9; - } +void saveMetaData(Common::WriteStream *s, Common::String &desc) { + TimeDate curTime; + g_system->getTimeAndDate(curTime); + + uint32 saveDate = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF); + uint16 saveTime = ((curTime.tm_hour & 0xFF) << 8) | ((curTime.tm_min) & 0xFF); + uint32 playTime = g_engine->getTotalPlayTime() / 1000; + + s->writeUint32BE(MAGIC_HEADER); + s->writeByte(SAVEGAME_VERSION); + s->writeByte(desc.size()); + s->writeString(desc); + s->writeUint32LE(saveDate); + s->writeUint16LE(saveTime); + s->writeUint32LE(playTime); +} - if (selectionMade == 1) { - file = Common::String::format("%s%02d", _targetName.c_str(), n + 1); - saveGame(file.c_str()); - saveSaveNames(); - } - } +void DrasculaEngine::convertSaveGame(int slot, Common::String &desc) { + Common::String oldFileName = Common::String::format("%s%02d", _targetName.c_str(), slot); + Common::String newFileName = Common::String::format("%s.%03d", _targetName.c_str(), slot); + Common::InSaveFile *oldFile = _saveFileMan->openForLoading(oldFileName); + if (!oldFile) + error("Can't open %s", oldFileName.c_str()); + Common::OutSaveFile *newFile = _saveFileMan->openForSaving(newFileName); + if (!newFile) + error("Can't open %s", newFileName.c_str()); + + // Read data from old file + int32 dataSize = oldFile->size(); + byte *buffer = new byte[dataSize]; + oldFile->read(buffer, dataSize); + + // First, write the appropriate meta data in the new file + saveMetaData(newFile, desc); + Graphics::saveThumbnail(*newFile); // basically, at this point this will capture a black screen + + // And then attach the actual save data + newFile->write(buffer, dataSize); + newFile->finalize(); + if (newFile->err()) + warning("Can't write file '%s'. (Disk full?)", newFileName.c_str()); + + delete[] buffer; + delete newFile; + delete oldFile; + + // Remove old save file + _saveFileMan->removeSavefile(oldFileName); +} - if (mouseX > 125 && mouseY > 123 && mouseX < 199 && mouseY < 149 && selectionMade == 1) { - if (!loadGame(file.c_str())) { - _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); - return false; - } - break; - } else if (mouseX > 208 && mouseY > 123 && mouseX < 282 && mouseY < 149 && selectionMade == 1) { - saveGame(file.c_str()); - saveSaveNames(); - } else if (mouseX > 168 && mouseY > 154 && mouseX < 242 && mouseY < 180) - break; - else if (selectionMade == 0) { - print_abc("Please select a slot", 117, 15); - } - updateScreen(); - delay(200); +/** + * Loads the first 10 save names, to be used in Drascula's save/load screen + */ +void DrasculaEngine::loadSaveNames() { + Common::String saveFileName; + Common::InSaveFile *in; + + for (int n = 0; n < NUM_SAVES; n++) { + saveFileName = Common::String::format("%s.%03d", _targetName.c_str(), n + 1); + if ((in = _saveFileMan->openForLoading(saveFileName))) { + SaveStateDescriptor desc = loadMetaData(in, n + 1, false); + _saveNames[n] = desc.getDescription(); + delete in; } - y = 26; + } +} + +void DrasculaEngine::saveGame(int slot, Common::String &desc) { + Common::OutSaveFile *out; + int l; - delay(5); + Common::String saveFileName = Common::String::format("%s.%03d", _targetName.c_str(), slot); + if (!(out = _saveFileMan->openForSaving(saveFileName))) { + error("Unable to open the file"); } - selectVerb(kVerbNone); + saveMetaData(out, desc); + Graphics::saveThumbnail(*out); - clearRoom(); - loadPic(roomNumber, bgSurface, HALF_PAL); - selectionMade = 0; + // Actual save data follows + out->writeSint32LE(currentChapter); + out->write(currentData, 20); + out->writeSint32LE(curX); + out->writeSint32LE(curY); + out->writeSint32LE(trackProtagonist); - _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); + for (l = 1; l < ARRAYSIZE(inventoryObjects); l++) { + out->writeSint32LE(inventoryObjects[l]); + } - return true; + for (l = 0; l < NUM_FLAGS; l++) { + out->writeSint32LE(flags[l]); + } + + out->writeSint32LE(takeObject); + out->writeSint32LE(pickedObject); + + out->finalize(); + if (out->err()) + warning("Can't write file '%s'. (Disk full?)", saveFileName.c_str()); + + delete out; } -bool DrasculaEngine::loadGame(const char *gameName) { +bool DrasculaEngine::loadGame(int slot) { int l, savedChapter, roomNum = 0; - Common::InSaveFile *sav; + Common::InSaveFile *in; previousMusic = roomMusic; _menuScreen = false; if (currentChapter != 1) clearRoom(); - if (!(sav = _saveFileMan->openForLoading(gameName))) { - error("missing savegame file"); + Common::String saveFileName = Common::String::format("%s.%03d", _targetName.c_str(), slot); + if (!(in = _saveFileMan->openForLoading(saveFileName))) { + error("missing savegame file %s", saveFileName.c_str()); } - savedChapter = sav->readSint32LE(); + loadMetaData(in, slot, true); + Graphics::skipThumbnail(*in); + + savedChapter = in->readSint32LE(); if (savedChapter != currentChapter) { - strcpy(saveName, gameName); + _currentSaveSlot = slot; currentChapter = savedChapter - 1; loadedDifferentChapter = 1; + delete in; return false; } - sav->read(currentData, 20); - curX = sav->readSint32LE(); - curY = sav->readSint32LE(); - trackProtagonist = sav->readSint32LE(); + + in->read(currentData, 20); + curX = in->readSint32LE(); + curY = in->readSint32LE(); + trackProtagonist = in->readSint32LE(); for (l = 1; l < ARRAYSIZE(inventoryObjects); l++) { - inventoryObjects[l] = sav->readSint32LE(); + inventoryObjects[l] = in->readSint32LE(); } for (l = 0; l < NUM_FLAGS; l++) { - flags[l] = sav->readSint32LE(); + flags[l] = in->readSint32LE(); } - takeObject = sav->readSint32LE(); - pickedObject = sav->readSint32LE(); + takeObject = in->readSint32LE(); + pickedObject = in->readSint32LE(); loadedDifferentChapter = 0; if (!sscanf(currentData, "%d.ald", &roomNum)) { error("Bad save format"); @@ -243,35 +295,158 @@ bool DrasculaEngine::loadGame(const char *gameName) { return true; } -void DrasculaEngine::saveGame(const char *gameName) { - Common::OutSaveFile *out; - int l; +Common::String DrasculaEngine::enterName(Common::String &selectedName) { + Common::KeyCode key; + Common::String inputLine = selectedName; - if (!(out = _saveFileMan->openForSaving(gameName))) { - error("Unable to open the file"); + flushKeyBuffer(); + _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); + + while (!shouldQuit()) { + copyBackground(115, 14, 115, 14, 176, 9, bgSurface, screenSurface); + print_abc((inputLine + "-").c_str(), 117, 15); + updateScreen(); + + key = getScan(); + + if (key != 0) { + if (key >= 0 && key <= 0xFF && isAlpha(key)) { + inputLine += tolower(key); + } else if ((key >= Common::KEYCODE_0 && key <= Common::KEYCODE_9) || key == Common::KEYCODE_SPACE) { + inputLine += key; + } else if (key == Common::KEYCODE_ESCAPE) { + inputLine.clear(); + break; + } else if (key == Common::KEYCODE_RETURN) { + break; + } else if (key == Common::KEYCODE_BACKSPACE) { + inputLine.deleteLastChar(); + } + } } - out->writeSint32LE(currentChapter); - out->write(currentData, 20); - out->writeSint32LE(curX); - out->writeSint32LE(curY); - out->writeSint32LE(trackProtagonist); - for (l = 1; l < ARRAYSIZE(inventoryObjects); l++) { - out->writeSint32LE(inventoryObjects[l]); + _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); + return inputLine; +} + +bool DrasculaEngine::scummVMSaveLoadDialog(bool isSave) { + GUI::SaveLoadChooser *dialog; + Common::String desc; + int slot; + + if (isSave) { + dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); + + slot = dialog->runModalWithCurrentTarget(); + desc = dialog->getResultString(); + + if (desc.empty()) { + // create our own description for the saved game, the user didnt enter it + desc = dialog->createDefaultSaveDescription(slot); + } + + if (desc.size() > 28) + desc = Common::String(desc.c_str(), 28); + } else { + dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); + slot = dialog->runModalWithCurrentTarget(); } - for (l = 0; l < NUM_FLAGS; l++) { - out->writeSint32LE(flags[l]); + delete dialog; + + if (slot < 0) + return true; + + if (isSave) { + saveGame(slot, desc); + return true; + } else { + return loadGame(slot); } +} - out->writeSint32LE(takeObject); - out->writeSint32LE(pickedObject); +bool DrasculaEngine::saveLoadScreen() { + int n, selectedSlot = 0; + Common::String selectedName; - out->finalize(); - if (out->err()) - warning("Can't write file '%s'. (Disk full?)", gameName); + clearRoom(); + loadPic("savescr.alg", bgSurface, HALF_PAL); + color_abc(kColorLightGreen); + setCursor(kCursorCrosshair); + loadSaveNames(); - delete out; + while (!shouldQuit()) { + copyBackground(); + for (n = 0; n < NUM_SAVES; n++) { + print_abc(_saveNames[n].c_str(), 116, 27 + 9 * n); + } + print_abc(selectedName.c_str(), 117, 15); + + updateScreen(); + updateEvents(); + + if (leftMouseButton == 1) { + // Check if the user has clicked on a save slot + for (n = 0; n < NUM_SAVES; n++) { + if (mouseX > 115 && mouseY > 27 + (9 * n) && mouseX < 115 + 175 && mouseY < 27 + 10 + (9 * n)) { + selectedSlot = n; + selectedName = _saveNames[selectedSlot]; + if (selectedName.empty()) { + selectedName = enterName(selectedName); + if (!selectedName.empty()) + _saveNames[selectedSlot] = selectedName; // update save name + } + break; + } + } + + // Check if the user has clicked in the text area above the save slots + if (mouseX > 117 && mouseY > 15 && mouseX < 295 && mouseY < 24 && !selectedName.empty()) { + selectedName = enterName(selectedName); + if (!selectedName.empty()) + _saveNames[selectedSlot] = selectedName; // update save name + } + + // Check if the user has clicked a button + if (mouseX > 208 && mouseY > 123 && mouseX < 282 && mouseY < 149) { + // "Save" button + if (selectedName.empty()) { + print_abc("Please select a slot", 117, 15); + updateScreen(); + delay(200); + } else { + selectVerb(kVerbNone); + clearRoom(); + loadPic(roomNumber, bgSurface, HALF_PAL); + updateRoom(); + updateScreen(); + + saveGame(selectedSlot + 1, _saveNames[selectedSlot]); + return true; + } + } else if (mouseX > 125 && mouseY > 123 && mouseX < 199 && mouseY < 149) { + // "Load" button + if (selectedName.empty()) { + print_abc("Please select a slot", 117, 15); + updateScreen(); + delay(200); + } else { + return loadGame(selectedSlot + 1); + } + } else if (mouseX > 168 && mouseY > 154 && mouseX < 242 && mouseY < 180) { + // "Play" button + break; + } + } // if (leftMouseButton == 1) + + leftMouseButton = 0; + delay(10); + } + + selectVerb(kVerbNone); + clearRoom(); + loadPic(roomNumber, bgSurface, HALF_PAL); + return true; } } // End of namespace Drascula diff --git a/engines/groovie/detection.cpp b/engines/groovie/detection.cpp index e06dace0d7..65452f5cf3 100644 --- a/engines/groovie/detection.cpp +++ b/engines/groovie/detection.cpp @@ -25,9 +25,12 @@ #include "groovie/saveload.h" #include "common/system.h" +#include "common/translation.h" namespace Groovie { +#define GAMEOPTION_T7G_FAST_MOVIE_SPEED GUIO_GAMEOPTIONS1 + static const PlainGameDescriptor groovieGames[] = { // Games {"t7g", "The 7th Guest"}, @@ -52,7 +55,7 @@ static const GroovieGameDescription gameDescriptions[] = { "t7g", "", AD_ENTRY1s("script.grv", "d1b8033b40aa67c076039881eccce90d", 16659), Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT) + GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT, GAMEOPTION_T7G_FAST_MOVIE_SPEED) }, kGroovieT7G, 0 }, @@ -63,7 +66,7 @@ static const GroovieGameDescription gameDescriptions[] = { "t7g", "", AD_ENTRY1s("T7GMac", "acdc4a58dd3f007f65e99b99d78e0bce", 1814029), Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, - GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT) + GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT, GAMEOPTION_T7G_FAST_MOVIE_SPEED) }, kGroovieT7G, 0 }, @@ -79,7 +82,7 @@ static const GroovieGameDescription gameDescriptions[] = { "t7g", "", AD_ENTRY1s("T7GMac", "6bdee8d0f9eef6d58d02fcd7deec3fb2", 1830783), Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, - GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT) + GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT, GAMEOPTION_T7G_FAST_MOVIE_SPEED) }, kGroovieT7G, 0 }, @@ -90,7 +93,7 @@ static const GroovieGameDescription gameDescriptions[] = { "t7g", "", AD_ENTRY1s("T7GMac", "0d595d4b44ae1814082938d051e5174e", 1830783), Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK, - GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT) + GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT, GAMEOPTION_T7G_FAST_MOVIE_SPEED) }, kGroovieT7G, 0 }, @@ -106,7 +109,7 @@ static const GroovieGameDescription gameDescriptions[] = { { NULL, 0, NULL, 0} }, Common::RU_RUS, Common::kPlatformPC, ADGF_NO_FLAGS, - GUIO4(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT) + GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_NOASPECT, GAMEOPTION_T7G_FAST_MOVIE_SPEED) }, kGroovieT7G, 0 }, @@ -120,7 +123,7 @@ static const GroovieGameDescription gameDescriptions[] = { { NULL, 0, NULL, 0} }, Common::EN_ANY, Common::kPlatformIOS, ADGF_NO_FLAGS, - GUIO2(GUIO_NOMIDI, GUIO_NOASPECT) + GUIO3(GUIO_NOMIDI, GUIO_NOASPECT, GAMEOPTION_T7G_FAST_MOVIE_SPEED) }, kGroovieT7G, 0 }, @@ -302,9 +305,23 @@ static const char *directoryGlobs[] = { 0 }; +static const ADExtraGuiOptionsMap optionsList[] = { + { + GAMEOPTION_T7G_FAST_MOVIE_SPEED, + { + _s("Fast movie speed"), + _s("Play movies at an increased speed"), + "fast_movie_speed", + false + } + }, + + AD_EXTRA_GUI_OPTIONS_TERMINATOR +}; + class GroovieMetaEngine : public AdvancedMetaEngine { public: - GroovieMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(GroovieGameDescription), groovieGames) { + GroovieMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(GroovieGameDescription), groovieGames, optionsList) { _singleid = "groovie"; // Use kADFlagUseExtraAsHint in order to distinguish the 11th hour from diff --git a/engines/groovie/groovie.cpp b/engines/groovie/groovie.cpp index 16358bfa28..5ade442742 100644 --- a/engines/groovie/groovie.cpp +++ b/engines/groovie/groovie.cpp @@ -60,13 +60,8 @@ GroovieEngine::GroovieEngine(OSystem *syst, const GroovieGameDescription *gd) : SearchMan.addSubDirectoryMatching(gameDataDir, "MIDI"); _modeSpeed = kGroovieSpeedNormal; - if (ConfMan.hasKey("t7g_speed")) { - Common::String speed = ConfMan.get("t7g_speed"); - if (speed.equals("im_an_ios")) - _modeSpeed = kGroovieSpeediOS; - else if (speed.equals("tweaked")) - _modeSpeed = kGroovieSpeedTweaked; - } + if (ConfMan.hasKey("fast_movie_speed") && ConfMan.getBool("fast_movie_speed")) + _modeSpeed = kGroovieSpeedFast; // Initialize the custom debug levels DebugMan.addDebugChannel(kGroovieDebugAll, "All", "Debug everything"); diff --git a/engines/groovie/groovie.h b/engines/groovie/groovie.h index c66e54b500..79abc13b1c 100644 --- a/engines/groovie/groovie.h +++ b/engines/groovie/groovie.h @@ -74,15 +74,14 @@ enum DebugLevels { /** * This enum reflects the available movie speed settings: - * - Normal: both movies and 'teeth' animations are played at a normal speed - * - Tweaked: movies are played at a normal speed, 'teeth' animations at - increased speed - * - iOS: both movies and 'teeth' animations are played at increased speed + * - Normal: play videos at a normal speed + * - Fast: play videos with audio at a fast speed. Videos without audio, + * like teeth animations, are played at their regular speed to avoid + * audio sync issues */ enum GameSpeed { kGroovieSpeedNormal, - kGroovieSpeediOS, - kGroovieSpeedTweaked + kGroovieSpeedFast }; struct GroovieGameDescription; diff --git a/engines/groovie/vdx.cpp b/engines/groovie/vdx.cpp index b3fcf462b2..8786e75488 100644 --- a/engines/groovie/vdx.cpp +++ b/engines/groovie/vdx.cpp @@ -88,7 +88,7 @@ uint16 VDXPlayer::loadInternal() { // Enable highspeed if we're not obeying fps, and not marked as special // This will be disabled in chunk audio if we're actually an audio vdx - if ( _vm->_modeSpeed == kGroovieSpeediOS || (_vm->_modeSpeed == kGroovieSpeedTweaked && ((_flags & (1 << 15)) == 0))) + if (_vm->_modeSpeed == kGroovieSpeedFast && ((_flags & (1 << 15)) == 0)) setOverrideSpeed(true); if (_flagOnePrev && !_flagOne && !_flagEight) { diff --git a/engines/mohawk/myst_stacks/mechanical.cpp b/engines/mohawk/myst_stacks/mechanical.cpp index ce6f902851..43e9bcfed5 100644 --- a/engines/mohawk/myst_stacks/mechanical.cpp +++ b/engines/mohawk/myst_stacks/mechanical.cpp @@ -837,7 +837,7 @@ void Mechanical::fortressRotation_run() { newRate = CLIP<double>(newRate, -2.5, 2.5); - _vm->_video->setVideoRate(gears, Common::Rational(newRate * 1000.0, 1000)); + _vm->_video->setVideoRate(gears, Common::Rational((int)(newRate * 1000.0), 1000)); _gearsWereRunning = true; } else if (_gearsWereRunning) { @@ -968,7 +968,7 @@ void Mechanical::fortressSimulation_run() { newRate = CLIP<double>(newRate, -2.5, 2.5); - _vm->_video->setVideoRate(holo, Common::Rational(newRate * 1000.0, 1000)); + _vm->_video->setVideoRate(holo, Common::Rational((int)(newRate * 1000.0), 1000)); _gearsWereRunning = true; } else if (_gearsWereRunning) { diff --git a/engines/sci/decompressor.cpp b/engines/sci/decompressor.cpp index 82af6eca43..306825008d 100644 --- a/engines/sci/decompressor.cpp +++ b/engines/sci/decompressor.cpp @@ -590,6 +590,8 @@ void DecompressorLZW::reorderView(byte *src, byte *dest) { if (celindex < cel_total) { warning("View decompression generated too few (%d / %d) headers", celindex, cel_total); + free(cc_pos); + free(cc_lengths); return; } diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp index 8b3afeef99..1d30f709dc 100644 --- a/engines/sci/engine/kgraphics32.cpp +++ b/engines/sci/engine/kgraphics32.cpp @@ -323,19 +323,29 @@ reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) { uint16 op = argv[0].toUint16(); switch (op) { case 0: // Init + // TODO: Init reads the nsLeft, nsTop, nsRight, nsBottom, + // borderColor, fore, back, mode, font, plane selectors + // from the window in argv[1]. g_sci->_gfxFrameout->initScrollText(argv[2].toUint16()); // maxItems g_sci->_gfxFrameout->clearScrollTexts(); return argv[1]; // kWindow case 1: // Show message, called by ScrollableWindow::addString case 14: // Modify message, called by ScrollableWindow::modifyString - // 5 or 6 parameters - // Seems to be called with 5 parameters when the narrator speaks, and - // with 6 when Roger speaks + // TODO: The parameters in Modify are shifted by one: the first + // argument is the handle of the text to modify. The others + // are as Add. { Common::String text = s->_segMan->getString(argv[2]); - uint16 x = 0;//argv[3].toUint16(); // TODO: can't be x (values are all wrong) - uint16 y = 0;//argv[4].toUint16(); // TODO: can't be y (values are all wrong) - // TODO: argv[5] is an optional unknown parameter (an integer set to 0) + uint16 x = 0; + uint16 y = 0; + // TODO: argv[3] is font + // TODO: argv[4] is color + // TODO: argv[5] is alignment (0 = left, 1 = center, 2 = right) + // font,color,alignment may also be -1. (Maybe same as previous?) + // TODO: argv[6] is an optional bool, defaulting to true if not present. + // If true, the old contents are scrolled out of view. + // TODO: Return a handle of the inserted text. (Used for modify/insert) + // This handle looks like it should also be usable by kString. g_sci->_gfxFrameout->addScrollTextEntry(text, kWindow, x, y, (op == 14)); } break; @@ -363,22 +373,27 @@ reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) { g_sci->_gfxFrameout->lastScrollText(); break; case 9: // Resize, called by ScrollableWindow::resize and ScrollerWindow::resize - // TODO + // TODO: This reads the nsLeft, nsTop, nsRight, nsBottom + // selectors from the SCI object passed in argv[2]. kStub(s, argc, argv); break; case 10: // Where, called by ScrollableWindow::where - // TODO - // argv[2] is an unknown integer + // TODO: + // Gives the current relative scroll location as a fraction + // with argv[2] as the denominator. (Return value is the numerator.) // Silenced the warnings because of the high amount of console spam //kStub(s, argc, argv); break; case 11: // Go, called by ScrollableWindow::scrollTo - // 2 extra parameters here - // TODO + // TODO: + // Two arguments provide a fraction: argv[2] is num., argv[3] is denom. + // Scrolls to the relative location given by the fraction. kStub(s, argc, argv); break; case 12: // Insert, called by ScrollableWindow::insertString - // 3 extra parameters here + // 5 extra parameters here: + // handle of insert location (new string takes that position). + // text, font, color, alignment // TODO kStub(s, argc, argv); break; diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index ffff329036..50ff0b3988 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -3609,7 +3609,7 @@ void Gdi::unkDecode9(byte *dst, int dstPitch, const byte *src, int height) const int i; uint buffer = 0, mask = 128; int h = height; - i = run = 0; + run = 0; int x = 8; for (;;) { diff --git a/engines/tinsel/saveload.cpp b/engines/tinsel/saveload.cpp index 2ef92d853f..acff196916 100644 --- a/engines/tinsel/saveload.cpp +++ b/engines/tinsel/saveload.cpp @@ -540,8 +540,8 @@ static void SaveFailure(Common::OutSaveFile *f) { if (f) { delete f; _vm->getSaveFileMan()->removeSavefile(g_SaveSceneName); - g_SaveSceneName = NULL; // Invalidate save name } + g_SaveSceneName = NULL; // Invalidate save name GUI::MessageDialog dialog(_("Failed to save game state to file.")); dialog.runModal(); } diff --git a/engines/toltecs/console.cpp b/engines/toltecs/console.cpp new file mode 100644 index 0000000000..f3394909ed --- /dev/null +++ b/engines/toltecs/console.cpp @@ -0,0 +1,79 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "gui/debugger.h" + +#include "toltecs/console.h" +//#include "toltecs/palette.h" +#include "toltecs/resource.h" +//#include "toltecs/sound.h" +#include "toltecs/toltecs.h" + +namespace Toltecs { + +Console::Console(ToltecsEngine *vm) : GUI::Debugger(), _vm(vm) { + DCmd_Register("room", WRAP_METHOD(Console, Cmd_Room)); + DCmd_Register("dump", WRAP_METHOD(Console, Cmd_Dump)); +} + +Console::~Console() { +} + +bool Console::Cmd_Room(int argc, const char **argv) { + if (argc < 2) { + DebugPrintf("Current room number is %d\n", _vm->_sceneResIndex); +#if 0 + DebugPrintf("Calling this command with the room number changes the room\n"); + DebugPrintf("WARNING: It's a bad idea to warp to rooms with this, as the room object scripts are not loaded\n"); +#endif + return true; +#if 0 + } else { + int roomNum = atoi(argv[1]); + + // sfClearPaletteFragments + _vm->_palette->clearFragments(); + + // sfLoadScene + _vm->_sound->stopAll(); + _vm->_res->purgeCache(); + _vm->loadScene(roomNum); +#endif + } + + return false; +} + +bool Console::Cmd_Dump(int argc, const char **argv) { + if (argc < 2) { + DebugPrintf("Usage: dump <resource number>\n"); + return true; + } + + int resNum = atoi(argv[1]); + _vm->_arc->dump(resNum); + DebugPrintf("Resource %d has been dumped to disk\n", resNum); + + return true; +} + +} // End of namespace Toltecs diff --git a/engines/toltecs/console.h b/engines/toltecs/console.h new file mode 100644 index 0000000000..bcdfd0cf04 --- /dev/null +++ b/engines/toltecs/console.h @@ -0,0 +1,45 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TOLTECS_CONSOLE_H +#define TOLTECS_CONSOLE_H + +#include "gui/debugger.h" + +namespace Toltecs { + +class ToltecsEngine; + +class Console : public GUI::Debugger { +public: + Console(ToltecsEngine *vm); + virtual ~Console(void); + +private: + ToltecsEngine *_vm; + + bool Cmd_Dump(int argc, const char **argv); + bool Cmd_Room(int argc, const char **argv); +}; + +} // End of namespace Toltecs +#endif diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp index c1a57638c2..4016becb82 100644 --- a/engines/toltecs/detection.cpp +++ b/engines/toltecs/detection.cpp @@ -24,6 +24,8 @@ #include "base/plugins.h" #include "engines/advancedDetector.h" + +#include "common/translation.h" #include "common/savefile.h" #include "common/str-array.h" #include "common/system.h" @@ -97,19 +99,6 @@ static const ToltecsGameDescription gameDescriptions[] = { }, { - // 3 Skulls of the Toltecs German Demo version - { - "toltecs", - 0, - AD_ENTRY1s("WESTERN", "1c85e82712d24f1d5c1ea2a66ddd75c2", 47730038), - Common::DE_DEU, - Common::kPlatformPC, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) - }, - }, - - { // 3 Skulls of the Toltecs French version { "toltecs", @@ -149,11 +138,44 @@ static const ToltecsGameDescription gameDescriptions[] = { }, }, + { + // 3 Skulls of the Toltecs English Demo version + { + "toltecs", + 0, + AD_ENTRY1s("WESTERN", "53a0abd1c0bc5cad8ba18f0e56877705", 46241833), + Common::EN_ANY, + Common::kPlatformPC, + ADGF_DEMO, + GUIO1(GUIO_NONE) + }, + }, + + { + // 3 Skulls of the Toltecs German Demo version + { + "toltecs", + 0, + AD_ENTRY1s("WESTERN", "1c85e82712d24f1d5c1ea2a66ddd75c2", 47730038), + Common::DE_DEU, + Common::kPlatformPC, + ADGF_DEMO, + GUIO1(GUIO_NONE) + }, + }, + { AD_TABLE_END_MARKER } }; } // End of namespace Toltecs +static const ExtraGuiOption toltecsExtraGuiOption = { + _s("Use original save/load screens"), + _s("Use the original save/load screens, instead of the ScummVM ones"), + "originalsaveload", + false +}; + class ToltecsMetaEngine : public AdvancedMetaEngine { public: ToltecsMetaEngine() : AdvancedMetaEngine(Toltecs::gameDescriptions, sizeof(Toltecs::ToltecsGameDescription), toltecsGames) { @@ -170,6 +192,7 @@ public: virtual bool hasFeature(MetaEngineFeature f) const; virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const; SaveStateList listSaves(const char *target) const; virtual int getMaximumSaveSlot() const; void removeSaveState(const char *target, int slot) const; @@ -202,6 +225,12 @@ bool ToltecsMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADG return gd != 0; } +const ExtraGuiOptions ToltecsMetaEngine::getExtraGuiOptions(const Common::String &target) const { + ExtraGuiOptions options; + options.push_back(toltecsExtraGuiOption); + return options; +} + SaveStateList ToltecsMetaEngine::listSaves(const char *target) const { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Toltecs::ToltecsEngine::SaveHeader header; diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp index 6e23ff988f..b52d7dad82 100644 --- a/engines/toltecs/menu.cpp +++ b/engines/toltecs/menu.cpp @@ -22,9 +22,12 @@ */ #include "audio/mixer.h" -#include "common/savefile.h" +#include "common/savefile.h" #include "common/config-manager.h" +#include "common/translation.h" + +#include "gui/saveload.h" #include "toltecs/toltecs.h" #include "toltecs/menu.h" @@ -41,9 +44,6 @@ MenuSystem::~MenuSystem() { } int MenuSystem::run(MenuID menuId) { - - //debug("MenuSystem::run()"); - _background = new Graphics::Surface(); _background->create(640, 400, Graphics::PixelFormat::createFormatCLUT8()); @@ -62,13 +62,12 @@ int MenuSystem::run(MenuID menuId) { _needRedraw = false; - // TODO: buildColorTransTable2 _vm->_palette->buildColorTransTable(0, 16, 7); _vm->_screen->_renderQueue->clear(); // Draw the menu background and frame _vm->_screen->blastSprite(0x140 + _vm->_cameraX, 0x175 + _vm->_cameraY, 0, 1, 0x4000); - shadeRect(60, 39, 520, 246, 30, 94); + shadeRect(60, 39, 520, 247, 225, 229); memcpy(_background->pixels, _vm->_screen->_frontScreen, 640 * 400); @@ -91,7 +90,6 @@ int MenuSystem::run(MenuID menuId) { } void MenuSystem::update() { - if (_currMenuID != _newMenuID) { _currMenuID = _newMenuID; //debug("_currMenuID = %d", _currMenuID); @@ -103,16 +101,13 @@ void MenuSystem::update() { if (_needRedraw) { //_vm->_system->copyRectToScreen(_vm->_screen->_frontScreen + 39 * 640 + 60, 640, 60, 39, 520, 247); _vm->_system->copyRectToScreen(_vm->_screen->_frontScreen, 640, 0, _top, 640, 400 - _top); - //debug("redraw"); _needRedraw = false; } _vm->_system->delayMillis(5); - } void MenuSystem::handleEvents() { - Common::Event event; Common::EventManager *eventMan = _vm->_system->getEventManager(); while (eventMan->pollEvent(event)) { @@ -126,18 +121,18 @@ void MenuSystem::handleEvents() { case Common::EVENT_MOUSEMOVE: handleMouseMove(event.mouse.x, event.mouse.y); break; - case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_LBUTTONUP: handleMouseClick(event.mouse.x, event.mouse.y); break; default: break; } } - } void MenuSystem::addClickTextItem(ItemID id, int x, int y, int w, uint fontNum, const char *caption, byte defaultColor, byte activeColor) { Item item; + item.enabled = true; item.id = id; item.defaultColor = defaultColor; item.activeColor = activeColor; @@ -202,7 +197,7 @@ void MenuSystem::handleKeyDown(const Common::KeyState& kbd) { ItemID MenuSystem::findItemAt(int x, int y) { for (Common::Array<Item>::iterator iter = _items.begin(); iter != _items.end(); iter++) { - if ((*iter).rect.contains(x, y - _top)) + if ((*iter).enabled && (*iter).rect.contains(x, y - _top)) return (*iter).id; } return kItemIdNone; @@ -220,6 +215,8 @@ void MenuSystem::setItemCaption(Item *item, const char *caption) { Font font(_vm->_res->load(_vm->_screen->getFontResIndex(item->fontNum))->data); int width = font.getTextWidth((const byte*)caption); int height = font.getHeight(); + if (width & 1) + width++; item->rect = Common::Rect(item->x, item->y - height, item->x + width, item->y); if (item->w) { item->rect.translate(item->w - width / 2, 0); @@ -236,59 +233,87 @@ void MenuSystem::initMenu(MenuID menuID) { switch (menuID) { case kMenuIdMain: - drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrWhatCanIDoForYou)); - addClickTextItem(kItemIdLoad, 0, 115, 320, 0, _vm->getSysString(kStrLoad), 229, 255); - addClickTextItem(kItemIdSave, 0, 135, 320, 0, _vm->getSysString(kStrSave), 229, 255); - addClickTextItem(kItemIdToggleText, 0, 165, 320, 0, _vm->getSysString(_vm->_cfgText ? kStrTextOn : kStrTextOff), 229, 255); - addClickTextItem(kItemIdToggleVoices, 0, 185, 320, 0, _vm->getSysString(_vm->_cfgVoices ? kStrVoicesOn : kStrVoicesOff), 229, 255); - addClickTextItem(kItemIdVolumesMenu, 0, 215, 320, 0, _vm->getSysString(kStrVolume), 229, 255); - addClickTextItem(kItemIdPlay, 0, 245, 320, 0, _vm->getSysString(kStrPlay), 229, 255); - addClickTextItem(kItemIdQuit, 0, 275, 320, 0, _vm->getSysString(kStrQuit), 229, 255); + drawString(0, 75, 320, 1, 229, _vm->getSysString(kStrWhatCanIDoForYou)); + addClickTextItem(kItemIdLoad, 0, 116, 320, 0, _vm->getSysString(kStrLoad), 253, 255); + addClickTextItem(kItemIdSave, 0, 136, 320, 0, _vm->getSysString(kStrSave), 253, 255); + addClickTextItem(kItemIdToggleText, 0, 166, 320, 0, _vm->getSysString(_vm->_cfgText ? kStrTextOn : kStrTextOff), 253, 255); + addClickTextItem(kItemIdToggleVoices, 0, 186, 320, 0, _vm->getSysString(_vm->_cfgVoices ? kStrVoicesOn : kStrVoicesOff), 253, 255); + addClickTextItem(kItemIdVolumesMenu, 0, 216, 320, 0, _vm->getSysString(kStrVolume), 253, 255); + addClickTextItem(kItemIdPlay, 0, 246, 320, 0, _vm->getSysString(kStrPlay), 253, 255); + addClickTextItem(kItemIdQuit, 0, 276, 320, 0, _vm->getSysString(kStrQuit), 253, 255); break; case kMenuIdLoad: - drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrLoadGame)); - addClickTextItem(kItemIdSavegameUp, 0, 155, 545, 1, "^", 255, 253); - addClickTextItem(kItemIdSavegameDown, 0, 195, 545, 1, "\\", 255, 253); - addClickTextItem(kItemIdCancel, 0, 275, 320, 0, _vm->getSysString(kStrCancel), 255, 253); - for (int i = 1; i <= 7; i++) { - Common::String saveDesc = Common::String::format("SAVEGAME %d", i); - addClickTextItem((ItemID)(kItemIdSavegame1 + i - 1), 0, 115 + 20 * (i - 1), 300, 0, saveDesc.c_str(), 231, 234); + if (ConfMan.getBool("originalsaveload")) { + shadeRect(80, 92, 440, 141, 226, 225); + drawString(0, 75, 320, 1, 229, _vm->getSysString(kStrLoadGame)); + addClickTextItem(kItemIdSavegameUp, 0, 156, 545, 1, "^", 253, 255); + addClickTextItem(kItemIdSavegameDown, 0, 196, 545, 1, "\\", 253, 255); + addClickTextItem(kItemIdCancel, 0, 276, 320, 0, _vm->getSysString(kStrCancel), 253, 255); + for (int i = 1; i <= 7; i++) { + Common::String saveDesc = Common::String::format("SAVEGAME %d", i); + addClickTextItem((ItemID)(kItemIdSavegame1 + i - 1), 0, 116 + 20 * (i - 1), 300, 0, saveDesc.c_str(), 231, 234); + } + loadSavegamesList(); + setSavegameCaptions(true); + } else { + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); + int slot = dialog->runModalWithCurrentTarget(); + delete dialog; + + if (slot >= 0) + _vm->requestLoadgame(slot); + + _running = false; } - loadSavegamesList(); - setSavegameCaptions(); break; case kMenuIdSave: - drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrSaveGame)); - addClickTextItem(kItemIdSavegameUp, 0, 155, 545, 1, "^", 255, 253); - addClickTextItem(kItemIdSavegameDown, 0, 195, 545, 1, "\\", 255, 253); - addClickTextItem(kItemIdCancel, 0, 275, 320, 0, _vm->getSysString(kStrCancel), 255, 253); - for (int i = 1; i <= 7; i++) { - Common::String saveDesc = Common::String::format("SAVEGAME %d", i); - addClickTextItem((ItemID)(kItemIdSavegame1 + i - 1), 0, 115 + 20 * (i - 1), 300, 0, saveDesc.c_str(), 231, 234); + if (ConfMan.getBool("originalsaveload")) { + shadeRect(80, 92, 440, 141, 226, 225); + drawString(0, 75, 320, 1, 229, _vm->getSysString(kStrSaveGame)); + addClickTextItem(kItemIdSavegameUp, 0, 156, 545, 1, "^", 253, 255); + addClickTextItem(kItemIdSavegameDown, 0, 196, 545, 1, "\\", 253, 255); + addClickTextItem(kItemIdCancel, 0, 276, 320, 0, _vm->getSysString(kStrCancel), 253, 255); + for (int i = 1; i <= 7; i++) { + Common::String saveDesc = Common::String::format("SAVEGAME %d", i); + addClickTextItem((ItemID)(kItemIdSavegame1 + i - 1), 0, 116 + 20 * (i - 1), 300, 0, saveDesc.c_str(), 231, 234); + } + newSlotNum = loadSavegamesList() + 1; + _savegames.push_back(SavegameItem(newSlotNum, Common::String::format("GAME %04d", _savegames.size()))); + setSavegameCaptions(true); + } else { + GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); + int slot = dialog->runModalWithCurrentTarget(); + Common::String desc = dialog->getResultString(); + if (desc.empty()) { + // Create our own description for the saved game, the user didn't enter one + desc = dialog->createDefaultSaveDescription(slot); + } + + if (slot >= 0) + _vm->requestSavegame(slot, desc); + + _running = false; } - newSlotNum = loadSavegamesList() + 1; - _savegames.push_back(SavegameItem(newSlotNum, Common::String::format("GAME %03d", _savegames.size() + 1))); - setSavegameCaptions(); break; case kMenuIdVolumes: - drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrAdjustVolume)); - drawString(0, 130, 200, 0, 246, _vm->getSysString(kStrMaster)); - drawString(0, 155, 200, 0, 244, _vm->getSysString(kStrVoices)); - drawString(0, 180, 200, 0, 244, _vm->getSysString(kStrMusic)); - drawString(0, 205, 200, 0, 244, _vm->getSysString(kStrSoundFx)); - drawString(0, 230, 200, 0, 244, _vm->getSysString(kStrBackground)); - addClickTextItem(kItemIdDone, 0, 275, 200, 0, _vm->getSysString(kStrDone), 229, 253); - addClickTextItem(kItemIdCancel, 0, 275, 440, 0, _vm->getSysString(kStrCancel), 229, 253); - addClickTextItem(kItemIdMasterDown, 0, 130 + 25 * 0, 348, 1, "[", 229, 253); - addClickTextItem(kItemIdVoicesDown, 0, 130 + 25 * 1, 348, 1, "[", 229, 253); - addClickTextItem(kItemIdMusicDown, 0, 130 + 25 * 2, 348, 1, "[", 229, 253); - addClickTextItem(kItemIdSoundFXDown, 0, 130 + 25 * 3, 348, 1, "[", 229, 253); - addClickTextItem(kItemIdBackgroundDown, 0, 130 + 25 * 4, 348, 1, "[", 229, 253); - addClickTextItem(kItemIdMasterUp, 0, 130 + 25 * 0, 372, 1, "]", 229, 253); - addClickTextItem(kItemIdVoicesUp, 0, 130 + 25 * 1, 372, 1, "]", 229, 253); - addClickTextItem(kItemIdMusicUp, 0, 130 + 25 * 2, 372, 1, "]", 229, 253); - addClickTextItem(kItemIdSoundFXUp, 0, 130 + 25 * 3, 372, 1, "]", 229, 253); - addClickTextItem(kItemIdBackgroundUp, 0, 130 + 25 * 4, 372, 1, "]", 229, 253); + drawString(0, 75, 320, 1, 229, _vm->getSysString(kStrAdjustVolume)); + drawString(0, 131, 200, 0, 246, _vm->getSysString(kStrMaster)); + drawString(0, 156, 200, 0, 244, _vm->getSysString(kStrVoices)); + drawString(0, 181, 200, 0, 244, _vm->getSysString(kStrMusic)); + drawString(0, 206, 200, 0, 244, _vm->getSysString(kStrSoundFx)); + drawString(0, 231, 200, 0, 244, _vm->getSysString(kStrBackground)); + addClickTextItem(kItemIdDone, 0, 276, 200, 0, _vm->getSysString(kStrDone), 253, 255); + addClickTextItem(kItemIdCancel, 0, 276, 440, 0, _vm->getSysString(kStrCancel), 253, 255); + addClickTextItem(kItemIdMasterDown, 0, 131 + 25 * 0, 348, 1, "[", 243, 246); + addClickTextItem(kItemIdVoicesDown, 0, 131 + 25 * 1, 348, 1, "[", 243, 246); + addClickTextItem(kItemIdMusicDown, 0, 131 + 25 * 2, 348, 1, "[", 243, 246); + addClickTextItem(kItemIdSoundFXDown, 0, 131 + 25 * 3, 348, 1, "[", 243, 246); + addClickTextItem(kItemIdBackgroundDown, 0, 131 + 25 * 4, 348, 1, "[", 243, 246); + addClickTextItem(kItemIdMasterUp, 0, 131 + 25 * 0, 372, 1, "]", 243, 246); + addClickTextItem(kItemIdVoicesUp, 0, 131 + 25 * 1, 372, 1, "]", 243, 246); + addClickTextItem(kItemIdMusicUp, 0, 131 + 25 * 2, 372, 1, "]", 243, 246); + addClickTextItem(kItemIdSoundFXUp, 0, 131 + 25 * 3, 372, 1, "]", 243, 246); + addClickTextItem(kItemIdBackgroundUp, 0, 131 + 25 * 4, 372, 1, "]", 243, 246); drawVolumeBar(kItemIdMaster); drawVolumeBar(kItemIdVoices); drawVolumeBar(kItemIdMusic); @@ -300,9 +325,36 @@ void MenuSystem::initMenu(MenuID menuID) { } for (Common::Array<Item>::iterator iter = _items.begin(); iter != _items.end(); iter++) { - drawItem((*iter).id, false); + if ((*iter).enabled) + drawItem((*iter).id, false); } + // Check if the mouse is already over an item + _currItemID = kItemIdNone; + Common::Point mousePos = _vm->_system->getEventManager()->getMousePos(); + handleMouseMove(mousePos.x, mousePos.y); +} + +void MenuSystem::enableItem(ItemID id) { + Item *item = getItem(id); + if (item) { + item->enabled = true; + drawItem(id, false); + _currItemID = kItemIdNone; + Common::Point mousePos = _vm->_system->getEventManager()->getMousePos(); + handleMouseMove(mousePos.x, mousePos.y); + } +} + +void MenuSystem::disableItem(ItemID id) { + Item *item = getItem(id); + if (item) { + item->enabled = false; + restoreRect(item->rect.left, item->rect.top, item->rect.width(), item->rect.height()); + if (_currItemID == id) { + _currItemID = kItemIdNone; + } + } } void MenuSystem::enterItem(ItemID id) { @@ -433,14 +485,16 @@ void MenuSystem::drawString(int16 x, int16 y, int w, uint fontNum, byte color, c fontNum = _vm->_screen->getFontResIndex(fontNum); Font font(_vm->_res->load(fontNum)->data); if (w) { - x = x + w - font.getTextWidth((const byte*)text) / 2; + int width = font.getTextWidth((const byte*)text); + if (width & 1) + width++; + x = x + w - width / 2; } _vm->_screen->drawString(x, y - font.getHeight(), color, fontNum, (const byte*)text, -1, NULL, true); _needRedraw = true; } int MenuSystem::loadSavegamesList() { - int maxSlotNum = -1; _savegameListTopIndex = 0; @@ -483,17 +537,32 @@ MenuSystem::SavegameItem *MenuSystem::getSavegameItemByID(ItemID id) { return NULL; } -void MenuSystem::setSavegameCaptions() { - uint index = _savegameListTopIndex; +void MenuSystem::setSavegameCaptions(bool scrollToBottom) { + int size = _savegames.size(); + if (scrollToBottom && size > 0) { + while (_savegameListTopIndex + 7 <= size) + _savegameListTopIndex += 6; + } + int index = _savegameListTopIndex; for (int i = 1; i <= 7; i++) - setItemCaption(getItem((ItemID)(kItemIdSavegame1 + i - 1)), index < _savegames.size() ? _savegames[index++]._description.c_str() : ""); + setItemCaption(getItem((ItemID)(kItemIdSavegame1 + i - 1)), index < size ? _savegames[index++]._description.c_str() : ""); + if (_savegameListTopIndex == 0) { + disableItem(kItemIdSavegameUp); + } else { + enableItem(kItemIdSavegameUp); + } + if (_savegameListTopIndex + 7 > size) { + disableItem(kItemIdSavegameDown); + } else { + enableItem(kItemIdSavegameDown); + } } void MenuSystem::scrollSavegames(int delta) { int newPos = CLIP<int>(_savegameListTopIndex + delta, 0, _savegames.size() - 1); _savegameListTopIndex = newPos; restoreRect(80, 92, 440, 140); - setSavegameCaptions(); + setSavegameCaptions(false); for (int i = 1; i <= 7; i++) drawItem((ItemID)(kItemIdSavegame1 + i - 1), false); } @@ -574,7 +643,6 @@ void MenuSystem::drawVolumeBar(ItemID itemID) { text[volume] = 0; drawString(0, y, w, 0, 246, text); - } void MenuSystem::changeVolumeBar(ItemID itemID, int delta) { diff --git a/engines/toltecs/menu.h b/engines/toltecs/menu.h index a72205c2e5..a5eca7c8ff 100644 --- a/engines/toltecs/menu.h +++ b/engines/toltecs/menu.h @@ -84,6 +84,7 @@ public: protected: struct Item { + bool enabled; Common::Rect rect; ItemID id; Common::String caption; @@ -130,6 +131,9 @@ protected: void initMenu(MenuID menuID); + void enableItem(ItemID id); + void disableItem(ItemID id); + void enterItem(ItemID id); void leaveItem(ItemID id); void clickItem(ItemID id); @@ -141,7 +145,7 @@ protected: SavegameItem *getSavegameItemByID(ItemID id); int loadSavegamesList(); - void setSavegameCaptions(); + void setSavegameCaptions(bool scrollToBottom); void scrollSavegames(int delta); void clickSavegameItem(ItemID id); void setCfgText(bool value, bool active); diff --git a/engines/toltecs/module.mk b/engines/toltecs/module.mk index aa4a6f376b..0de1eef733 100644 --- a/engines/toltecs/module.mk +++ b/engines/toltecs/module.mk @@ -2,6 +2,7 @@ MODULE := engines/toltecs MODULE_OBJS = \ animation.o \ + console.o \ detection.o \ menu.o \ microtiles.o \ diff --git a/engines/toltecs/movie.cpp b/engines/toltecs/movie.cpp index 35accb5d93..45711ad983 100644 --- a/engines/toltecs/movie.cpp +++ b/engines/toltecs/movie.cpp @@ -45,7 +45,7 @@ enum ChunkTypes { kChunkStopSubtitles = 8 }; -MoviePlayer::MoviePlayer(ToltecsEngine *vm) : _vm(vm) { +MoviePlayer::MoviePlayer(ToltecsEngine *vm) : _vm(vm), _isPlaying(false) { } MoviePlayer::~MoviePlayer() { @@ -62,6 +62,7 @@ void MoviePlayer::playMovie(uint resIndex) { int16 savedGuiHeight = _vm->_guiHeight; byte moviePalette[768]; + _isPlaying = true; _vm->_isSaveAllowed = false; memset(moviePalette, 0, sizeof(moviePalette)); @@ -99,8 +100,9 @@ void MoviePlayer::playMovie(uint resIndex) { byte *chunkBuffer = NULL; uint32 chunkBufferSize = 0; uint32 frame = 0; + bool abortMovie = false; - while (_chunkCount--) { + while (_chunkCount-- && !abortMovie) { byte chunkType = _vm->_arc->readByte(); uint32 chunkSize = _vm->_arc->readUint32LE(); @@ -136,7 +138,8 @@ void MoviePlayer::playMovie(uint resIndex) { if (_vm->_screen->_shakeActive && _vm->_screen->updateShakeScreen()) { _vm->_screen->_fullRefresh = true; } - _vm->updateInput(); + if (!handleInput()) + abortMovie = true; _vm->drawScreen(); // Note: drawScreen() calls delayMillis() } @@ -180,7 +183,7 @@ void MoviePlayer::playMovie(uint resIndex) { } if (!handleInput()) - break; + abortMovie = true; } delete[] chunkBuffer; @@ -200,6 +203,7 @@ void MoviePlayer::playMovie(uint resIndex) { _vm->_guiHeight = savedGuiHeight; _vm->_isSaveAllowed = true; + _isPlaying = false; } void MoviePlayer::fetchAudioChunks() { @@ -272,12 +276,15 @@ bool MoviePlayer::handleInput() { case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_ESCAPE) return false; + if (event.kbd.keycode == Common::KEYCODE_F10) { + // TODO: The original would bring up a stripped down + // main menu dialog, without the save/restore options. + } break; case Common::EVENT_LBUTTONDOWN: case Common::EVENT_RBUTTONDOWN: return false; case Common::EVENT_QUIT: - _vm->quitGame(); return false; default: break; diff --git a/engines/toltecs/movie.h b/engines/toltecs/movie.h index 8fa48975d7..c1ed6d7ba0 100644 --- a/engines/toltecs/movie.h +++ b/engines/toltecs/movie.h @@ -37,11 +37,15 @@ public: void playMovie(uint resIndex); + bool isPlaying() { return _isPlaying; } + protected: ToltecsEngine *_vm; Audio::QueuingAudioStream *_audioStream; Audio::SoundHandle _audioStreamHandle; + bool _isPlaying; + uint32 _chunkCount, _frameCount, _lastPrefetchOfs; uint32 _soundChunkFramesLeft, _framesPerSoundChunk; diff --git a/engines/toltecs/palette.cpp b/engines/toltecs/palette.cpp index 74683c6d7a..b93bb8b510 100644 --- a/engines/toltecs/palette.cpp +++ b/engines/toltecs/palette.cpp @@ -32,6 +32,8 @@ namespace Toltecs { Palette::Palette(ToltecsEngine *vm) : _vm(vm) { clearFragments(); + memset(_mainPalette, 0, sizeof(_mainPalette)); + memset(_animPalette, 0, sizeof(_animPalette)); memset(_colorTransTable, 0, sizeof(_colorTransTable)); } @@ -138,52 +140,48 @@ void Palette::clearFragments() { _fragments.clear(); } +byte Palette::getMatchingColor(byte r, byte g, byte b) { + int bestIndex = 0; + uint16 bestMatch = 0xFFFF; + + for (int j = 0; j < 256; j++) { + byte distance = ABS(_mainPalette[j * 3 + 0] - r) + ABS(_mainPalette[j * 3 + 1] - g) + ABS(_mainPalette[j * 3 + 2] - b); + byte maxColor = MAX(_mainPalette[j * 3 + 0], MAX(_mainPalette[j * 3 + 1], _mainPalette[j * 3 + 2])); + uint16 match = (distance << 8) | maxColor; + if (match < bestMatch) { + bestMatch = match; + bestIndex = j; + } + } + + return bestIndex; +} + void Palette::buildColorTransTable(byte limit, int8 deltaValue, byte mask) { byte r = 0, g = 0, b = 0; mask &= 7; - for (int i = 0; i < 256; i++) { - - if (deltaValue < 0) { - // TODO (probably unused) - warning("Palette::buildColorTransTable(%d, %d, %02X) not yet implemented!", limit, deltaValue, mask); - } else { - r = _mainPalette[i * 3 + 0]; - g = _mainPalette[i * 3 + 1]; - b = _mainPalette[i * 3 + 2]; - if (MAX(r, MAX(b, g)) >= limit) { - if ((mask & 1) && r >= deltaValue) - r -= deltaValue; - if ((mask & 2) && g >= deltaValue) - g -= deltaValue; - if ((mask & 4) && b >= deltaValue) - b -= deltaValue; - } - } + if (deltaValue < 0) // unused + error("buildColorTransTable called with a negative delta value(limit %d, delta %d, mask %02X)", limit, deltaValue, mask); - int bestIndex = 0; - uint16 bestMatch = 0xFFFF; - - for (int j = 0; j < 256; j++) { - byte distance = ABS(_mainPalette[j * 3 + 0] - r) + ABS(_mainPalette[j * 3 + 1] - g) + ABS(_mainPalette[j * 3 + 2] - b); - byte maxColor = MAX(_mainPalette[j * 3 + 0], MAX(_mainPalette[j * 3 + 1], _mainPalette[j * 3 + 2])); - uint16 match = (distance << 8) | maxColor; - if (match < bestMatch) { - bestMatch = match; - bestIndex = j; - } + for (int i = 0; i < 256; i++) { + r = _mainPalette[i * 3 + 0]; + g = _mainPalette[i * 3 + 1]; + b = _mainPalette[i * 3 + 2]; + if (MAX(r, MAX(b, g)) >= limit) { + if ((mask & 1) && r >= deltaValue) + r -= deltaValue; + if ((mask & 2) && g >= deltaValue) + g -= deltaValue; + if ((mask & 4) && b >= deltaValue) + b -= deltaValue; } - _colorTransTable[i] = bestIndex; - + _colorTransTable[i] = getMatchingColor(r, g, b); } } -void Palette::buildColorTransTable2(byte limit, int8 deltaValue, byte mask) { - // TODO -} - void Palette::saveState(Common::WriteStream *out) { // Save currently active palette byte palette[768]; diff --git a/engines/toltecs/palette.h b/engines/toltecs/palette.h index 570f51777e..4777a82699 100644 --- a/engines/toltecs/palette.h +++ b/engines/toltecs/palette.h @@ -50,8 +50,8 @@ public: uint16 findFragment(int16 id); void clearFragments(); + byte getMatchingColor(byte r, byte g, byte b); void buildColorTransTable(byte limit, int8 deltaValue, byte mask); - void buildColorTransTable2(byte limit, int8 deltaValue, byte mask); byte getColorTransPixel(byte pixel) const { return _colorTransTable[pixel]; } byte *getMainPalette() { return _mainPalette; } diff --git a/engines/toltecs/resource.cpp b/engines/toltecs/resource.cpp index 0b9f7c8fcd..437b4a963a 100644 --- a/engines/toltecs/resource.cpp +++ b/engines/toltecs/resource.cpp @@ -61,16 +61,11 @@ uint32 ArchiveReader::getResourceSize(uint resIndex) { return _offsets[resIndex + 1] - _offsets[resIndex]; } -void ArchiveReader::dump(uint resIndex, const char *prefix) { +void ArchiveReader::dump(uint resIndex) { int32 resourceSize = getResourceSize(resIndex); byte *data = new byte[resourceSize]; - Common::String fn; - - if (prefix) - fn = Common::String::format("%s_%04X.0", prefix, resIndex); - else - fn = Common::String::format("%04X.0", resIndex); + Common::String fn = Common::String::format("toltecs_res.%03d", resIndex); openResource(resIndex); read(data, resourceSize); diff --git a/engines/toltecs/resource.h b/engines/toltecs/resource.h index 3fed2e11ca..3d45d9fb1b 100644 --- a/engines/toltecs/resource.h +++ b/engines/toltecs/resource.h @@ -50,7 +50,7 @@ public: // Returns the size of the resource uint32 getResourceSize(uint resIndex); - void dump(uint resIndex, const char *prefix = NULL); + void dump(uint resIndex); protected: uint32 *_offsets; diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp index c8d6740b02..e970d9a6ed 100644 --- a/engines/toltecs/screen.cpp +++ b/engines/toltecs/screen.cpp @@ -287,7 +287,6 @@ void Screen::blastSprite(int16 x, int16 y, int16 fragmentId, int16 resIndex, uin } void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) { - debug(0, "Screen::updateVerbLine() _verbLineNum = %d; _verbLineX = %d; _verbLineY = %d; _verbLineWidth = %d; _verbLineCount = %d", _verbLineNum, _verbLineX, _verbLineY, _verbLineWidth, _verbLineCount); @@ -339,7 +338,7 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) { wrapState.len1 -= len; wrapState.len2 = len + 1; - drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0], wrapState); + drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y - 1, 0xF9, 0xFF, _fontResIndexArray[0], wrapState); wrapState.destString = wrapState.textBuffer; wrapState.width = 0; @@ -354,7 +353,7 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) { wrapState.len1 -= len; wrapState.len2 = len; - drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0], wrapState); + drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y - 1, 0xF9, 0xFF, _fontResIndexArray[0], wrapState); _guiRefresh = true; @@ -554,7 +553,7 @@ void Screen::drawGuiTextMulti(byte *textData) { wrapState.width = 0; wrapState.len1 = 0; wrapState.len2 = wrapGuiText(_fontResIndexArray[1], 640, wrapState); - drawGuiText(x - wrapState.width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1], wrapState); + drawGuiText(x - wrapState.width / 2, y - 1, _fontColor1, _fontColor2, _fontResIndexArray[1], wrapState); } } while (*wrapState.sourceString != 0xFF); @@ -593,7 +592,6 @@ void Screen::drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uin x = drawString(x + 1, y + _vm->_cameraHeight, fontColor1, fontResIndex, wrapState.textBuffer, wrapState.len1, &ywobble, false); x = drawString(x, y + _vm->_cameraHeight, fontColor2, fontResIndex, wrapState.textBuffer + wrapState.len1, wrapState.len2, &ywobble, false); - } int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, const byte *text, int len, int16 *ywobble, bool outline) { @@ -614,7 +612,7 @@ int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, const if (ch <= 0x20) { x += font.getWidth(); } else { - drawChar(font, _frontScreen, x, y - yadd, ch, color, outline); + drawChar(font, _frontScreen, x, y + yadd, ch, color, outline); x += font.getCharWidth(ch) + font.getSpacing() - 1; yadd = -yadd; } diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp index 5e8617bc43..f5e3f8481f 100644 --- a/engines/toltecs/script.cpp +++ b/engines/toltecs/script.cpp @@ -40,6 +40,22 @@ namespace Toltecs { +static const VarType varTypes[] = { + vtByte, vtWord, vtWord, vtByte, vtWord, // 0 - 4 + vtWord, vtWord, vtWord, vtWord, vtWord, // 5 - 9 + vtWord, vtWord, vtByte, vtWord, vtWord, // 10 - 14 + vtWord, vtWord, vtWord, vtWord, vtWord, // 15 - 19 + vtWord, vtWord // 20 - 21 +}; + +static const char *varNames[] = { + "mouseDisabled", "mouseY", "mouseX", "mouseButton", "verbLineY", // 0 - 4 + "verbLineX", "verbLineWidth", "verbLineCount", "verbLineNum", "talkTextItemNum", // 5 - 9 + "talkTextY", "talkTextX", "talkTextFontColor", "cameraY", "cameraX", // 10 - 14 + "walkSpeedY", "walkSpeedX", "flag01", "sceneResIndex", "guiHeight", // 15 - 19 + "sceneHeight", "sceneWidth" // 20 - 21 +}; + ScriptInterpreter::ScriptInterpreter(ToltecsEngine *vm) : _vm(vm) { _stack = new byte[kScriptStackSize]; @@ -154,7 +170,6 @@ void ScriptInterpreter::setupScriptFunctions() { } void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) { - delete[] _slots[slotIndex].data; _slots[slotIndex].resIndex = resIndex; @@ -162,7 +177,6 @@ void ScriptInterpreter::loadScript(uint resIndex, uint slotIndex) { _slots[slotIndex].size = scriptResource->size; _slots[slotIndex].data = new byte[_slots[slotIndex].size]; memcpy(_slots[slotIndex].data, scriptResource->data, _slots[slotIndex].size); - } void ScriptInterpreter::setMainScript(uint slotIndex) { @@ -228,10 +242,9 @@ int16 ScriptInterpreter::readInt16() { } void ScriptInterpreter::execOpcode(byte opcode) { - int16 ofs; - debug(1, "opcode = %d", opcode); + debug(2, "opcode = %d", opcode); switch (opcode) { case 0: @@ -239,35 +252,29 @@ void ScriptInterpreter::execOpcode(byte opcode) { // ok _subCode = _code; byte length = readByte(); - debug(1, "length = %d", length); + debug(2, "length = %d", length); uint16 index = readInt16(); - debug(1, "callScriptFunction %d", index); + debug(2, "callScriptFunction %d", index); execScriptFunction(index); _code += length - 2; break; } case 1: - // ok _regs.reg0 = readInt16(); break; case 2: - // ok _regs.reg1 = readInt16(); break; case 3: - // ok _regs.reg3 = readInt16(); break; case 4: - // ok _regs.reg5 = _regs.reg0; break; case 5: - // ok _regs.reg3 = _regs.reg0; break; case 6: - // ok _regs.reg1 = _regs.reg0; break; case 7: @@ -468,72 +475,14 @@ void ScriptInterpreter::execOpcode(byte opcode) { } void ScriptInterpreter::execScriptFunction(uint16 index) { - debug(4, "execScriptFunction(%d)", index); if (index >= _scriptFuncs.size()) error("ScriptInterpreter::execScriptFunction() Invalid script function index %d", index); - debug(4, "%s", _scriptFuncNames[index]); + debug(1, "execScriptFunction %s (%d)", _scriptFuncNames[index], index); (*_scriptFuncs[index])(); } -VarType ScriptInterpreter::getGameVarType(uint variable) { - switch (variable) { - case 0: return vtByte; - case 1: return vtWord; - case 2: return vtWord; - case 3: return vtByte; - case 4: return vtWord; - case 5: return vtWord; - case 6: return vtWord; - case 7: return vtWord; - case 8: return vtWord; - case 9: return vtWord; - case 10: return vtWord; - case 11: return vtWord; - case 12: return vtByte; - case 13: return vtWord; - case 14: return vtWord; - case 15: return vtWord; - case 16: return vtWord; - case 17: return vtWord; - case 18: return vtWord; - case 19: return vtWord; - case 20: return vtWord; - case 21: return vtWord; - default: - error("Invalid game variable"); - } -} - -const char *getVarName(uint variable) { - switch (variable) { - case 0: return "mouseDisabled"; - case 1: return "mouseY"; - case 2: return "mouseX"; - case 3: return "mouseButton"; - case 4: return "verbLineY"; - case 5: return "verbLineX"; - case 6: return "verbLineWidth"; - case 7: return "verbLineCount"; - case 8: return "verbLineNum"; - case 9: return "talkTextItemNum"; - case 10: return "talkTextY"; - case 11: return "talkTextX"; - case 12: return "talkTextFontColor"; - case 13: return "cameraY"; - case 14: return "cameraX"; - case 15: return "walkSpeedY"; - case 16: return "walkSpeedX"; - case 17: return "flag01"; - case 18: return "sceneResIndex"; - case 19: return "guiHeight"; - case 20: return "sceneHeight"; - case 21: return "sceneWidth"; - } - return "(invalid)"; -} - int16 ScriptInterpreter::getGameVar(uint variable) { - debug(0, "ScriptInterpreter::getGameVar(%d{%s})", variable, getVarName(variable)); + debug(2, "ScriptInterpreter::getGameVar(%d{%s})", variable, varNames[variable]); switch (variable) { case 0: return _vm->_mouseDisabled; @@ -559,13 +508,13 @@ int16 ScriptInterpreter::getGameVar(uint variable) { case 20: return _vm->_sceneHeight; case 21: return _vm->_sceneWidth; default: - warning("Getting unimplemented game variable %s (%d)", getVarName(variable), variable); + warning("Getting unimplemented game variable %s (%d)", varNames[variable], variable); return 0; } } void ScriptInterpreter::setGameVar(uint variable, int16 value) { - debug(0, "ScriptInterpreter::setGameVar(%d{%s}, %d)", variable, getVarName(variable), value); + debug(2, "ScriptInterpreter::setGameVar(%d{%s}, %d)", variable, varNames[variable], value); switch (variable) { case 0: @@ -632,10 +581,9 @@ void ScriptInterpreter::setGameVar(uint variable, int16 value) { case 1: case 2: default: - warning("Setting unimplemented game variable %s (%d) to %d", getVarName(variable), variable, value); + warning("Setting unimplemented game variable %s (%d) to %d", varNames[variable], variable, value); break; } - } byte ScriptInterpreter::arg8(int16 offset) { @@ -657,32 +605,31 @@ int16 ScriptInterpreter::popInt16() { } void ScriptInterpreter::localWrite8(int16 offset, byte value) { - //debug(1, "localWrite8(%d, %d)", offset, value); + //debug(2, "localWrite8(%d, %d)", offset, value); _localData[offset] = value; } byte ScriptInterpreter::localRead8(int16 offset) { - //debug(1, "localRead8(%d) -> %d", offset, _localData[offset]); + //debug(2, "localRead8(%d) -> %d", offset, _localData[offset]); return _localData[offset]; } void ScriptInterpreter::localWrite16(int16 offset, int16 value) { - //debug(1, "localWrite16(%d, %d)", offset, value); + //debug(2, "localWrite16(%d, %d)", offset, value); WRITE_LE_UINT16(&_localData[offset], value); } int16 ScriptInterpreter::localRead16(int16 offset) { - //debug(1, "localRead16(%d) -> %d", offset, (int16)READ_LE_UINT16(&_localData[offset])); + //debug(2, "localRead16(%d) -> %d", offset, (int16)READ_LE_UINT16(&_localData[offset])); return (int16)READ_LE_UINT16(&_localData[offset]); } byte *ScriptInterpreter::localPtr(int16 offset) { - //debug(1, "localPtr(%d)", offset); + //debug(2, "localPtr(%d)", offset); return &_localData[offset]; } void ScriptInterpreter::saveState(Common::WriteStream *out) { - // Save registers out->writeUint16LE(_regs.reg0); out->writeUint16LE(_regs.reg1); @@ -708,11 +655,9 @@ void ScriptInterpreter::saveState(Common::WriteStream *out) { // Save IP out->writeUint16LE((int16)(_code - getSlotData(_regs.reg4))); - } void ScriptInterpreter::loadState(Common::ReadStream *in) { - // Load registers _regs.reg0 = in->readUint16LE(); _regs.reg1 = in->readUint16LE(); @@ -741,7 +686,6 @@ void ScriptInterpreter::loadState(Common::ReadStream *in) { // Load IP _code = getSlotData(_regs.reg4) + in->readUint16LE(); - } void ScriptInterpreter::sfNop() { @@ -755,7 +699,9 @@ void ScriptInterpreter::sfGetGameVar() { void ScriptInterpreter::sfSetGameVar() { int16 varIndex = arg16(3); - VarType varType = getGameVarType(varIndex); + assert(varIndex <= 21); + + VarType varType = varTypes[varIndex]; int16 value = 0; if (varType == vtByte) value = arg8(5); @@ -810,8 +756,7 @@ void ScriptInterpreter::sfSetDeltaAnimPalette() { } void ScriptInterpreter::sfSetUnkPaletteEffect() { - // TODO - debug("ScriptInterpreter::sfSetUnkPaletteEffect"); + error("ScriptInterpreter::sfSetUnkPaletteEffect called"); // unused } void ScriptInterpreter::sfBuildColorTransTable() { @@ -992,7 +937,8 @@ void ScriptInterpreter::sfStopShakeScreen() { void ScriptInterpreter::sfStartSequence() { int16 sequenceResIndex = arg16(3); - //debug("ScriptInterpreter::sfStartSequence(%d)", sequenceResIndex); + debug(1, "ScriptInterpreter::sfStartSequence(%d)", sequenceResIndex); + if (sequenceResIndex >= 0) { //_vm->_arc->dump(sequenceResIndex, "music"); // DEBUG: Dump music so we know what's in there @@ -1001,7 +947,6 @@ void ScriptInterpreter::sfStartSequence() { } void ScriptInterpreter::sfEndSequence() { - //debug("ScriptInterpreter::sfEndSequence"); _vm->_music->stopSequence(); } @@ -1029,9 +974,8 @@ void ScriptInterpreter::sfHandleInput() { if (_vm->_rightButtonDown) { keyCode = 1; } else { - /* Convert keyboard scancode to IBM PC scancode - Only scancodes known to be used (so far) are converted - */ + // Convert keyboard scancode to IBM PC scancode. + // Only scancodes known to be used (so far) are converted. switch (_vm->_keyState.keycode) { case Common::KEYCODE_ESCAPE: keyCode = 1; @@ -1050,11 +994,13 @@ void ScriptInterpreter::sfRunOptionsScreen() { _vm->showMenu(kMenuIdMain); } -/* NOTE: The opcodes sfPrecacheSprites, sfPrecacheSounds1, sfPrecacheSounds2 and - sfDeletePrecachedFiles were used by the original engine to handle precaching - of data so the game doesn't stall while playing (due to the slow speed of - CD-Drives back then). This is not needed in ScummVM since all supported - systems are fast enough to load data in-game. */ +/** + * NOTE: The opcodes sfPrecacheSprites, sfPrecacheSounds1, sfPrecacheSounds2 and + * sfDeletePrecachedFiles were used by the original engine to handle precaching + * of data so the game doesn't stall while playing (due to the slow speed of + * CD-Drives back then). This is not needed in ScummVM since all supported + * systems are fast enough to load data in-game. + */ void ScriptInterpreter::sfPrecacheSprites() { // See note above diff --git a/engines/toltecs/script.h b/engines/toltecs/script.h index 89dca4598f..4c880dfef5 100644 --- a/engines/toltecs/script.h +++ b/engines/toltecs/script.h @@ -49,7 +49,6 @@ public: byte *getSlotData(int slotIndex) const { return _slots[slotIndex].data; } - VarType getGameVarType(uint variable); int16 getGameVar(uint variable); void setGameVar(uint variable, int16 value); diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp index 9f3a10a03b..f6a2dfed9d 100644 --- a/engines/toltecs/toltecs.cpp +++ b/engines/toltecs/toltecs.cpp @@ -39,6 +39,7 @@ #include "toltecs/toltecs.h" #include "toltecs/animation.h" +#include "toltecs/console.h" #include "toltecs/menu.h" #include "toltecs/movie.h" #include "toltecs/music.h" @@ -62,6 +63,9 @@ struct GameSettings { }; ToltecsEngine::ToltecsEngine(OSystem *syst, const ToltecsGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) { + // Assign default values to the config manager, in case settings are missing + ConfMan.registerDefault("originalsaveload", "false"); + _rnd = new Common::RandomSource("toltecs"); } @@ -123,6 +127,7 @@ Common::Error ToltecsEngine::run() { _menuSystem = new MenuSystem(this); _sound = new Sound(this); + _console = new Console(this); _cfgText = ConfMan.getBool("subtitles"); _cfgVoices = !ConfMan.getBool("speech_mute"); @@ -176,6 +181,7 @@ Common::Error ToltecsEngine::run() { _music->stopSequence(); _sound->stopAll(); + delete _console; delete _arc; delete _res; delete _screen; @@ -215,7 +221,6 @@ void ToltecsEngine::requestLoadgame(int slotNum) { } void ToltecsEngine::loadScene(uint resIndex) { - Resource *sceneResource = _res->load(resIndex); byte *scene = sceneResource->data; @@ -250,13 +255,10 @@ void ToltecsEngine::loadScene(uint resIndex) { _screen->_fullRefresh = true; _screen->_renderQueue->clear(); - } void ToltecsEngine::updateScreen() { - _sound->updateSpeech(); - _screen->updateShakeScreen(); // TODO: Set quit flag @@ -289,7 +291,6 @@ void ToltecsEngine::updateScreen() { _counter02 = (currUpdateTime - prevUpdateTime) / 13; } while (_counter02 == 0); prevUpdateTime = currUpdateTime; - } void ToltecsEngine::drawScreen() { @@ -310,6 +311,7 @@ void ToltecsEngine::drawScreen() { _screen->_guiRefresh = false; } + _console->onFrame(); _system->updateScreen(); _system->delayMillis(10); @@ -317,7 +319,6 @@ void ToltecsEngine::drawScreen() { } void ToltecsEngine::updateInput() { - Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); while (eventMan->pollEvent(event)) { @@ -327,6 +328,9 @@ void ToltecsEngine::updateInput() { //debug("key: flags = %02X; keycode = %d", _keyState.flags, _keyState.keycode); + if (event.kbd.hasFlags(Common::KBD_CTRL) && event.kbd.keycode == Common::KEYCODE_d) + _console->attach(); + switch (event.kbd.keycode) { case Common::KEYCODE_F5: showMenu(kMenuIdSave); @@ -350,9 +354,6 @@ void ToltecsEngine::updateInput() { case Common::EVENT_KEYUP: _keyState.reset(); break; - case Common::EVENT_QUIT: - quitGame(); - break; case Common::EVENT_MOUSEMOVE: _mouseX = event.mouse.x; _mouseY = event.mouse.y; @@ -408,9 +409,7 @@ void ToltecsEngine::updateInput() { _mouseWaitForRelease = false; _mouseButton = 0; } - } - } void ToltecsEngine::setGuiHeight(int16 guiHeight) { @@ -478,7 +477,6 @@ void ToltecsEngine::scrollCameraRight(int16 delta) { } void ToltecsEngine::updateCamera() { - if (_cameraX != _newCameraX) { _cameraX = _newCameraX; _screen->_fullRefresh = true; @@ -492,11 +490,9 @@ void ToltecsEngine::updateCamera() { } //debug(0, "ToltecsEngine::updateCamera() _cameraX = %d; _cameraY = %d", _cameraX, _cameraY); - } void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) { - byte *scanData = _script->getSlotData(slotIndex) + slotOffset; while (*scanData < 0xF0) { @@ -526,11 +522,9 @@ void ToltecsEngine::talk(int16 slotIndex, int16 slotOffset) { } else { _screen->updateTalkText(slotIndex, slotOffset); } - } void ToltecsEngine::walk(byte *walkData) { - int16 xdelta, ydelta, v8, v10, v11; int16 xstep, ystep; ScriptWalk walkInfo; @@ -613,7 +607,6 @@ void ToltecsEngine::walk(byte *walkData) { WRITE_LE_UINT16(walkData + 14, walkInfo.xerror); WRITE_LE_UINT16(walkData + 16, walkInfo.mulValue); WRITE_LE_UINT16(walkData + 18, walkInfo.scaling); - } int16 ToltecsEngine::findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize, diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h index b95a4f77cb..0be2d2a646 100644 --- a/engines/toltecs/toltecs.h +++ b/engines/toltecs/toltecs.h @@ -42,6 +42,7 @@ struct ToltecsGameDescription; class AnimationPlayer; class ArchiveReader; +class Console; class Input; class MenuSystem; class MoviePlayer; @@ -144,6 +145,7 @@ public: AnimationPlayer *_anim; ArchiveReader *_arc; + Console *_console; Input *_input; MenuSystem *_menuSystem; MoviePlayer *_moviePlayer; diff --git a/gui/about.cpp b/gui/about.cpp index 9eb8a0175a..e2b7064279 100644 --- a/gui/about.cpp +++ b/gui/about.cpp @@ -54,7 +54,7 @@ enum { static const char *copyright_text[] = { "", -"C0""Copyright (C) 2001-2012 The ScummVM project", +"C0""Copyright (C) 2001-2013 The ScummVM project", "C0""http://www.scummvm.org", "", "C0""ScummVM is the legal property of its developers, whose names are too numerous to list here. Please refer to the COPYRIGHT file distributed with this binary.", diff --git a/gui/credits.h b/gui/credits.h index f63f54a6fb..237d97d56c 100644 --- a/gui/credits.h +++ b/gui/credits.h @@ -237,6 +237,10 @@ static const char *credits[] = { "C0""Filippos Karapetis", "C0""Joost Peters", "", +"C1""Toltecs", +"C0""Benjamin Haisch", +"C0""Filippos Karapetis", +"", "C1""Tony", "C0""Arnaud Boutonn\351", "C0""Paul Gilbert", diff --git a/gui/options.cpp b/gui/options.cpp index 4868f1876d..ea3cbff2be 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -877,7 +877,7 @@ void OptionsDialog::addMT32Controls(GuiObject *boss, const Common::String &prefi _mt32Checkbox = new CheckboxWidget(boss, prefix + "mcMt32Checkbox", _c("True Roland MT-32 (no GM emulation)", "lowres"), _("Check if you want to use your real hardware Roland-compatible sound device connected to your computer")); // GS Extensions setting - _enableGSCheckbox = new CheckboxWidget(boss, prefix + "mcGSCheckbox", _("Enable Roland GS Mode"), _("Turns off General MIDI mapping for games with Roland MT-32 soundtrack")); + _enableGSCheckbox = new CheckboxWidget(boss, prefix + "mcGSCheckbox", _("Roland GS Mode (disable GM mapping)"), _("Turns off General MIDI mapping for games with Roland MT-32 soundtrack")); const MusicPlugin::List p = MusicMan.getPlugins(); // Make sure the null device is the first one in the list to avoid undesired diff --git a/gui/widget.cpp b/gui/widget.cpp index 4ffb63e945..c3f10a861f 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -593,8 +593,8 @@ void SliderWidget::handleMouseUp(int x, int y, int button, int clickCount) { void SliderWidget::handleMouseWheel(int x, int y, int direction) { if (isEnabled() && !_isDragging) { - // Increment or decrement one position - int newValue = posToValue(valueToPos(_value) - 1 * direction); + // Increment or decrement by one + int newValue = _value - direction; if (newValue < _valueMin) newValue = _valueMin; diff --git a/gui/widgets/popup.cpp b/gui/widgets/popup.cpp index 1a552e97c0..829a49c53e 100644 --- a/gui/widgets/popup.cpp +++ b/gui/widgets/popup.cpp @@ -388,24 +388,28 @@ void PopUpWidget::handleMouseDown(int x, int y, int button, int clickCount) { if (newSel != -1 && _selectedItem != newSel) { _selectedItem = newSel; sendCommand(kPopUpItemSelectedCmd, _entries[_selectedItem].tag); + draw(); } } } void PopUpWidget::handleMouseWheel(int x, int y, int direction) { - int newSelection = _selectedItem + direction; + if (isEnabled()) { + int newSelection = _selectedItem + direction; - // Skip separator entries - while ((newSelection >= 0) && (newSelection < (int)_entries.size()) && - _entries[newSelection].name.equals("")) { - newSelection += direction; - } + // Skip separator entries + while ((newSelection >= 0) && (newSelection < (int)_entries.size()) && + _entries[newSelection].name.equals("")) { + newSelection += direction; + } - // Just update the selected item when we're in range - if ((newSelection >= 0) && (newSelection < (int)_entries.size()) && - (newSelection != _selectedItem)) { - _selectedItem = newSelection; - draw(); + // Just update the selected item when we're in range + if ((newSelection >= 0) && (newSelection < (int)_entries.size()) && + (newSelection != _selectedItem)) { + _selectedItem = newSelection; + sendCommand(kPopUpItemSelectedCmd, _entries[_selectedItem].tag); + draw(); + } } } diff --git a/po/POTFILES b/po/POTFILES index 72c6fb1d18..3d9b993d47 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -25,6 +25,8 @@ engines/dialogs.cpp engines/engine.cpp engines/agi/detection.cpp engines/agi/saveload.cpp +engines/drascula/detection.cpp +engines/drascula/saveload.cpp engines/dreamweb/detection.cpp engines/sci/detection.cpp engines/scumm/dialogs.cpp @@ -40,6 +42,7 @@ engines/agos/animation.cpp engines/gob/inter_playtoons.cpp engines/gob/inter_v2.cpp engines/gob/inter_v5.cpp +engines/groovie/detection.cpp engines/groovie/script.cpp engines/kyra/detection.cpp engines/kyra/lol.cpp @@ -55,6 +58,8 @@ engines/sword2/animation.cpp engines/sword2/sword2.cpp engines/teenagent/resources.cpp engines/tinsel/saveload.cpp +engines/toltecs/detection.cpp +engines/toltecs/menu.cpp engines/parallaction/saveload.cpp audio/fmopl.cpp diff --git a/po/be_BY.po b/po/be_BY.po index 9539588ba6..3d64a3f55f 100644 --- a/po/be_BY.po +++ b/po/be_BY.po @@ -1,5 +1,5 @@ # Belarusian translation for ScummVM. -# Copyright (C) 2010-2012 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Ivan Lukyanov <greencis@mail.ru>, 2012. # diff --git a/po/ca_ES.po b/po/ca_ES.po index 2a6aa716cf..706eb64edb 100644 --- a/po/ca_ES.po +++ b/po/ca_ES.po @@ -1,5 +1,5 @@ # Catalan translation for ScummVM. -# Copyright (C) 2007-2012 ScummVM Team +# Copyright (C) 2007-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Jordi Vilalta Prat <jvprat@jvprat.com>, 2007-2011. # diff --git a/po/cs_CZ.po b/po/cs_CZ.po index 4f800906e7..5b1dc7ec52 100644 --- a/po/cs_CZ.po +++ b/po/cs_CZ.po @@ -1,5 +1,5 @@ # Czech translation for ScummVM. -# Copyright (C) 2001-2011 ScummVM Team +# Copyright (C) 2011-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Zbynìk Schwarz <zbynek.schwarz@gmail.com>, 2011. # diff --git a/po/da_DA.po b/po/da_DA.po index 002bd4e13c..1e1a491990 100644 --- a/po/da_DA.po +++ b/po/da_DA.po @@ -1,4 +1,5 @@ -# Copyright (C) 2010-2012 ScummVM Team +# Dansk translation for ScummVM +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Steffen Nyeland <steffen@nyeland.dk>, 2010. # diff --git a/po/de_DE.po b/po/de_DE.po index ae7b48eae0..f164a9b76d 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -1,5 +1,5 @@ # German translation for ScummVM. -# Copyright (C) 2010-2012 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Simon Sawatzki <SimSaw@gmx.de>, Lothar Serra Mari <Lothar@Windowsbase.de>, 2012. # diff --git a/po/es_ES.po b/po/es_ES.po index 13bbc16584..0d38044824 100644 --- a/po/es_ES.po +++ b/po/es_ES.po @@ -1,5 +1,5 @@ # Spanish translation for ScummVM. -# Copyright (C) 2010-2012 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Tomás Maidagan, 2011. # @@ -1,5 +1,5 @@ # Basque translation for ScummVM. -# Copyright (C) 2011 ScummVM Team +# Copyright (C) 2012-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Mikel Iturbe Urretxa <mikel@hamahiru.org>, 2012. # diff --git a/po/fi_FI.po b/po/fi_FI.po index 0cac4d6c79..d2fda71b7d 100644 --- a/po/fi_FI.po +++ b/po/fi_FI.po @@ -1,5 +1,5 @@ # Finnish translation for ScummVM. -# Copyright (C) 2012 ScummVM Team +# Copyright (c) 2012-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Toni Saarela <saarela@gmail.com>, 2012. # diff --git a/po/fr_FR.po b/po/fr_FR.po index 6e8f350b4e..ad1406ed18 100644 --- a/po/fr_FR.po +++ b/po/fr_FR.po @@ -1,5 +1,5 @@ # French translation for ScummVM. -# Copyright (C) 2010-2012 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Thierry Crozat <criezy@scummvm.org>, 2011. # diff --git a/po/gl_ES.po b/po/gl_ES.po index c18a1935c3..a650ff338d 100644 --- a/po/gl_ES.po +++ b/po/gl_ES.po @@ -1,5 +1,5 @@ # LANGUAGE translation for ScummVM. -# Copyright (C) YEAR ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # diff --git a/po/hu_HU.po b/po/hu_HU.po index a7824259b5..03b6c1a405 100644 --- a/po/hu_HU.po +++ b/po/hu_HU.po @@ -1,5 +1,5 @@ # Hungarian translation for ScummVM. -# Copyright (C) 2010-2011 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # George Kormendi <grubycza@hotmail.com>, 2010. # diff --git a/po/it_IT.po b/po/it_IT.po index 3ebb5ca090..220e18fce5 100644 --- a/po/it_IT.po +++ b/po/it_IT.po @@ -1,5 +1,5 @@ # Italian translation for ScummVM. -# Copyright (C) 2010-2012 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Matteo 'Maff' Angelino <matteo.maff at gmail dot com>, 2010. # diff --git a/po/nb_NO.po b/po/nb_NO.po index e28c370f2d..bf94822c95 100644 --- a/po/nb_NO.po +++ b/po/nb_NO.po @@ -1,5 +1,5 @@ # Norwegian (Bokmaal) translation for ScummVM. -# Copyright (C) 2010-2012 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Einar Johan T. Sømåen <einarjohants@gmail.com>, 2010. # diff --git a/po/nn_NO.po b/po/nn_NO.po index 77af3801bf..64c18effa8 100644 --- a/po/nn_NO.po +++ b/po/nn_NO.po @@ -1,5 +1,5 @@ # Norwegian (Nynorsk) translation for ScummVM. -# Copyright (C) 2010-2012 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Einar Johan T. Sømåen <einarjohants@gmail.com>, 2010. # diff --git a/po/pl_PL.po b/po/pl_PL.po index 6e8699113a..154d05a411 100644 --- a/po/pl_PL.po +++ b/po/pl_PL.po @@ -1,7 +1,7 @@ # Polish translation for ScummVM. -# Copyright (C) 2010-2012 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. -# Grajpopolsku.pl <grajpopolsku@gmail.com>, 2011-2012. +# Grajpopolsku.pl <grajpopolsku@gmail.com>, 2011-2013. # msgid "" msgstr "" diff --git a/po/pt_BR.po b/po/pt_BR.po index 0d80b9d8c9..0225854de6 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -1,5 +1,5 @@ # Portuguese (Brazilian) translation for ScummVM. -# Copyright (C) 2010-2012 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Saulo Benigno <saulobenigno@gmail.com>, 2010. # diff --git a/po/ru_RU.po b/po/ru_RU.po index fb078b74d1..3140b41f50 100644 --- a/po/ru_RU.po +++ b/po/ru_RU.po @@ -1,5 +1,5 @@ # Russian translation for ScummVM. -# Copyright (C) 2010-2012 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Eugene Sandulenko <sev@scummvm.org>, 2010. # diff --git a/po/se_SE.po b/po/se_SE.po index 7dbcd432f6..1eb6ffa4a3 100644 --- a/po/se_SE.po +++ b/po/se_SE.po @@ -1,5 +1,5 @@ # Swedish translation for ScummVM. -# Copyright (C) 2011-2012 ScummVM Team +# Copyright (C) 2011-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Hampus Flink <hampus.flink@gmail.com>, 2011. # diff --git a/po/uk_UA.po b/po/uk_UA.po index b6cf7d51fe..3b6ccd266f 100644 --- a/po/uk_UA.po +++ b/po/uk_UA.po @@ -1,5 +1,5 @@ # Ukrainian translation for ScummVM. -# Copyright (C) 2010-2012 ScummVM Team +# Copyright (C) 2010-2013 ScummVM Team # This file is distributed under the same license as the ScummVM package. # Lubomyr Lisen, 2010. # |