aboutsummaryrefslogtreecommitdiff
path: root/engines/tucker
diff options
context:
space:
mode:
authorGregory Montoir2008-11-28 23:56:25 +0000
committerGregory Montoir2008-11-28 23:56:25 +0000
commit362bdf87d78f611f3e308e7e9234831208b93d68 (patch)
tree41cf8bb25390cc1ed37d9ccdea87856b68a101eb /engines/tucker
parent443c57146d74d7a92d1c9ec48c0f7eb8a497749b (diff)
downloadscummvm-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.cpp40
-rw-r--r--engines/tucker/graphics.cpp37
-rw-r--r--engines/tucker/graphics.h26
-rw-r--r--engines/tucker/resource.cpp16
-rw-r--r--engines/tucker/saveload.cpp46
-rw-r--r--engines/tucker/sequences.cpp20
-rw-r--r--engines/tucker/staticres.cpp8
-rw-r--r--engines/tucker/tucker.cpp29
-rw-r--r--engines/tucker/tucker.h17
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;