diff options
author | Gregory Montoir | 2008-11-28 23:56:25 +0000 |
---|---|---|
committer | Gregory Montoir | 2008-11-28 23:56:25 +0000 |
commit | 362bdf87d78f611f3e308e7e9234831208b93d68 (patch) | |
tree | 41cf8bb25390cc1ed37d9ccdea87856b68a101eb /engines/tucker | |
parent | 443c57146d74d7a92d1c9ec48c0f7eb8a497749b (diff) | |
download | scummvm-rg350-362bdf87d78f611f3e308e7e9234831208b93d68.tar.gz scummvm-rg350-362bdf87d78f611f3e308e7e9234831208b93d68.tar.bz2 scummvm-rg350-362bdf87d78f611f3e308e7e9234831208b93d68.zip |
added support for kSupportsLoadingDuringRuntime & kSupportsSavingDuringRuntime, cleanup
svn-id: r35171
Diffstat (limited to 'engines/tucker')
-rw-r--r-- | engines/tucker/detection.cpp | 40 | ||||
-rw-r--r-- | engines/tucker/graphics.cpp | 37 | ||||
-rw-r--r-- | engines/tucker/graphics.h | 26 | ||||
-rw-r--r-- | engines/tucker/resource.cpp | 16 | ||||
-rw-r--r-- | engines/tucker/saveload.cpp | 46 | ||||
-rw-r--r-- | engines/tucker/sequences.cpp | 20 | ||||
-rw-r--r-- | engines/tucker/staticres.cpp | 8 | ||||
-rw-r--r-- | engines/tucker/tucker.cpp | 29 | ||||
-rw-r--r-- | engines/tucker/tucker.h | 17 |
9 files changed, 170 insertions, 69 deletions
diff --git a/engines/tucker/detection.cpp b/engines/tucker/detection.cpp index b3fa353b08..d6742bb342 100644 --- a/engines/tucker/detection.cpp +++ b/engines/tucker/detection.cpp @@ -97,12 +97,52 @@ public: return "Bud Tucker in Double Trouble (C) Merit Studios"; } + virtual bool hasFeature(MetaEngineFeature f) const { + switch (f) { + case kSupportsListSaves: + case kSupportsDeleteSave: + return true; + default: + return false; + } + } + virtual bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const { if (desc) { *engine = new Tucker::TuckerEngine(syst, desc->language, (desc->flags & Common::ADGF_DEMO) != 0); } return desc != 0; } + + virtual SaveStateList listSaves(const char *target) const { + Common::String pattern = Tucker::generateGameStateFileName(target, 0, true); + Common::StringList filenames = g_system->getSavefileManager()->listSavefiles(pattern.c_str()); + sort(filenames.begin(), filenames.end()); + SaveStateList saveList; + for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + int slot; + const char *ext = strrchr(file->c_str(), '.'); + if (ext && (slot = atoi(ext + 1)) >= 0) { + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(file->c_str()); + if (in) { + char description[64]; + snprintf(description, sizeof(description), "savegm.%02d", slot); + saveList.push_back(SaveStateDescriptor(slot, description)); + delete in; + } + } + } + return saveList; + } + + virtual int getMaximumSaveSlot() const { + return 99; + } + + virtual void removeSaveState(const char *target, int slot) const { + Common::String filename = Tucker::generateGameStateFileName(target, slot); + g_system->getSavefileManager()->removeSavefile(filename.c_str()); + } }; #if PLUGIN_ENABLED_DYNAMIC(TUCKER) diff --git a/engines/tucker/graphics.cpp b/engines/tucker/graphics.cpp index 4955068b05..a2ac399e63 100644 --- a/engines/tucker/graphics.cpp +++ b/engines/tucker/graphics.cpp @@ -223,15 +223,15 @@ void Graphics::copyTo640(uint8 *dst, const uint8 *src, int w, int srcPitch, int } void Graphics::drawStringChar(uint8 *dst, uint8 chr, int pitch, uint8 chrColor, const uint8 *src) { - if (chr < 32 || chr - 32 >= _charset->xCount * _charset->yCount) { + if (chr < 32 || chr - 32 >= _charset.xCount * _charset.yCount) { return; } - int offset = (chr - 32) * _charset->charH * _charset->charW; - for (int y = 0; y < _charset->charH; ++y) { - for (int x = 0; x < _charset->charW; ++x) { + int offset = (chr - 32) * _charset.charH * _charset.charW; + for (int y = 0; y < _charset.charH; ++y) { + for (int x = 0; x < _charset.charW; ++x) { const int color = src[offset++]; if (color != 0) { - if (_charset == &_creditsCharset) { + if (_charsetType == kCharsetTypeCredits) { dst[x] = color; } else { dst[x] = (color == 128) ? color : chrColor; @@ -242,4 +242,31 @@ void Graphics::drawStringChar(uint8 *dst, uint8 chr, int pitch, uint8 chrColor, } } +void Graphics::setCharset(CharsetType type) { + switch (type) { + case kCharsetTypeEnglish: + _charset.charW = 10; + _charset.charH = 8; + _charset.xCount = 32; + _charset.yCount = 3; + break; + case kCharsetTypeFrench: + _charset.charW = 10; + _charset.charH = 10; + _charset.xCount = 32; + _charset.yCount = 7; + break; + case kCharsetTypeCredits: + _charset.charW = 19; + _charset.charH = 10; + _charset.xCount = 16; + _charset.yCount = 7; + break; + } +} + +Charset Graphics::_charset; + +CharsetType Graphics::_charsetType; + } // namespace Tucker diff --git a/engines/tucker/graphics.h b/engines/tucker/graphics.h index 7ffabe3033..b2d14e221e 100644 --- a/engines/tucker/graphics.h +++ b/engines/tucker/graphics.h @@ -30,15 +30,22 @@ namespace Tucker { +enum CharsetType { + kCharsetTypeEnglish, + kCharsetTypeFrench, + kCharsetTypeCredits +}; + +struct Charset { + int charW; + int charH; + int xCount; + int yCount; +}; + class Graphics { public: - struct Charset { - int charW; - int charH; - int xCount; - int yCount; - }; static int encodeRLE(const uint8 *src, uint8 *dst, int w, int h); static int encodeRAW(const uint8 *src, uint8 *dst, int w, int h); @@ -53,11 +60,10 @@ public: static void drawStringChar(uint8 *dst, uint8 chr, int pitch, uint8 chrColor, const uint8 *src); - static const Charset _enCharset; - static const Charset _frCharset; - static const Charset _creditsCharset; + static void setCharset(CharsetType type); - static const Charset *_charset; + static Charset _charset; + static CharsetType _charsetType; }; } // namespace Tucker diff --git a/engines/tucker/resource.cpp b/engines/tucker/resource.cpp index 6968b8e256..ca903a7e21 100644 --- a/engines/tucker/resource.cpp +++ b/engines/tucker/resource.cpp @@ -268,7 +268,7 @@ void TuckerEngine::loadCursor() { void TuckerEngine::loadCharset() { strcpy(_fileToLoad, "charset.pcx"); loadImage(_loadTempBuf, 0); - Graphics::_charset = (_lang == Common::FR_FRA) ? &Graphics::_frCharset : &Graphics::_enCharset; + Graphics::setCharset((_lang == Common::FR_FRA) ? kCharsetTypeFrench : kCharsetTypeEnglish); loadCharsetHelper(); } @@ -278,18 +278,16 @@ void TuckerEngine::loadCharset2() { memcpy(_charWidthTable + 65, _charWidthCharset2, 58); strcpy(_fileToLoad, "char2.pcx"); loadImage(_loadTempBuf, 0); - Graphics::_charset = &Graphics::_creditsCharset; + Graphics::setCharset(kCharsetTypeCredits); loadCharsetHelper(); } void TuckerEngine::loadCharsetHelper() { - const int charW = Graphics::_charset->charW; - const int charH = Graphics::_charset->charH; - const int xSize = Graphics::_charset->xCount; - const int ySize = Graphics::_charset->yCount; + const int charW = Graphics::_charset.charW; + const int charH = Graphics::_charset.charH; int offset = 0; - for (int y = 0; y < ySize; ++y) { - for (int x = 0; x < xSize; ++x) { + for (int y = 0; y < Graphics::_charset.yCount; ++y) { + for (int x = 0; x < Graphics::_charset.xCount; ++x) { offset += Graphics::encodeRAW(_loadTempBuf + (y * 320) * charH + x * charW, _charsetGfxBuf + offset, charW, charH); } } @@ -907,7 +905,7 @@ void TuckerEngine::loadSound(Audio::Mixer::SoundType type, int num, int volume, } if (stream) { _mixer->stopHandle(*handle); - _mixer->playInputStream(type, handle, stream, -1, volume * Audio::Mixer::kMaxChannelVolume / kMaxSoundVolume); + _mixer->playInputStream(type, handle, stream, -1, scaleMixerVolume(volume, kMaxSoundVolume)); } } diff --git a/engines/tucker/saveload.cpp b/engines/tucker/saveload.cpp index 145c86ef18..0faa96c404 100644 --- a/engines/tucker/saveload.cpp +++ b/engines/tucker/saveload.cpp @@ -33,13 +33,16 @@ enum { kCurrentGameStateVersion = 1 }; -void TuckerEngine::generateGameStateFileName(int num, char *dst, int len, bool prefixOnly) const { +Common::String generateGameStateFileName(const char *target, int slot, bool prefixOnly) { + Common::String name(target); if (prefixOnly) { - snprintf(dst, len, "%s.*", _targetName.c_str()); + name += ".*"; } else { - snprintf(dst, len, "%s.%d", _targetName.c_str(), num); + char slotStr[16]; + snprintf(slotStr, sizeof(slotStr), ".%d", slot); + name += slotStr; } - dst[len] = 0; + return name; } static void saveOrLoadInt(Common::WriteStream &stream, int &i) { @@ -74,19 +77,20 @@ void TuckerEngine::saveOrLoadGameStateData(S &s) { saveOrLoadInt(s, _inventoryObjectsOffset); } -void TuckerEngine::loadGame(int slot) { - char gameStateFileName[64]; - generateGameStateFileName(slot, gameStateFileName, 63); - Common::InSaveFile *f = _saveFileMan->openForLoading(gameStateFileName); +Common::Error TuckerEngine::loadGameState(int num) { + Common::Error ret = Common::kNoError; + Common::String gameStateFileName = generateGameStateFileName(_targetName.c_str(), num); + Common::InSaveFile *f = _saveFileMan->openForLoading(gameStateFileName.c_str()); if (f) { uint16 version = f->readUint16LE(); if (version < kCurrentGameStateVersion) { - warning("Unsupported gamestate version %d (slot %d)", version, slot); + warning("Unsupported gamestate version %d (slot %d)", version, num); } else { f->skip(2); saveOrLoadGameStateData(*f); if (f->ioFailed()) { - warning("Can't read file '%s'", gameStateFileName); + warning("Can't read file '%s'", gameStateFileName.c_str()); + ret = Common::kReadingFailed; } else { _nextLocationNum = _locationNum; setBlackPalette(); @@ -95,22 +99,34 @@ void TuckerEngine::loadGame(int slot) { } delete f; } + return ret; } -void TuckerEngine::saveGame(int slot) { - char gameStateFileName[64]; - generateGameStateFileName(slot, gameStateFileName, 63); - Common::OutSaveFile *f = _saveFileMan->openForSaving(gameStateFileName); +Common::Error TuckerEngine::saveGameState(int num, const char *description) { + Common::Error ret = Common::kNoError; + Common::String gameStateFileName = generateGameStateFileName(_targetName.c_str(), num); + Common::OutSaveFile *f = _saveFileMan->openForSaving(gameStateFileName.c_str()); if (f) { f->writeUint16LE(kCurrentGameStateVersion); f->writeUint16LE(0); saveOrLoadGameStateData(*f); f->finalize(); if (f->ioFailed()) { - warning("Can't write file '%s'", gameStateFileName); + warning("Can't write file '%s'", gameStateFileName.c_str()); + ret = Common::kWritingFailed; } delete f; } + return ret; +} + + +bool TuckerEngine::canLoadGameStateCurrently() { + return !_player && _cursorType < 2; +} + +bool TuckerEngine::canSaveGameStateCurrently() { + return !_player && _cursorType < 2; } } // namespace Tucker diff --git a/engines/tucker/sequences.cpp b/engines/tucker/sequences.cpp index 57e037cf97..a1523c7aa0 100644 --- a/engines/tucker/sequences.cpp +++ b/engines/tucker/sequences.cpp @@ -33,6 +33,14 @@ namespace Tucker { +void TuckerEngine::handleIntroSequence() { + const int firstSequence = _isDemo ? kFirstAnimationSequenceDemo : kFirstAnimationSequenceGame; + _player = new AnimationSequencePlayer(_system, _mixer, _eventMan, firstSequence); + _player->mainLoop(); + delete _player; + _player = 0; +} + void TuckerEngine::handleCreditsSequence() { static const int _creditsSequenceData1[] = { 200, 350, 650, 850, 1150, 1450, 12000 }; static const int _creditsSequenceData2[] = { 1, 1, 5, 0, 6, 6, 0 }; @@ -727,7 +735,7 @@ void AnimationSequencePlayer::loadSounds(int type, int num) { if (_musicVolume != 0) { Audio::AudioStream *s; if ((s = loadSoundFileAsStream(_musicFileNamesTable[index], (type == 5) ? kAnimationSoundType16BitsRAW : kAnimationSoundType8BitsRAW)) != 0) { - _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, s, -1, _musicVolume * Audio::Mixer::kMaxChannelVolume / 100); + _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, s, -1, scaleMixerVolume(_musicVolume)); } } } @@ -741,14 +749,14 @@ void AnimationSequencePlayer::updateSounds() { case 0: if ((index = p[1]) < _soundsList1Count) { if ((s = loadSoundFileAsStream(_soundsList1[index], kAnimationSoundTypeWAV)) != 0) { - _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_soundsHandle[index], s, -1, p[3] * Audio::Mixer::kMaxChannelVolume / 100); + _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_soundsHandle[index], s, -1, scaleMixerVolume(p[3])); } } break; case 1: if ((index = p[1]) < _soundsList1Count) { if ((s = loadSoundFileAsStream(_soundsList1[index], kAnimationSoundTypeLoopingWAV)) != 0) { - _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_soundsHandle[index], s, -1, p[3] * Audio::Mixer::kMaxChannelVolume / 100); + _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_soundsHandle[index], s, -1, scaleMixerVolume(p[3])); } } break; @@ -765,13 +773,13 @@ void AnimationSequencePlayer::updateSounds() { index = p[1]; if ((s = loadSoundFileAsStream(_musicFileNamesTable[index], kAnimationSoundType8BitsRAW)) != 0) { _musicVolume = p[3]; - _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, s, -1, _musicVolume * Audio::Mixer::kMaxChannelVolume / 100); + _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, s, -1, scaleMixerVolume(_musicVolume)); } break; case 5: if ((index = p[1]) < _soundsList2Count) { if ((s = loadSoundFileAsStream(_soundsList2[index], kAnimationSoundTypeWAV)) != 0) { - _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, s, -1, p[3] * Audio::Mixer::kMaxChannelVolume / 100); + _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, s, -1, scaleMixerVolume(p[3])); } } break; @@ -780,7 +788,7 @@ void AnimationSequencePlayer::updateSounds() { index = p[1]; if ((s = loadSoundFileAsStream(_musicFileNamesTable[index], kAnimationSoundType16BitsRAW)) != 0) { _musicVolume = p[3]; - _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, s, -1, _musicVolume * Audio::Mixer::kMaxChannelVolume / 100); + _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, s, -1, scaleMixerVolume(_musicVolume)); } break; default: diff --git a/engines/tucker/staticres.cpp b/engines/tucker/staticres.cpp index e5e41166df..0db11899ab 100644 --- a/engines/tucker/staticres.cpp +++ b/engines/tucker/staticres.cpp @@ -234,14 +234,6 @@ const uint8 TuckerEngine::_charWidthCharset2[58] = { 0x13, 0x12, 0x10, 0x11, 0x13, 0x14, 0x14, 0x10, 0x13, 0x10, }; -const Graphics::Charset Graphics::_enCharset = { 10, 8, 32, 3 }; - -const Graphics::Charset Graphics::_frCharset = { 10, 10, 32, 7 }; - -const Graphics::Charset Graphics::_creditsCharset = { 19, 10, 16, 7 }; - -const Graphics::Charset *Graphics::_charset = 0; - // timestamp, index, opcode, volume const int AnimationSequencePlayer::_soundSeqData1[1] = { diff --git a/engines/tucker/tucker.cpp b/engines/tucker/tucker.cpp index 93f16a68d4..6d5740ff2f 100644 --- a/engines/tucker/tucker.cpp +++ b/engines/tucker/tucker.cpp @@ -43,22 +43,23 @@ TuckerEngine::~TuckerEngine() { Common::Error TuckerEngine::init() { initGraphics(kScreenWidth, kScreenHeight, false); - - _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); + syncSoundSettings(); return Common::kNoError; } bool TuckerEngine::hasFeature(EngineFeature f) const { - return (f == kSupportsRTL); + switch (f) { + case kSupportsRTL: + case kSupportsLoadingDuringRuntime: + case kSupportsSavingDuringRuntime: + return true; + default: + return false; + } } Common::Error TuckerEngine::go() { - const int firstSequence = _isDemo ? kFirstAnimationSequenceDemo : kFirstAnimationSequenceGame; - AnimationSequencePlayer *player = new AnimationSequencePlayer(_system, _mixer, _eventMan, firstSequence); - player->mainLoop(); - delete player; + handleIntroSequence(); if (!_isDemo && !shouldQuit()) { mainLoop(); } @@ -66,7 +67,9 @@ Common::Error TuckerEngine::go() { } void TuckerEngine::syncSoundSettings() { - // TODO + _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); + _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); } int TuckerEngine::getRandomNumber() { @@ -1293,9 +1296,9 @@ void TuckerEngine::saveOrLoad() { } if (_mousePosX > 260 && _mousePosX < 290 && _mousePosY > 152 && _mousePosY < 168) { if (_saveOrLoadGamePanel == 1) { - saveGame(_currentSaveLoadGameState); + saveGameState(_currentSaveLoadGameState, ""); } else if (_currentSaveLoadGameState > 0) { - loadGame(_currentSaveLoadGameState); + loadGameState(_currentSaveLoadGameState); } _forceRedrawPanelItems = 1; _panelState = 0; @@ -1897,7 +1900,7 @@ void TuckerEngine::drawInfoString() { } } infoStringWidth += verbPrepositionWidth; - if (_actionObj2Num > 0) { + if (_actionObj2Num > 0 || _actionObj2Type > 0) { infoStringWidth += getStringWidth(_actionObj2Num + 1, obj2StrBuf); } } diff --git a/engines/tucker/tucker.h b/engines/tucker/tucker.h index be51ce5a56..5dde36fb21 100644 --- a/engines/tucker/tucker.h +++ b/engines/tucker/tucker.h @@ -200,6 +200,14 @@ enum InputKey { kInputKeyCount }; +inline int scaleMixerVolume(int volume, int max = 100) { + return volume * Audio::Mixer::kMaxChannelVolume / max; +} + +Common::String generateGameStateFileName(const char *target, int slot, bool prefixOnly = false); + +class AnimationSequencePlayer; + class TuckerEngine: public Engine { public: @@ -505,11 +513,13 @@ protected: void updateSprite_locationNum81_1(int i); void updateSprite_locationNum82(int i); - void generateGameStateFileName(int num, char *dst, int len, bool prefixOnly = false) const; template <class S> void saveOrLoadGameStateData(S &s); - void loadGame(int slot); - void saveGame(int slot); + virtual Common::Error loadGameState(int num); + virtual Common::Error saveGameState(int num, const char *description); + virtual bool canLoadGameStateCurrently(); + virtual bool canSaveGameStateCurrently(); + void handleIntroSequence(); void handleCreditsSequence(); void handleCongratulationsSequence(); void handleNewPartSequence(); @@ -552,6 +562,7 @@ protected: Common::RandomSource _rnd; Common::Language _lang; bool _isDemo; + AnimationSequencePlayer *_player; bool _quitGame; bool _fastMode; |