aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
authorMatthew Hoops2011-06-13 13:12:23 -0400
committerMatthew Hoops2011-06-13 13:12:23 -0400
commitd355475a0416897ed254fa85f4d63d0f75d9c7ea (patch)
tree184892480ebb704b28163c51999e50c414e85f8a /engines/kyra
parent224c71e483e09931ba386555ff3b436b9defe63d (diff)
parentbfa26ffc44f80e4eb3d8590f5f865cda6a5188b7 (diff)
downloadscummvm-rg350-d355475a0416897ed254fa85f4d63d0f75d9c7ea.tar.gz
scummvm-rg350-d355475a0416897ed254fa85f4d63d0f75d9c7ea.tar.bz2
scummvm-rg350-d355475a0416897ed254fa85f4d63d0f75d9c7ea.zip
Merge remote branch 'upstream/master' into pegasus
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/animator_mr.cpp7
-rw-r--r--engines/kyra/detection.cpp32
-rw-r--r--engines/kyra/detection_tables.h105
-rw-r--r--engines/kyra/gui_lol.cpp15
-rw-r--r--engines/kyra/gui_mr.cpp20
-rw-r--r--engines/kyra/items_lol.cpp26
-rw-r--r--engines/kyra/kyra_mr.cpp33
-rw-r--r--engines/kyra/kyra_mr.h2
-rw-r--r--engines/kyra/kyra_v1.cpp77
-rw-r--r--engines/kyra/kyra_v1.h4
-rw-r--r--engines/kyra/lol.cpp74
-rw-r--r--engines/kyra/lol.h3
-rw-r--r--engines/kyra/scene_lol.cpp42
-rw-r--r--engines/kyra/script_lol.cpp41
-rw-r--r--engines/kyra/script_tim.cpp26
-rw-r--r--engines/kyra/sequences_lol.cpp72
-rw-r--r--engines/kyra/sound_lok.cpp5
-rw-r--r--engines/kyra/sound_lol.cpp40
-rw-r--r--engines/kyra/staticres.cpp2
-rw-r--r--engines/kyra/text_hof.cpp9
-rw-r--r--engines/kyra/text_mr.cpp12
21 files changed, 352 insertions, 295 deletions
diff --git a/engines/kyra/animator_mr.cpp b/engines/kyra/animator_mr.cpp
index 6db2e45b0e..84bda3f3fd 100644
--- a/engines/kyra/animator_mr.cpp
+++ b/engines/kyra/animator_mr.cpp
@@ -449,11 +449,10 @@ void KyraEngine_MR::showIdleAnim() {
"A", "R", "R", "FR", "FX", "FL", "L", "L"
};
- char filename[14];
- snprintf(filename, 14, "MI0%s%.02d.EMC", facingTable[_mainCharacter.facing], _characterShapeFile);
+ Common::String filename = Common::String::format( "MI0%s%.02d.EMC", facingTable[_mainCharacter.facing], _characterShapeFile);
- if (_res->exists(filename))
- runAnimationScript(filename, 1, 1, 1, 1);
+ if (_res->exists(filename.c_str()))
+ runAnimationScript(filename.c_str(), 1, 1, 1, 1);
}
_nextIdleType = !_nextIdleType;
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 47a086e08c..6589c2b45b 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -47,37 +47,15 @@ const char * const directoryGlobs[] = {
0
};
-static const ADParams detectionParams = {
- // Pointer to ADGameDescription or its superset structure
- (const byte *)adGameDescs,
- // Size of that superset structure
- sizeof(KYRAGameDescription),
- // Number of bytes to compute MD5 sum for
- 1024 * 1024,
- // List of all engine targets
- gameList,
- // Structure for autoupgrading obsolete targets
- 0,
- // Name of single gameid (optional)
- 0,
- // List of files for file-based fallback detection (optional)
- 0,
- // Flags
- 0,
- // Additional GUI options (for every game}
- Common::GUIO_NONE,
- // Maximum directory depth
- 2,
- // List of directory globs
- directoryGlobs
-};
-
} // End of anonymous namespace
class KyraMetaEngine : public AdvancedMetaEngine {
public:
- KyraMetaEngine() : AdvancedMetaEngine(detectionParams) {}
-
+ KyraMetaEngine() : AdvancedMetaEngine(adGameDescs, sizeof(KYRAGameDescription), gameList) {
+ params.md5Bytes = 1024 * 1024;
+ params.depth = 2;
+ params.directoryGlobs = directoryGlobs;
+ }
const char *getName() const {
return "Kyra";
}
diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h
index 8a948eff00..47a3c4362a 100644
--- a/engines/kyra/detection_tables.h
+++ b/engines/kyra/detection_tables.h
@@ -47,6 +47,7 @@ namespace {
#define KYRA3_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, true, false, Kyra::GI_KYRA3)
#define LOL_CD_FLAGS FLAGS(false, false, true, false, false, false, false, Kyra::GI_LOL)
+#define LOL_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, Kyra::GI_LOL)
#define LOL_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, Kyra::GI_LOL)
#define LOL_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, true, Kyra::GI_LOL)
#define LOL_PC98_SJIS_FLAGS FLAGS(false, false, false, true, true, false, false, Kyra::GI_LOL)
@@ -1056,6 +1057,109 @@ const KYRAGameDescription adGameDescs[] = {
LOL_CD_FLAGS
},
+ // Italian fan translation
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::IT_ITA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "9e4bab499b7ea9337b91ac29fcba6d13", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::IT_ITA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "9e4bab499b7ea9337b91ac29fcba6d13", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
+ {
+ {
+ "lol",
+ "CD",
+ {
+ { "GENERAL.PAK", 0, "9e4bab499b7ea9337b91ac29fcba6d13", -1 },
+ { "L01.PAK", 0, "898485c0eb7bb4403fdd63bf5191f37e", -1 },
+ { 0, 0, 0, 0 }
+ },
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ ADGF_DROPLANGUAGE | ADGF_CD,
+ Common::GUIO_MIDIADLIB | Common::GUIO_MIDIMT32 | Common::GUIO_MIDIGM | Common::GUIO_MIDIPCSPK
+ },
+ LOL_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
+ },
+
{
{
"lol",
@@ -1222,7 +1326,6 @@ const KYRAGameDescription adGameDescs[] = {
LOL_KYRA2_DEMO_FLAGS
},
#endif // ENABLE_LOL
-
{ AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0, 0) }
};
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp
index 4c4dc50503..fb11040168 100644
--- a/engines/kyra/gui_lol.cpp
+++ b/engines/kyra/gui_lol.cpp
@@ -2806,15 +2806,18 @@ int GUI_LoL::clickedOptionsMenu(Button *button) {
case 0xfff3:
_vm->_configVoice ^= 3;
break;
- case 0x4072:
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%02d.%s", _vm->_currentLevel, _vm->_languageExt[_vm->_lang]);
+ case 0x4072: {
+ Common::String filename;
+ filename = Common::String::format("LEVEL%02d.%s", _vm->_currentLevel, _vm->_languageExt[_vm->_lang]);
delete[] _vm->_levelLangFile;
- _vm->_levelLangFile = _vm->resource()->fileData(filename, 0);
- snprintf(filename, sizeof(filename), "LANDS.%s", _vm->_languageExt[_vm->_lang]);
+ _vm->_levelLangFile = _vm->resource()->fileData(filename.c_str(), 0);
+ filename = Common::String::format("LANDS.%s", _vm->_languageExt[_vm->_lang]);
delete[] _vm->_landsFile;
- _vm->_landsFile = _vm->resource()->fileData(filename, 0);
+ _vm->_landsFile = _vm->resource()->fileData(filename.c_str(), 0);
_newMenu = _lastMenu;
+ } break;
+ default:
+ // TODO: Is there anything we should do if we hit this case?
break;
}
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index 25a77c6cc8..32eb02e06d 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -717,25 +717,25 @@ void KyraEngine_MR::showAlbum() {
}
void KyraEngine_MR::loadAlbumPage() {
- char filename[16];
+ Common::String filename;
int num = _album.curPage / 2;
if (num == 0) {
- strcpy(filename, "ALBUM0.CPS");
+ filename = "ALBUM0.CPS";
} else if (num >= 1 && num <= 6) {
--num;
num %= 2;
- snprintf(filename, 16, "ALBUM%d.CPS", num+1);
+ filename = Common::String::format("ALBUM%d.CPS", num+1);
} else {
- strcpy(filename, "ALBUM3.CPS");
+ filename = "ALBUM3.CPS";
}
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 4, Screen::CR_NO_P_CHECK);
- _screen->loadBitmap(filename, 3, 3, 0);
+ _screen->loadBitmap(filename.c_str(), 3, 3, 0);
}
void KyraEngine_MR::loadAlbumPageWSA() {
- char filename[16];
+ Common::String filename;
_album.leftPage.curFrame = 0;
_album.leftPage.maxFrame = 0;
@@ -746,14 +746,14 @@ void KyraEngine_MR::loadAlbumPageWSA() {
_album.rightPage.wsa->close();
if (_album.curPage) {
- snprintf(filename, 16, "PAGE%x.WSA", _album.curPage);
- _album.leftPage.wsa->open(filename, 1, 0);
+ filename = Common::String::format("PAGE%x.WSA", _album.curPage);
+ _album.leftPage.wsa->open(filename.c_str(), 1, 0);
_album.leftPage.maxFrame = _album.leftPage.wsa->frames()-1;
}
if (_album.curPage != 14) {
- snprintf(filename, 16, "PAGE%x.WSA", _album.curPage+1);
- _album.rightPage.wsa->open(filename, 1, 0);
+ filename = Common::String::format("PAGE%x.WSA", _album.curPage+1);
+ _album.rightPage.wsa->open(filename.c_str(), 1, 0);
_album.rightPage.maxFrame = _album.leftPage.wsa->frames()-1;
}
}
diff --git a/engines/kyra/items_lol.cpp b/engines/kyra/items_lol.cpp
index b6388604f5..2cf2cb2c70 100644
--- a/engines/kyra/items_lol.cpp
+++ b/engines/kyra/items_lol.cpp
@@ -396,20 +396,20 @@ bool LoLEngine::launchObject(int objectType, Item item, int startX, int startY,
return true;
}
-void LoLEngine::endObjectFlight(FlyingObject *t, int x, int y, int objectOnNextBlock) {
+void LoLEngine::endObjectFlight(FlyingObject *t, int x, int y, int collisionObject) {
int cx = x;
int cy = y;
uint16 block = calcBlockIndex(t->x, t->y);
removeAssignedObjectFromBlock(&_levelBlockProperties[block], t->item);
removeDrawObjectFromBlock(&_levelBlockProperties[block], t->item);
- if (objectOnNextBlock == 1) {
+ if (collisionObject == 1) {
cx = t->x;
cy = t->y;
}
if (t->objectType == 0 || t->objectType == 1) {
- objectFlightProcessHits(t, cx, cy, objectOnNextBlock);
+ objectFlightProcessHits(t, cx, cy, collisionObject);
t->x = (cx & 0xffc0) | 0x40;
t->y = (cy & 0xffc0) | 0x40;
t->flyingHeight = 0;
@@ -481,8 +481,24 @@ void LoLEngine::updateFlyingObject(FlyingObject *t) {
int x = 0;
int y = 0;
getNextStepCoords(t->x, t->y, x, y, t->direction);
- // WORKAROUND: The next line seems to be bugged in the original code. I have fixed it in a way that at least seems to work fine.
- int objectOnNextBlock = checkBlockBeforeObjectPlacement(x, y, _itemProperties[_itemsInPlay[t->item].itemPropertyIndex].flags & 0x4000 ? 127 : 63, t->flags, t->wallFlags);
+ /* WORKAROUND:
+ Large fireballs cast by the "birds" in white tower level 2 and by the "wraith knights" in castle cimmeria
+ level 1 (or possible other objects with flag 0x4000) could not fly through corridors in ScummVM and would
+ be terminated prematurely. The original code (all versions) involuntarily circumvents this via a bug in the
+ next line of code.
+ The original checks for _itemProperties[t->item].flags instead of _itemProperties[_itemsInPlay[t->item].itemPropertyIndex].flags.
+ This leads to more or less unpredictable object widths. The large fireballs will usually get a width of 63
+ instead of 256 making them work just fine in the original.
+
+ I have fixed this by setting an object width of 63 of here. This produces results faithful to the original
+ at least.
+
+ Other methods of working around this issue don't make too much sense. An object with a width of 256
+ could never fly through corridors, since 256 is also the width of a block. Aligning the fireballs to the
+ middle of a block (or making the monsters align to the middle before casting them) wouldn't help here
+ (and wouldn't be faithful to the original either).
+ */
+ int objectOnNextBlock = checkBlockBeforeObjectPlacement(x, y, /*_itemProperties[_itemsInPlay[t->item].itemPropertyIndex].flags & 0x4000 ? 256 :*/ 63, t->flags, t->wallFlags);
if (objectOnNextBlock) {
endObjectFlight(t, x, y, objectOnNextBlock);
} else {
diff --git a/engines/kyra/kyra_mr.cpp b/engines/kyra/kyra_mr.cpp
index 4ce5c5b2cf..973ab25088 100644
--- a/engines/kyra/kyra_mr.cpp
+++ b/engines/kyra/kyra_mr.cpp
@@ -366,10 +366,9 @@ void KyraEngine_MR::uninitMainMenu() {
void KyraEngine_MR::playVQA(const char *name) {
VQAMovie vqa(this, _system);
- char filename[20];
- snprintf(filename, sizeof(filename), "%s%d.VQA", name, _configVQAQuality);
+ Common::String filename = Common::String::format("%s%d.VQA", name, _configVQAQuality);
- if (vqa.open(filename)) {
+ if (vqa.open(filename.c_str())) {
for (int i = 0; i < 4; ++i) {
if (i != _musicSoundChannel)
_soundDigital->stopSound(i);
@@ -444,12 +443,11 @@ void KyraEngine_MR::fadeOutMusic(int ticks) {
void KyraEngine_MR::snd_playSoundEffect(int item, int volume) {
if (_sfxFileMap[item*2+0] != 0xFF) {
- char filename[16];
assert(_sfxFileMap[item*2+0] < _sfxFileListSize);
- snprintf(filename, 16, "%s", _sfxFileList[_sfxFileMap[item*2+0]]);
+ Common::String filename = Common::String::format("%s", _sfxFileList[_sfxFileMap[item*2+0]]);
uint8 priority = _sfxFileMap[item*2+1];
- _soundDigital->playSound(filename, priority, Audio::Mixer::kSFXSoundType, volume);
+ _soundDigital->playSound(filename.c_str(), priority, Audio::Mixer::kSFXSoundType, volume);
}
}
@@ -458,11 +456,10 @@ void KyraEngine_MR::playVoice(int high, int low) {
}
void KyraEngine_MR::snd_playVoiceFile(int file) {
- char filename[16];
- snprintf(filename, 16, "%.08u", (uint)file);
+ Common::String filename = Common::String::format("%.08u", (uint)file);
if (speechEnabled())
- _voiceSoundChannel = _soundDigital->playSound(filename, 0xFE, Audio::Mixer::kSpeechSoundType, 255);
+ _voiceSoundChannel = _soundDigital->playSound(filename.c_str(), 0xFE, Audio::Mixer::kSpeechSoundType, 255);
}
bool KyraEngine_MR::snd_voiceIsPlaying() {
@@ -1242,26 +1239,14 @@ void KyraEngine_MR::restoreGfxRect32x32(int x, int y) {
#pragma mark -
-char *KyraEngine_MR::appendLanguage(char *buf, int lang, int bufSize) {
- assert(lang < _languageExtensionSize);
-
- const int size = Common::strlcat(buf, _languageExtension[lang], bufSize);
- if (size >= bufSize) {
- warning("buffer too small to append language extension");
- return 0;
- }
-
- return buf;
-}
-
int KyraEngine_MR::loadLanguageFile(const char *file, uint8 *&buffer) {
delete[] buffer;
buffer = 0;
uint32 size = 0;
- char nBuf[32];
- Common::strlcpy(nBuf, file, sizeof(nBuf));
- buffer = _res->fileData(appendLanguage(nBuf, _lang, sizeof(nBuf)), &size);
+ Common::String nBuf = file;
+ nBuf += _languageExtension[_lang];
+ buffer = _res->fileData(nBuf.c_str(), &size);
return buffer ? size : 0;
}
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index 0d9d66ce95..b762648d29 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -662,8 +662,6 @@ private:
static const char *_languageExtension[];
static const int _languageExtensionSize;
- char *appendLanguage(char *buf, int lang, int bufSize);
-
int loadLanguageFile(const char *file, uint8 *&buffer);
};
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index f108082e13..f79fabf9eb 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -93,15 +93,6 @@ Common::Error KyraEngine_v1::init() {
syncSoundSettings();
if (!_flags.useDigSound) {
- // In Kyra 1 users who have specified a default MT-32 device in the launcher settings
- // will get MT-32 music, otherwise AdLib. In Kyra 2 and LoL users who have specified a
- // default GM device in the launcher will get GM music, otherwise AdLib. Users who want
- // MT-32 music in Kyra2 or LoL have to select this individually (since we assume that
- // most users rather have a GM device than a MT-32 device).
- // Users who want PC speaker sound always have to select this individually for all
- // Kyra games.
- MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB | ((_flags.gameID == GI_KYRA2 || _flags.gameID == GI_LOL) ? MDT_PREFER_GM : MDT_PREFER_MT32));
-
if (_flags.platform == Common::kPlatformFMTowns) {
if (_flags.gameID == GI_KYRA1)
_sound = new SoundTowns(this, _mixer);
@@ -114,43 +105,53 @@ Common::Error KyraEngine_v1::init() {
_sound = new SoundTownsPC98_v2(this, _mixer);
} else if (_flags.platform == Common::kPlatformAmiga) {
_sound = new SoundAmiga(this, _mixer);
- } else if (MidiDriver::getMusicType(dev) == MT_ADLIB) {
- _sound = new SoundAdLibPC(this, _mixer);
} else {
- Sound::kType type;
- const MusicType midiType = MidiDriver::getMusicType(dev);
+ // In Kyra 1 users who have specified a default MT-32 device in the launcher settings
+ // will get MT-32 music, otherwise AdLib. In Kyra 2 and LoL users who have specified a
+ // default GM device in the launcher will get GM music, otherwise AdLib. Users who want
+ // MT-32 music in Kyra2 or LoL have to select this individually (since we assume that
+ // most users rather have a GM device than a MT-32 device).
+ // Users who want PC speaker sound always have to select this individually for all
+ // Kyra games.
+ MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB | ((_flags.gameID == GI_KYRA2 || _flags.gameID == GI_LOL) ? MDT_PREFER_GM : MDT_PREFER_MT32));
+ if (MidiDriver::getMusicType(dev) == MT_ADLIB) {
+ _sound = new SoundAdLibPC(this, _mixer);
+ } else {
+ Sound::kType type;
+ const MusicType midiType = MidiDriver::getMusicType(dev);
- if (midiType == MT_PCSPK || midiType == MT_NULL)
- type = Sound::kPCSpkr;
- else if (midiType == MT_MT32 || ConfMan.getBool("native_mt32"))
- type = Sound::kMidiMT32;
- else
- type = Sound::kMidiGM;
+ if (midiType == MT_PCSPK || midiType == MT_NULL)
+ type = Sound::kPCSpkr;
+ else if (midiType == MT_MT32 || ConfMan.getBool("native_mt32"))
+ type = Sound::kMidiMT32;
+ else
+ type = Sound::kMidiGM;
- MidiDriver *driver = 0;
+ MidiDriver *driver = 0;
- if (MidiDriver::getMusicType(dev) == MT_PCSPK) {
- driver = new MidiDriver_PCSpeaker(_mixer);
- } else {
- driver = MidiDriver::createMidi(dev);
- if (type == Sound::kMidiMT32)
- driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
- }
+ if (MidiDriver::getMusicType(dev) == MT_PCSPK) {
+ driver = new MidiDriver_PCSpeaker(_mixer);
+ } else {
+ driver = MidiDriver::createMidi(dev);
+ if (type == Sound::kMidiMT32)
+ driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
+ }
- assert(driver);
+ assert(driver);
- SoundMidiPC *soundMidiPc = new SoundMidiPC(this, _mixer, driver, type);
- _sound = soundMidiPc;
- assert(_sound);
+ SoundMidiPC *soundMidiPc = new SoundMidiPC(this, _mixer, driver, type);
+ _sound = soundMidiPc;
+ assert(_sound);
- // Unlike some SCUMM games, it's not that the MIDI sounds are
- // missing. It's just that at least at the time of writing they
- // are decidedly inferior to the AdLib ones.
- if (ConfMan.getBool("multi_midi")) {
- SoundAdLibPC *adlib = new SoundAdLibPC(this, _mixer);
- assert(adlib);
+ // Unlike some SCUMM games, it's not that the MIDI sounds are
+ // missing. It's just that at least at the time of writing they
+ // are decidedly inferior to the AdLib ones.
+ if (ConfMan.getBool("multi_midi")) {
+ SoundAdLibPC *adlib = new SoundAdLibPC(this, _mixer);
+ assert(adlib);
- _sound = new MixedSoundDriver(this, _mixer, soundMidiPc, adlib);
+ _sound = new MixedSoundDriver(this, _mixer, soundMidiPc, adlib);
+ }
}
}
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index bb533b14a5..5b4f3385a4 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -99,7 +99,7 @@ class KyraMetaEngine;
* - The Legend of Kyrandia (fully supported, except for Macintosh port, which lacks sound)
* - (The) Hand of Fate (fully supported)
* - Malcolm's Revenge (fully supported)
- * - Lands of Lore: The Throne of Chaos (completable, still work in progress)
+ * - Lands of Lore: The Throne of Chaos (fully supported)
*/
namespace Kyra {
@@ -418,7 +418,7 @@ protected:
void loadGameStateCheck(int slot);
virtual Common::Error loadGameState(int slot) = 0;
- Common::Error saveGameState(int slot, const char *saveName) { return saveGameStateIntern(slot, saveName, 0); }
+ Common::Error saveGameState(int slot, const Common::String &desc) { return saveGameStateIntern(slot, desc.c_str(), 0); }
virtual Common::Error saveGameStateIntern(int slot, const char *saveName, const Graphics::Surface *thumbnail) = 0;
Common::SeekableReadStream *openSaveForReading(const char *filename, SaveHeader &header);
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 9b0ae173d5..c567cbb037 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -42,9 +42,13 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_gui = 0;
_txt = 0;
_tim = 0;
- _animator = 0;
- switch (_flags.lang) {
+ _lang = 0;
+ Common::Language lang = Common::parseLanguage(ConfMan.get("language"));
+ if (lang == _flags.fanLang && _flags.replacedLang != Common::UNK_LANG)
+ lang = _flags.replacedLang;
+
+ switch (lang) {
case Common::EN_ANY:
case Common::EN_USA:
case Common::EN_GRB:
@@ -576,7 +580,6 @@ Common::Error LoLEngine::go() {
_tim = new TIMInterpreter_LoL(this, _screen, _system);
assert(_tim);
- _animator = _tim->animator();
if (shouldQuit())
return Common::kNoError;
@@ -613,11 +616,11 @@ void LoLEngine::preInit() {
loadTalkFile(0);
- char filename[32];
- snprintf(filename, sizeof(filename), "LANDS.%s", _languageExt[_lang]);
- _res->exists(filename, true);
+ Common::String filename;
+ filename = Common::String::format("LANDS.%s", _languageExt[_lang]);
+ _res->exists(filename.c_str(), true);
delete[] _landsFile;
- _landsFile = _res->fileData(filename, 0);
+ _landsFile = _res->fileData(filename.c_str(), 0);
loadItemIconShapes();
}
@@ -1163,9 +1166,8 @@ void LoLEngine::loadCharFaceShapes(int charNum, int id) {
if (id < 0)
id = -id;
- char file[13];
- snprintf(file, sizeof(file), "FACE%02d.SHP", id);
- _screen->loadBitmap(file, 3, 3, 0);
+ Common::String file = Common::String::format("FACE%02d.SHP", id);
+ _screen->loadBitmap(file.c_str(), 3, 3, 0);
const uint8 *p = _screen->getCPagePtr(3);
for (int i = 0; i < 40; i++) {
@@ -1811,29 +1813,26 @@ void LoLEngine::createTransparencyTables() {
}
void LoLEngine::updateSequenceBackgroundAnimations() {
- if (_updateFlags & 8 || !_animator)
+ if (_updateFlags & 8 || !_tim)
+ return;
+ if (!_tim->animator())
return;
for (int i = 0; i < 6; i++)
- _animator->update(i);
+ _tim->animator()->update(i);
}
void LoLEngine::loadTalkFile(int index) {
- char file[8];
-
if (index == _curTlkFile)
return;
- if (_curTlkFile > 0 && index > 0) {
- snprintf(file, sizeof(file), "%02d.TLK", _curTlkFile);
- _res->unloadPakFile(file);
- }
+ if (_curTlkFile > 0 && index > 0)
+ _res->unloadPakFile(Common::String::format("%02d.TLK", _curTlkFile));
if (index > 0)
_curTlkFile = index;
- snprintf(file, sizeof(file), "%02d.TLK", index);
- _res->loadPakFile(file);
+ _res->loadPakFile(Common::String::format("%02d.TLK", index));
}
int LoLEngine::characterSays(int track, int charId, bool redraw) {
@@ -2702,12 +2701,11 @@ int LoLEngine::processMagicMistOfDoom(int charNum, int spellLevel) {
snd_playSoundEffect(155, -1);
- char wsafile[13];
- snprintf(wsafile, 13, "mists%0d.wsa", spellLevel + 1);
+ Common::String wsafile = Common::String::format("mists%0d.wsa", spellLevel + 1);
WSAMovie_v2 *mov = new WSAMovie_v2(this);
- mov->open(wsafile, 1, 0);
+ mov->open(wsafile.c_str(), 1, 0);
if (!mov->opened())
- error("Mist: Unable to load mists.wsa");
+ error("Mist: Unable to load %s", wsafile.c_str());
snd_playSoundEffect(_mistAnimData[spellLevel].sound, -1);
playSpellAnimation(mov, _mistAnimData[spellLevel].part1First, _mistAnimData[spellLevel].part1Last, 7, 112, 0, 0, 0, 0, 0, false);
@@ -2720,7 +2718,7 @@ int LoLEngine::processMagicMistOfDoom(int charNum, int spellLevel) {
_screen->copyPage(12, 0);
updateDrawPage2();
- this->snd_playQueuedEffects();
+ snd_playQueuedEffects();
return 1;
}
@@ -2734,12 +2732,11 @@ int LoLEngine::processMagicLightning(int charNum, int spellLevel) {
_lightningDiv = _lightningProps[spellLevel].frameDiv;
_lightningFirstSfx = 0;
- char wsafile[13];
- snprintf(wsafile, 13, "litning%d.wsa", spellLevel + 1);
+ Common::String wsafile = Common::String::format("litning%d.wsa", spellLevel + 1);
WSAMovie_v2 *mov = new WSAMovie_v2(this);
- mov->open(wsafile, 1, 0);
+ mov->open(wsafile.c_str(), 1, 0);
if (!mov->opened())
- error("Litning: Unable to load litning.wsa");
+ error("Litning: Unable to load %s", wsafile.c_str());
for (int i = 0; i < 4; i++)
playSpellAnimation(mov, 0, _lightningProps[spellLevel].lastFrame, 3, 93, 0, &LoLEngine::callbackProcessMagicLightning, 0, 0, 0, false);
@@ -3139,11 +3136,10 @@ void LoLEngine::transferSpellToScollAnimation(int charNum, int spell, int slot)
int vX = _updateSpellBookCoords[slot << 1] + 32;
int vY = _updateSpellBookCoords[(slot << 1) + 1] + 5;
- char wsaFile[13];
+ Common::String wsaFile = Common::String::format("write%0d", spell);
if (_flags.isTalkie)
- snprintf(wsaFile, 13, "write%0d%c.wsa", spell, (_lang == 1) ? 'f' : (_lang == 0 ? 'e' : 'g'));
- else
- snprintf(wsaFile, 13, "write%0d.wsa", spell);
+ wsaFile += (_lang == 1) ? 'f' : (_lang == 0 ? 'e' : 'g');
+ wsaFile += ".wsa";
snd_playSoundEffect(_updateSpellBookAnimData[(spell << 2) + 3], -1);
snd_playSoundEffect(95, -1);
@@ -3187,7 +3183,7 @@ void LoLEngine::transferSpellToScollAnimation(int charNum, int spell, int slot)
playSpellAnimation(mov, 0, 6, 5, _updateSpellBookCoords[slot << 1], _updateSpellBookCoords[(slot << 1) + 1], 0, 0, 0, 0, false);
mov->close();
- mov->open(wsaFile, 0, 0);
+ mov->open(wsaFile.c_str(), 0, 0);
if (!mov->opened())
error("SpellBook: Unable to load spellbook anim");
snd_playSoundEffect(_updateSpellBookAnimData[(spell << 2) + 3], -1);
@@ -4160,10 +4156,9 @@ void LoLEngine::loadMapLegendData(int level) {
legendData[i * 6 + 5] = 0xffff;
}
- char file[13];
+ Common::String file = Common::String::format("level%d.xxx", level);
uint32 size = 0;
- snprintf(file, 12, "level%d.xxx", level);
- uint8 *data = _res->fileData(file, &size);
+ uint8 *data = _res->fileData(file.c_str(), &size);
uint8 *pos = data;
size = MIN<uint32>(size / 12, 32);
@@ -4531,10 +4526,9 @@ void LoLEngine::generateTempData() {
_lvlTempData[l]->monsters = new MonsterInPlay[30];
_lvlTempData[l]->flyingObjects = new FlyingObject[8];
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.CMZ", _currentLevel);
+ Common::String filename = Common::String::format("LEVEL%d.CMZ", _currentLevel);
- _screen->loadBitmap(filename, 15, 15, 0);
+ _screen->loadBitmap(filename.c_str(), 15, 15, 0);
const uint8 *p = _screen->getCPagePtr(14);
uint16 len = READ_LE_UINT16(p + 4);
p += 6;
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index a815fa1a37..943bb7f8d5 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -315,7 +315,6 @@ private:
GUI_LoL *_gui;
TIMInterpreter *_tim;
- TimAnimator *_animator;
Common::Error init();
Common::Error go();
@@ -1215,7 +1214,7 @@ private:
void setItemPosition(Item item, uint16 x, uint16 y, int flyingHeight, int b);
void removeLevelItem(Item item, int block);
bool launchObject(int objectType, Item item, int startX, int startY, int flyingHeight, int direction, int, int attackerId, int c);
- void endObjectFlight(FlyingObject *t, int x, int y, int objectOnNextBlock);
+ void endObjectFlight(FlyingObject *t, int x, int y, int collisionObject);
void processObjectFlight(FlyingObject *t, int x, int y);
void updateObjectFlightPosition(FlyingObject *t);
void objectFlightProcessHits(FlyingObject *t, int x, int y, int objectOnNextBlock);
diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index 305036fc51..165919dff2 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -67,18 +67,17 @@ void LoLEngine::loadLevel(int index) {
loadLevelWallData(index, true);
_loadLevelFlag = 1;
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.INI", index);
+ Common::String filename = Common::String::format("LEVEL%d.INI", index);
int f = _hasTempDataFlags & (1 << (index - 1));
- runInitScript(filename, f ? 0 : 1);
+ runInitScript(filename.c_str(), f ? 0 : 1);
if (f)
restoreBlockTempData(index);
- snprintf(filename, sizeof(filename), "LEVEL%d.INF", index);
- runInfScript(filename);
+ filename = Common::String::format("LEVEL%d.INF", index);
+ runInfScript(filename.c_str());
addLevelItems();
deleteMonstersFromBlock(_currentBlock);
@@ -142,11 +141,10 @@ void LoLEngine::assignBlockObject(LevelBlockProperty *l, uint16 item) {
}
void LoLEngine::loadLevelWallData(int index, bool mapShapes) {
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.WLL", index);
+ Common::String filename = Common::String::format("LEVEL%d.WLL", index);
uint32 size;
- uint8 *file = _res->fileData(filename, &size);
+ uint8 *file = _res->fileData(filename.c_str(), &size);
uint16 c = READ_LE_UINT16(file);
loadLevelShpDat(_levelShpList[c], _levelDatList[c], false);
@@ -241,10 +239,9 @@ void LoLEngine::restoreBlockTempData(int index) {
memcpy(_monsters, _lvlTempData[l]->monsters, sizeof(MonsterInPlay) * 30);
memcpy(_flyingObjects, _lvlTempData[l]->flyingObjects, sizeof(FlyingObject) * 8);
- char filename[13];
- snprintf(filename, sizeof(filename), "LEVEL%d.CMZ", index);
+ Common::String filename = Common::String::format("LEVEL%d.CMZ", index);
- _screen->loadBitmap(filename, 3, 3, 0);
+ _screen->loadBitmap(filename.c_str(), 3, 3, 0);
const uint8 *p = _screen->getCPagePtr(2);
uint16 len = READ_LE_UINT16(p + 4);
p += 6;
@@ -366,13 +363,13 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
_lastSpecialColor = 0x44;
}
- char fname[13];
+ Common::String fname;
const uint8 *v = 0;
int tlen = 0;
if (_flags.use16ColorMode) {
- snprintf(fname, sizeof(fname), "%s.VCF", _lastBlockDataFile);
- _screen->loadBitmap(fname, 3, 3, 0);
+ fname = Common::String::format("%s.VCF", _lastBlockDataFile);
+ _screen->loadBitmap(fname.c_str(), 3, 3, 0);
v = _screen->getCPagePtr(2);
tlen = READ_LE_UINT16(v) << 5;
v += 2;
@@ -383,8 +380,8 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
memcpy(_vcfBlocks, v, tlen);
}
- snprintf(fname, sizeof(fname), "%s.VCN", _lastBlockDataFile);
- _screen->loadBitmap(fname, 3, 3, 0);
+ fname = Common::String::format("%s.VCN", _lastBlockDataFile);
+ _screen->loadBitmap(fname.c_str(), 3, 3, 0);
v = _screen->getCPagePtr(2);
tlen = READ_LE_UINT16(v);
v += 2;
@@ -434,8 +431,8 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
memcpy(_vcnBlocks, v, vcnLen);
v += vcnLen;
- snprintf(fname, sizeof(fname), "%s.VMP", _lastBlockDataFile);
- _screen->loadBitmap(fname, 3, 3, 0);
+ fname = Common::String::format("%s.VMP", _lastBlockDataFile);
+ _screen->loadBitmap(fname.c_str(), 3, 3, 0);
v = _screen->getCPagePtr(2);
if (vmpLen == -1)
@@ -503,9 +500,7 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight
generateBrightnessPalette(_screen->getPalette(0), _screen->getPalette(1), _brightness, _lampEffect);
if (_flags.isTalkie) {
- char tname[13];
- snprintf(tname, sizeof(tname), "LEVEL%.02d.TLC", _currentLevel);
- Common::SeekableReadStream *s = _res->createReadStream(tname);
+ Common::SeekableReadStream *s = _res->createReadStream(Common::String::format("LEVEL%.02d.TLC", _currentLevel));
s->read(_transparencyTable1, 256);
s->read(_transparencyTable2, 5120);
delete s;
@@ -1375,9 +1370,8 @@ void LoLEngine::processGasExplosion(int soundId) {
if (dist) {
WSAMovie_v2 *mov = new WSAMovie_v2(this);
- char file[13];
- snprintf(file, 13, "gasexp%0d.wsa", dist);
- mov->open(file, 1, 0);
+ Common::String file = Common::String::format("gasexp%0d.wsa", dist);
+ mov->open(file.c_str(), 1, 0);
if (!mov->opened())
error("Gas: Unable to load gasexp.wsa");
diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp
index 2261ef8389..695528b8d1 100644
--- a/engines/kyra/script_lol.cpp
+++ b/engines/kyra/script_lol.cpp
@@ -524,7 +524,7 @@ int LoLEngine::olol_initAnimStruct(EMCState *script) {
int LoLEngine::olol_playAnimationPart(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playAnimationPart(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
- _animator->playPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ _tim->animator()->playPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
return 1;
}
@@ -593,13 +593,13 @@ int LoLEngine::olol_clearDialogueField(EMCState *script) {
int LoLEngine::olol_setupBackgroundAnimationPart(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setupBackgroundAnimationPart(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
- _animator->setupPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
+ _tim->animator()->setupPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
return 0;
}
int LoLEngine::olol_startBackgroundAnimation(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_startBackgroundAnimation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
- _animator->start(stackPos(0), stackPos(1));
+ _tim->animator()->start(stackPos(0), stackPos(1));
return 1;
}
@@ -629,7 +629,7 @@ int LoLEngine::olol_loadBitmap(EMCState *script) {
int LoLEngine::olol_stopBackgroundAnimation(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_stopBackgroundAnimation(%p) (%d)", (const void *)script, stackPos(0));
- _animator->stop(stackPos(0));
+ _tim->animator()->stop(stackPos(0));
return 1;
}
@@ -1136,9 +1136,8 @@ int LoLEngine::olol_loadTimScript(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadTimScript(%p) (%d, %s)", (const void *)script, stackPos(0), stackPosString(1));
if (_activeTim[stackPos(0)])
return 1;
- char file[13];
- snprintf(file, sizeof(file), "%s.TIM", stackPosString(1));
- _activeTim[stackPos(0)] = _tim->load(file, &_timIngameOpcodes);
+ Common::String file = Common::String::format("%s.TIM", stackPosString(1));
+ _activeTim[stackPos(0)] = _tim->load(file.c_str(), &_timIngameOpcodes);
return 1;
}
@@ -1185,10 +1184,9 @@ int LoLEngine::olol_giveItemToMonster(EMCState *script) {
int LoLEngine::olol_loadLangFile(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadLangFile(%p) (%s)", (const void *)script, stackPosString(0));
- char filename[13];
- snprintf(filename, sizeof(filename), "%s.%s", stackPosString(0), _languageExt[_lang]);
+ Common::String filename = Common::String::format("%s.%s", stackPosString(0), _languageExt[_lang]);
delete[] _levelLangFile;
- _levelLangFile = _res->fileData(filename, 0);
+ _levelLangFile = _res->fileData(filename.c_str(), 0);
return 1;
}
@@ -1440,7 +1438,10 @@ int LoLEngine::olol_playEndSequence(EMCState *script){
_screen->getPalette(1).clear();
showOutro(c, (_monsterDifficulty == 2));
- quitGame();
+ // Don't call quitGame() on a RTL request (because this would
+ // make the next game launched from the launcher quit instantly.
+ if (!shouldQuit())
+ quitGame();
return 0;
}
@@ -1983,7 +1984,7 @@ int LoLEngine::olol_removeInventoryItem(EMCState *script) {
int LoLEngine::olol_getAnimationLastPart(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getAnimationLastPart(%p) (%d)", (const void *)script, stackPos(0));
- return _animator->resetLastPart(stackPos(0));
+ return _tim->animator()->resetLastPart(stackPos(0));
}
int LoLEngine::olol_assignSpecialGuiShape(EMCState *script) {
@@ -2406,16 +2407,16 @@ int LoLEngine::tlol_processWsaFrame(const TIM *tim, const uint16 *param) {
const int y2 = param[3];
const int factor = MAX<int>(0, (int16)param[4]);
- const int x1 = _animator->getAnimX(animIndex);
- const int y1 = _animator->getAnimY(animIndex);
- const Movie *wsa = _animator->getWsaCPtr(animIndex);
+ const int x1 = _tim->animator()->getAnimX(animIndex);
+ const int y1 = _tim->animator()->getAnimY(animIndex);
+ const Movie *wsa = _tim->animator()->getWsaCPtr(animIndex);
int w1 = wsa->width();
int h1 = wsa->height();
int w2 = (w1 * factor) / 100;
int h2 = (h1 * factor) / 100;
- _animator->displayFrame(animIndex, 2, frame);
+ _tim->animator()->displayFrame(animIndex, 2, frame);
_screen->wsaFrameAnimationStep(x1, y1, x2, y2, w1, h1, w2, h2, 2, _flags.isDemo && _flags.platform != Common::kPlatformPC98 ? 0 : 8, 0);
if (!_flags.isDemo && _flags.platform != Common::kPlatformPC98)
_screen->checkedPageUpdate(8, 4);
@@ -2584,13 +2585,13 @@ int LoLEngine::tlol_playSoundEffect(const TIM *tim, const uint16 *param) {
int LoLEngine::tlol_startBackgroundAnimation(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_startBackgroundAnimation(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
- _animator->start(param[0], param[1]);
+ _tim->animator()->start(param[0], param[1]);
return 1;
}
int LoLEngine::tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_stopBackgroundAnimation(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
- _animator->stop(param[0]);
+ _tim->animator()->stop(param[0]);
return 1;
}
@@ -2674,12 +2675,12 @@ int LoLEngine::tlol_displayAnimFrame(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayAnimFrame(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
const int animIndex = tim->wsa[param[0]].anim - 1;
- const Movie *wsa = _animator->getWsaCPtr(animIndex);
+ const Movie *wsa = _tim->animator()->getWsaCPtr(animIndex);
if (param[1] == 0xFFFF) {
_screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK);
} else {
- _animator->displayFrame(animIndex, 2, param[1], 0);
+ _tim->animator()->displayFrame(animIndex, 2, param[1], 0);
_screen->copyRegion(wsa->xAdd(), wsa->yAdd(), wsa->xAdd(), wsa->yAdd(), wsa->width(), wsa->height(), 2, 0);
}
diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp
index 501ae2defd..6f0f0ab083 100644
--- a/engines/kyra/script_tim.cpp
+++ b/engines/kyra/script_tim.cpp
@@ -482,17 +482,16 @@ int TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y
wsaOpenFlags = 1;
}
- char file[32];
- snprintf(file, 32, "%s.WSA", filename);
+ Common::String file = Common::String::format("%s.WSA", filename);
- if (_vm->resource()->exists(file)) {
+ if (_vm->resource()->exists(file.c_str())) {
if (isLoLDemo)
wsa = new WSAMovie_v1(_vm);
else
wsa = new WSAMovie_v2(_vm);
assert(wsa);
- wsa->open(file, wsaOpenFlags, (index == 1) ? &_screen->getPalette(0) : 0);
+ wsa->open(file.c_str(), wsaOpenFlags, (index == 1) ? &_screen->getPalette(0) : 0);
}
if (wsa && wsa->opened()) {
@@ -526,10 +525,10 @@ int TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y
}
if (wsaFlags & 4) {
- snprintf(file, 32, "%s.CPS", filename);
+ file = Common::String::format("%s.CPS", filename);
- if (_vm->resource()->exists(file)) {
- _screen->loadBitmap(file, 3, 3, &_screen->getPalette(0));
+ if (_vm->resource()->exists(file.c_str())) {
+ _screen->loadBitmap(file.c_str(), 3, 3, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
if (_drawPage2)
_screen->checkedPageUpdate(8, 4);
@@ -550,10 +549,10 @@ int TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y
_screen->updateScreen();
}
- snprintf(file, 32, "%s.CPS", filename);
+ file = Common::String::format("%s.CPS", filename);
- if (_vm->resource()->exists(file)) {
- _screen->loadBitmap(file, 3, 3, &_screen->getPalette(0));
+ if (_vm->resource()->exists(file.c_str())) {
+ _screen->loadBitmap(file.c_str(), 3, 3, &_screen->getPalette(0));
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
if (_drawPage2)
_screen->checkedPageUpdate(8, 4);
@@ -922,13 +921,12 @@ int TIMInterpreter_LoL::initAnimStruct(int index, const char *filename, int x, i
if (wsaFlags & 8)
wsaOpenFlags |= 1;
- char file[32];
- snprintf(file, 32, "%s.WSA", filename);
+ Common::String file = Common::String::format("%s.WSA", filename);
- if (_vm->resource()->exists(file)) {
+ if (_vm->resource()->exists(file.c_str())) {
wsa = new WSAMovie_v2(_vm);
assert(wsa);
- wsa->open(file, wsaOpenFlags, &_screen->getPalette(3));
+ wsa->open(file.c_str(), wsaOpenFlags, &_screen->getPalette(3));
}
if (!_vm->_flags.use16ColorMode) {
diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp
index d11403ad9f..01bf3c5e26 100644
--- a/engines/kyra/sequences_lol.cpp
+++ b/engines/kyra/sequences_lol.cpp
@@ -202,8 +202,7 @@ void LoLEngine::setupPrologueData(bool load) {
void LoLEngine::showIntro() {
_tim = new TIMInterpreter(this, _screen, _system);
assert(_tim);
- _animator = _tim->animator();
-
+
if (_flags.platform == Common::kPlatformPC98)
showStarcraftLogo();
@@ -262,7 +261,6 @@ void LoLEngine::showIntro() {
delete _tim;
_tim = 0;
- _animator = 0;
_screen->fadePalette(_screen->getPalette(1), 30, 0);
}
@@ -270,7 +268,6 @@ void LoLEngine::showIntro() {
int LoLEngine::chooseCharacter() {
_tim = new TIMInterpreter(this, _screen, _system);
assert(_tim);
- _animator = _tim->animator();
_tim->setLangData("LOLINTRO.DIP");
@@ -309,9 +306,8 @@ int LoLEngine::chooseCharacter() {
Screen::FontId old = _screen->setFont(Screen::FID_SJIS_FNT);
for (int j = 0; j < 3; ++j) {
- char buffer[3];
- snprintf(buffer, sizeof(buffer), "%2d", _charPreviews[i].attrib[j]);
- _screen->printText(buffer, _charPosXPC98[i] + 16, 176 + j * 8, 0x81, 0x00);
+ Common::String attribString = Common::String::format("%2d", _charPreviews[i].attrib[j]);
+ _screen->printText(attribString.c_str(), _charPosXPC98[i] + 16, 176 + j * 8, 0x81, 0x00);
}
_screen->setFont(old);
}
@@ -387,7 +383,6 @@ int LoLEngine::chooseCharacter() {
delete _tim;
_tim = 0;
- _animator = 0;
return _charSelection;
}
@@ -1061,7 +1056,6 @@ void LoLEngine::showOutro(int character, bool maxDifficulty) {
setupEpilogueData(true);
TIMInterpreter *timBackUp = _tim;
_tim = new TIMInterpreter(this, _screen, _system);
- _animator = _tim->animator();
_screen->getPalette(0).clear();
_screen->setScreenPalette(_screen->getPalette(0));
@@ -1117,47 +1111,49 @@ void LoLEngine::showOutro(int character, bool maxDifficulty) {
_screen->fadeToBlack(30);
- showCredits();
+ if (!shouldQuit())
+ showCredits();
_eventList.clear();
+
+ if (!shouldQuit()) {
+ switch (character) {
+ case 0:
+ _screen->loadBitmap("KIERAN.CPS", 3, 3, &_screen->getPalette(0));
+ break;
- switch (character) {
- case 0:
- _screen->loadBitmap("KIERAN.CPS", 3, 3, &_screen->getPalette(0));
- break;
-
- case 1:
- _screen->loadBitmap("AK'SHEL.CPS", 3, 3, &_screen->getPalette(0));
- break;
+ case 1:
+ _screen->loadBitmap("AK'SHEL.CPS", 3, 3, &_screen->getPalette(0));
+ break;
- case 2:
- _screen->loadBitmap("MICHAEL.CPS", 3, 3, &_screen->getPalette(0));
- break;
+ case 2:
+ _screen->loadBitmap("MICHAEL.CPS", 3, 3, &_screen->getPalette(0));
+ break;
- case 3:
- _screen->loadBitmap("CONRAD.CPS", 3, 3, &_screen->getPalette(0));
- break;
+ case 3:
+ _screen->loadBitmap("CONRAD.CPS", 3, 3, &_screen->getPalette(0));
+ break;
- default:
- _screen->clearPage(3);
- _screen->getPalette(0).clear();
- }
+ default:
+ _screen->clearPage(3);
+ _screen->getPalette(0).clear();
+ }
- _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
- if (maxDifficulty && !_flags.use16ColorMode)
- _tim->displayText(0x8000, 0, 0xDC);
- _screen->updateScreen();
- _screen->fadePalette(_screen->getPalette(0), 30, 0);
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
+ if (maxDifficulty && !_flags.use16ColorMode)
+ _tim->displayText(0x8000, 0, 0xDC);
+ _screen->updateScreen();
+ _screen->fadePalette(_screen->getPalette(0), 30, 0);
- while (!checkInput(0) && !shouldQuit())
- delay(_tickLength);
+ while (!checkInput(0) && !shouldQuit())
+ delay(_tickLength);
- _screen->fadeToBlack(30);
+ _screen->fadeToBlack(30);
+ }
_tim->clearLangData();
delete _tim;
_tim = timBackUp;
- _animator = 0;
setupEpilogueData(false);
}
@@ -1245,7 +1241,7 @@ void LoLEngine::processCredits(char *t, int dimState, int page, int delayTime) {
int curShapeFile = 0;
uint8 *shapes[12];
- memset(&shapes, 0, sizeof(shapes));
+ memset(shapes, 0, sizeof(shapes));
loadOutroShapes(curShapeFile++, shapes);
uint8 *monsterPal = 0;
diff --git a/engines/kyra/sound_lok.cpp b/engines/kyra/sound_lok.cpp
index 95a632c08c..b2a9c2fd93 100644
--- a/engines/kyra/sound_lok.cpp
+++ b/engines/kyra/sound_lok.cpp
@@ -74,9 +74,8 @@ void KyraEngine_LoK::snd_playWanderScoreViaMap(int command, int restart) {
}
void KyraEngine_LoK::snd_playVoiceFile(int id) {
- char vocFile[9];
- snprintf(vocFile, sizeof(vocFile), "%03d", id);
- _speechPlayTime = _sound->voicePlay(vocFile, &_speechHandle);
+ Common::String vocFile = Common::String::format("%03d", id);
+ _speechPlayTime = _sound->voicePlay(vocFile.c_str(), &_speechHandle);
}
void KyraEngine_LoK::snd_voiceWaitForFinish(bool ingame) {
diff --git a/engines/kyra/sound_lol.cpp b/engines/kyra/sound_lol.cpp
index a7776f0ab6..7262635728 100644
--- a/engines/kyra/sound_lol.cpp
+++ b/engines/kyra/sound_lol.cpp
@@ -50,36 +50,34 @@ bool LoLEngine::snd_playCharacterSpeech(int id, int8 speaker, int) {
_lastSpeaker = speaker;
_nextSpeechId = _nextSpeaker = -1;
- char pattern1[8];
- char pattern2[5];
- char file1[13];
- char file2[13];
- char file3[13];
- file3[0] = 0;
+ Common::String pattern1;
+ Common::String file1;
+ Common::String file2;
+ Common::String file3;
SpeechList newSpeechList;
- snprintf(pattern2, sizeof(pattern2), "%02d", id & 0x4000 ? 0 : _curTlkFile);
+ Common::String pattern2 = Common::String::format("%02d", id & 0x4000 ? 0 : _curTlkFile);
if (id & 0x4000) {
- snprintf(pattern1, sizeof(pattern1), "%03X", id & 0x3fff);
+ pattern1 = Common::String::format("%03X", id & 0x3fff);
} else if (id < 1000) {
- snprintf(pattern1, sizeof(pattern1), "%03d", id);
+ pattern1 = Common::String::format("%03d", id);
} else {
- snprintf(file3, sizeof(file3), "@%04d%c.%s", id - 1000, (char)speaker, pattern2);
- if (_sound->isVoicePresent(file3))
- newSpeechList.push_back(_sound->getVoiceStream(file3));
+ file3 = Common::String::format("@%04d%c.%s", id - 1000, (char)speaker, pattern2.c_str());
+ if (_sound->isVoicePresent(file3.c_str()))
+ newSpeechList.push_back(_sound->getVoiceStream(file3.c_str()));
}
- if (!file3[0]) {
+ if (file3.empty()) {
for (char i = 0; ; i++) {
char symbol = '0' + i;
- snprintf(file1, sizeof(file1), "%s%c%c.%s", pattern1, (char)speaker, symbol, pattern2);
- snprintf(file2, sizeof(file2), "%s%c%c.%s", pattern1, '_', symbol, pattern2);
- if (_sound->isVoicePresent(file1))
- newSpeechList.push_back(_sound->getVoiceStream(file1));
- else if (_sound->isVoicePresent(file2))
- newSpeechList.push_back(_sound->getVoiceStream(file2));
+ file1 = Common::String::format("%s%c%c.%s", pattern1.c_str(), (char)speaker, symbol, pattern2.c_str());
+ file2 = Common::String::format("%s%c%c.%s", pattern1.c_str(), '_', symbol, pattern2.c_str());
+ if (_sound->isVoicePresent(file1.c_str()))
+ newSpeechList.push_back(_sound->getVoiceStream(file1.c_str()));
+ else if (_sound->isVoicePresent(file2.c_str()))
+ newSpeechList.push_back(_sound->getVoiceStream(file2.c_str()));
else
break;
}
@@ -260,9 +258,7 @@ void LoLEngine::snd_loadSoundFile(int track) {
int t = (track - 250) * 3;
if (_curMusicFileIndex != _musicTrackMap[t] || _curMusicFileExt != (char)_musicTrackMap[t + 1]) {
snd_stopMusic();
- char filename[13];
- snprintf(filename, sizeof(filename), "LORE%02d%c", _musicTrackMap[t], (char)_musicTrackMap[t + 1]);
- _sound->loadSoundFile(filename);
+ _sound->loadSoundFile(Common::String::format("LORE%02d%c", _musicTrackMap[t], (char)_musicTrackMap[t + 1]));
_curMusicFileIndex = _musicTrackMap[t];
_curMusicFileExt = (char)_musicTrackMap[t + 1];
} else {
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 499cc6f301..d56abc5d47 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -38,7 +38,7 @@
namespace Kyra {
-#define RESFILE_VERSION 73
+#define RESFILE_VERSION 74
namespace {
bool checkKyraDat(Common::SeekableReadStream *file) {
diff --git a/engines/kyra/text_hof.cpp b/engines/kyra/text_hof.cpp
index 393fa8d11f..4406f3ec41 100644
--- a/engines/kyra/text_hof.cpp
+++ b/engines/kyra/text_hof.cpp
@@ -436,15 +436,16 @@ void KyraEngine_HoF::updateDlgBuffer() {
_npcTalkChpIndex = _currentChapter;
_npcTalkDlgIndex = _mainCharacter.dlgIndex;
- char filename[13];
- snprintf(filename, 13, "CH%.02d-S%.02d.DLG", _currentChapter, _npcTalkDlgIndex);
+ Common::String filename = Common::String::format("CH%.02d-S%.02d.DL", _currentChapter, _npcTalkDlgIndex);
const char *suffix = _flags.isTalkie ? suffixTalkie : suffixTowns;
if (_flags.platform != Common::kPlatformPC || _flags.isTalkie)
- filename[11] = suffix[_lang];
+ filename += suffix[_lang];
+ else
+ filename += 'G';
delete[] _dlgBuffer;
- _dlgBuffer = _res->fileData(filename, 0);
+ _dlgBuffer = _res->fileData(filename.c_str(), 0);
}
void KyraEngine_HoF::loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2) {
diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp
index 2cb752fdb3..d690b70266 100644
--- a/engines/kyra/text_mr.cpp
+++ b/engines/kyra/text_mr.cpp
@@ -625,24 +625,20 @@ void KyraEngine_MR::malcolmSceneStartupChat() {
}
void KyraEngine_MR::updateDlgBuffer() {
- char dlgFile[16];
- char cnvFile[16];
-
if (_cnvFile)
_cnvFile->seek(0, SEEK_SET);
if (_curDlgIndex == _mainCharacter.dlgIndex && _curDlgChapter == _currentChapter && _curDlgLang == _lang)
return;
- snprintf(dlgFile, 16, "CH%.02d-S%.02d.", _currentChapter, _mainCharacter.dlgIndex);
- appendLanguage(dlgFile, _lang, 16);
- snprintf(cnvFile, 16, "CH%.02d-S%.02d.CNV", _currentChapter, _mainCharacter.dlgIndex);
+ Common::String dlgFile = Common::String::format("CH%.02d-S%.02d.%s", _currentChapter, _mainCharacter.dlgIndex, _languageExtension[_lang]);
+ Common::String cnvFile = Common::String::format("CH%.02d-S%.02d.CNV", _currentChapter, _mainCharacter.dlgIndex);
delete _cnvFile;
delete _dlgBuffer;
- _res->exists(cnvFile, true);
- _res->exists(dlgFile, true);
+ _res->exists(cnvFile.c_str(), true);
+ _res->exists(dlgFile.c_str(), true);
_cnvFile = _res->createReadStream(cnvFile);
_dlgBuffer = _res->createReadStream(dlgFile);
assert(_cnvFile);