diff options
Diffstat (limited to 'engines/sky')
| -rw-r--r-- | engines/sky/compact.cpp | 29 | ||||
| -rw-r--r-- | engines/sky/compact.h | 2 | ||||
| -rw-r--r-- | engines/sky/control.cpp | 39 | ||||
| -rw-r--r-- | engines/sky/control.h | 2 | ||||
| -rw-r--r-- | engines/sky/detection.cpp | 4 | ||||
| -rw-r--r-- | engines/sky/logic.cpp | 130 | ||||
| -rw-r--r-- | engines/sky/logic.h | 2 | ||||
| -rw-r--r-- | engines/sky/music/adlibchannel.cpp | 2 | ||||
| -rw-r--r-- | engines/sky/music/adlibchannel.h | 5 | ||||
| -rw-r--r-- | engines/sky/music/adlibmusic.cpp | 6 | ||||
| -rw-r--r-- | engines/sky/music/adlibmusic.h | 5 | ||||
| -rw-r--r-- | engines/sky/sky.h | 4 | ||||
| -rw-r--r-- | engines/sky/skydefs.h | 1 |
13 files changed, 123 insertions, 108 deletions
diff --git a/engines/sky/compact.cpp b/engines/sky/compact.cpp index ee165934a0..ab244c1f84 100644 --- a/engines/sky/compact.cpp +++ b/engines/sky/compact.cpp @@ -126,11 +126,11 @@ static const uint32 turnTableOffsets[] = { SkyCompact::SkyCompact() { _cptFile = new Common::File(); - if (!_cptFile->open("sky.cpt")) { - GUI::MessageDialog dialog(_("Unable to find \"sky.cpt\" file!\n" - "Please download it from www.scummvm.org"), _("OK"), NULL); - dialog.runModal(); - error("Unable to find \"sky.cpt\" file\nPlease download it from www.scummvm.org"); + Common::String filename = "sky.cpt"; + if (!_cptFile->open(filename.c_str())) { + Common::String msg = Common::String::format(_("Unable to locate the '%s' engine data file."), filename.c_str()); + GUIErrorMessage(msg); + error("%s", msg.c_str()); } uint16 fileVersion = _cptFile->readUint16LE(); @@ -138,7 +138,7 @@ SkyCompact::SkyCompact() { error("unknown \"sky.cpt\" version"); if (SKY_CPT_SIZE != _cptFile->size()) { - GUI::MessageDialog dialog(_("The \"sky.cpt\" file has an incorrect size.\nPlease (re)download it from www.scummvm.org"), _("OK"), NULL); + GUI::MessageDialog dialog(_("The \"sky.cpt\" engine data file has an incorrect size."), _("OK"), NULL); dialog.runModal(); error("Incorrect sky.cpt size (%d, expected: %d)", _cptFile->size(), SKY_CPT_SIZE); } @@ -236,6 +236,8 @@ SkyCompact::SkyCompact() { for (cnt = 0; cnt < _numSaveIds; cnt++) _saveIds[cnt] = FROM_LE_16(_saveIds[cnt]); _resetDataPos = _cptFile->pos(); + + checkAndFixOfficerBluntError(); } SkyCompact::~SkyCompact() { @@ -257,6 +259,21 @@ SkyCompact::~SkyCompact() { delete _cptFile; } +/* WORKAROUND for bug #2687: + The first release of scummvm with externalized, binary compact data has one broken 16 bit reference. + When talking to Officer Blunt on ground level while in a crouched position, the game enters an + unfinishable state because Blunt jumps into the lake and can no longer be interacted with. + This fixes the problem when playing with a broken sky.cpt */ +#define SCUMMVM_BROKEN_TALK_INDEX 158 +void SkyCompact::checkAndFixOfficerBluntError() { + // Retrieve the table with the animation ids to use for talking + uint16 *talkTable = (uint16*)fetchCpt(CPT_TALK_TABLE_LIST); + if (talkTable[SCUMMVM_BROKEN_TALK_INDEX] == ID_SC31_GUARD_TALK) { + debug(1, "SKY.CPT with Officer Blunt bug encountered, fixing talk gfx."); + talkTable[SCUMMVM_BROKEN_TALK_INDEX] = ID_SC31_GUARD_TALK2; + } +} + // needed for some workaround where the engine has to check if it's currently processing joey, for example bool SkyCompact::cptIsId(Compact *cpt, uint16 id) { return (cpt == fetchCpt(id)); diff --git a/engines/sky/compact.h b/engines/sky/compact.h index 0bd5b4943b..86db0ba55b 100644 --- a/engines/sky/compact.h +++ b/engines/sky/compact.h @@ -78,6 +78,8 @@ public: uint16 giveDataListLen(uint16 listNum); const char *nameForType(uint16 type); private: + void checkAndFixOfficerBluntError(); + uint16 _numDataLists; uint16 *_dataListLen; uint16 *_rawBuf; diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp index dfdd765120..a3fef3c0cd 100644 --- a/engines/sky/control.cpp +++ b/engines/sky/control.cpp @@ -167,7 +167,7 @@ ControlStatus::~ControlStatus() { void ControlStatus::setToText(const char *newText) { char tmpLine[256]; - strcpy(tmpLine, newText); + Common::strlcpy(tmpLine, newText, 256); if (_textData) { _statusText->flushForRedraw(); free(_textData); @@ -324,7 +324,11 @@ void Control::initPanel() { } void Control::buttonControl(ConResource *pButton) { - char autoSave[] = "Restore Autosave"; + char autoSave[50] = "Restore Autosave"; + + if (Common::parseLanguage(ConfMan.get("language")) == Common::RU_RUS) + strncpy(autoSave, "Zarpyzit/ abtocoxpahehie", 50); + if (pButton == NULL) { free(_textSprite); _textSprite = NULL; @@ -398,7 +402,8 @@ void Control::animClick(ConResource *pButton) { void Control::drawMainPanel() { memset(_screenBuf, 0, GAME_SCREEN_WIDTH * FULL_SCREEN_HEIGHT); _system->copyRectToScreen(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT); - _controlPanel->drawToScreen(NO_MASK); + if (_controlPanel) + _controlPanel->drawToScreen(NO_MASK); _exitButton->drawToScreen(NO_MASK); _savePanButton->drawToScreen(NO_MASK); _restorePanButton->drawToScreen(NO_MASK); @@ -525,8 +530,13 @@ void Control::doControlPanel() { } uint16 Control::handleClick(ConResource *pButton) { - char quitDos[] = "Quit to DOS?"; - char restart[] = "Restart?"; + char quitDos[50] = "Quit to DOS?"; + char restart[50] = "Restart?"; + + if (Common::parseLanguage(ConfMan.get("language")) == Common::RU_RUS) { + strncpy(quitDos, "B[uti b DOC?", 50); + strncpy(restart, "Hobaq irpa?", 50); + } switch (pButton->_onClick) { case DO_NOTHING: @@ -1328,13 +1338,13 @@ uint16 Control::parseSaveData(uint8 *srcBuf) { displayMessage(0, "Unknown save file revision (%d)", saveRev); return RESTORE_FAILED; } else if (saveRev < OLD_SAVEGAME_TYPE) { - displayMessage(0, "This savegame version is unsupported."); + displayMessage(0, "This saved game version is unsupported."); return RESTORE_FAILED; } LODSD(srcPos, gameVersion); if (gameVersion != SkyEngine::_systemVars.gameVersion) { if ((!SkyEngine::isCDVersion()) || (gameVersion < 365)) { // cd versions are compatible - displayMessage(NULL, "This savegame was created by\n" + displayMessage(NULL, "This saved game was created by\n" "Beneath a Steel Sky v0.0%03d\n" "It cannot be loaded by this version (v0.0%3d)", gameVersion, SkyEngine::_systemVars.gameVersion); @@ -1562,8 +1572,13 @@ void Control::showGameQuitMsg() { screenData = _skyScreen->giveCurrent(); - _skyText->displayText(_quitTexts[SkyEngine::_systemVars.language * 2 + 0], textBuf1, true, 320, 255); - _skyText->displayText(_quitTexts[SkyEngine::_systemVars.language * 2 + 1], textBuf2, true, 320, 255); + if (Common::parseLanguage(ConfMan.get("language")) == Common::RU_RUS) { + _skyText->displayText(_quitTexts[8 * 2 + 0], textBuf1, true, 320, 255); + _skyText->displayText(_quitTexts[8 * 2 + 1], textBuf2, true, 320, 255); + } else { + _skyText->displayText(_quitTexts[SkyEngine::_systemVars.language * 2 + 0], textBuf1, true, 320, 255); + _skyText->displayText(_quitTexts[SkyEngine::_systemVars.language * 2 + 1], textBuf2, true, 320, 255); + } uint8 *curLine1 = textBuf1 + sizeof(DataFileHeader); uint8 *curLine2 = textBuf2 + sizeof(DataFileHeader); uint8 *targetLine = screenData + GAME_SCREEN_WIDTH * 80; @@ -1584,7 +1599,7 @@ void Control::showGameQuitMsg() { free(textBuf2); } -char Control::_quitTexts[16][35] = { +char Control::_quitTexts[18][35] = { "Game over player one", "BE VIGILANT", "Das Spiel ist aus.", @@ -1600,7 +1615,9 @@ char Control::_quitTexts[16][35] = { "Fim de jogo para o jogador um", "BE VIGILANT", "Game over player one", - "BE VIGILANT" + "BE VIGILANT", + "Irpa okohseha, irpok 1", + "JYD\x96 JDITELEH" }; uint8 Control::_crossImg[594] = { diff --git a/engines/sky/control.h b/engines/sky/control.h index 44591f299d..2089c74363 100644 --- a/engines/sky/control.h +++ b/engines/sky/control.h @@ -292,7 +292,7 @@ private: ControlStatus *_statusBar; - static char _quitTexts[16][35]; + static char _quitTexts[18][35]; static uint8 _crossImg[594]; }; diff --git a/engines/sky/detection.cpp b/engines/sky/detection.cpp index d85299cc24..4b91f50a61 100644 --- a/engines/sky/detection.cpp +++ b/engines/sky/detection.cpp @@ -136,7 +136,7 @@ const ExtraGuiOptions SkyMetaEngine::getExtraGuiOptions(const Common::String &ta } GameDescriptor SkyMetaEngine::findGame(const char *gameid) const { - if (0 == scumm_stricmp(gameid, skySetting.gameid)) + if (0 == scumm_stricmp(gameid, skySetting.gameId)) return skySetting; return GameDescriptor(); } @@ -175,7 +175,7 @@ GameList SkyMetaEngine::detectGames(const Common::FSList &fslist) const { // Match found, add to list of candidates, then abort inner loop. // The game detector uses US English by default. We want British // English to match the recorded voices better. - GameDescriptor dg(skySetting.gameid, skySetting.description, Common::UNK_LANG, Common::kPlatformUnknown); + GameDescriptor dg(skySetting.gameId, skySetting.description, Common::UNK_LANG, Common::kPlatformUnknown); const SkyVersion *sv = skyVersions; while (sv->dinnerTableEntries) { if (dinnerTableEntries == sv->dinnerTableEntries && diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp index e1175f9936..207db3b497 100644 --- a/engines/sky/logic.cpp +++ b/engines/sky/logic.cpp @@ -245,7 +245,7 @@ void Logic::arAnim() { // fine because the later collision will almost certainly // take longer to clear than the earlier one. - if (collide(_skyCompact->fetchCpt(_compact->waitingFor))) { + if (isCollision(_skyCompact->fetchCpt(_compact->waitingFor))) { stopAndWait(); return; } @@ -280,7 +280,7 @@ void Logic::arAnim() { if (cpt->screen != _compact->screen) // is it on our screen? continue; - if (collide(cpt)) { // check for a hit + if (isCollision(cpt)) { // check for a hit // ok, we've hit a mega // is it moving... or something else? @@ -627,7 +627,7 @@ void Logic::stopped() { Compact *cpt = _skyCompact->fetchCpt(_compact->waitingFor); if (cpt) - if (!cpt->mood && collide(cpt)) + if (!cpt->mood && isCollision(cpt)) return; // we are free, continue processing the script @@ -720,88 +720,56 @@ void Logic::simpleAnim() { logicScript(); } -bool Logic::collide(Compact *cpt) { - MegaSet *m1 = SkyCompact::getMegaSet(_compact); - MegaSet *m2 = SkyCompact::getMegaSet(cpt); +/** Checks if the currently processed object in _compact collides + with the one given as parameter */ +bool Logic::isCollision(Compact *other) { + MegaSet *thisMegaSet = SkyCompact::getMegaSet(_compact); + MegaSet *otherMegaSet = SkyCompact::getMegaSet(other); // target's base coordinates - uint16 x = cpt->xcood & 0xfff8; - uint16 y = cpt->ycood & 0xfff8; - - // The collision is direction dependent - switch (_compact->dir) { - case 0: // looking up - x -= m1->colOffset; // compensate for inner x offsets - x += m2->colOffset; - - if ((x + m2->colWidth) < _compact->xcood) // their rightmost - return false; - - x -= m1->colWidth; // our left, their right - if (x >= _compact->xcood) - return false; - - y += 8; // bring them down a line - if (y == _compact->ycood) - return true; - - y += 8; // bring them down a line - if (y == _compact->ycood) - return true; - - return false; - case 1: // looking down - x -= m1->colOffset; // compensate for inner x offsets - x += m2->colOffset; - - if ((x + m2->colWidth) < _compact->xcood) // their rightmoast - return false; - - x -= m1->colWidth; // our left, their right - if (x >= _compact->xcood) - return false; - - y -= 8; // bring them up a line - if (y == _compact->ycood) - return true; - - y -= 8; // bring them up a line - if (y == _compact->ycood) - return true; - - return false; - case 2: // looking left - - if (y != _compact->ycood) - return false; - - x += m2->lastChr; - if (x == _compact->xcood) - return true; - - x -= 8; // out another one - if (x == _compact->xcood) - return true; - - return false; - case 3: // looking right - case 4: // talking (not sure if this makes sense...) - - if (y != _compact->ycood) - return false; - - x -= m1->lastChr; // last block - if (x == _compact->xcood) - return true; + uint16 otherX = other->xcood & ~7; + uint16 otherY = other->ycood & ~7; + if ((_compact->dir == UPY) || (_compact->dir == DOWNY)) { // If we're looking up or down... + otherX -= thisMegaSet->colOffset; // ...then compensate inner otherX offsets + otherX += otherMegaSet->colOffset; + } - x -= 8; // out another block - if (x != _compact->xcood) + if ((_compact->dir == UPY) || (_compact->dir == DOWNY)) { + // Check X coordinate, same for facing up or down + if (otherX + otherMegaSet->colWidth < _compact->xcood) // their rightmost + return false; // other is left of us + + if (otherX - thisMegaSet->colWidth >= _compact->xcood) // our left, their right + return false; // other is right of us + // Check Y coordinate according to actual direction + if (_compact->dir == UPY) { + if (otherY + 8 == _compact->ycood) + return true; + if (otherY + 16 == _compact->ycood) + return true; + } else { + if (otherY - 8 == _compact->ycood) + return true; + if (otherY - 16 == _compact->ycood) + return true; + } + } else { + // Facing left, right (or talking, which probably never happens) + if (otherY != _compact->ycood) return false; - - return true; - default: - error("Unknown Direction: %d", _compact->dir); + if (_compact->dir == LEFTY) { // looking left + if (otherX + otherMegaSet->lastChr == _compact->xcood) + return true; + if (otherX + otherMegaSet->lastChr - 8 == _compact->xcood) + return true; + } else { + if (otherX - thisMegaSet->lastChr == _compact->xcood) + return true; + if (otherX - thisMegaSet->lastChr - 8 == _compact->xcood) + return true; + } } + return false; } void Logic::runGetOff() { @@ -1717,7 +1685,7 @@ bool Logic::fnSpeakMe(uint32 targetId, uint32 mesgNum, uint32 animNum) { on other screens, as the lack of speech files for these lines will cause Foster's speech to be aborted if the timing is bad. */ - if (targetId == 0x4039 && animNum == 0x9B && Logic::_scriptVariables[SCREEN] != 38) { + if (targetId == ID_DANIELLE && animNum == 0x9B && Logic::_scriptVariables[SCREEN] != 38) { return false; } diff --git a/engines/sky/logic.h b/engines/sky/logic.h index 8507fe7398..cd83e1a5f8 100644 --- a/engines/sky/logic.h +++ b/engines/sky/logic.h @@ -164,7 +164,7 @@ protected: void push(uint32); uint32 pop(); void checkModuleLoaded(uint16 moduleNo); - bool collide(Compact *cpt); + bool isCollision(Compact *cpt); void initScriptVariables(); void mainAnim(); void runGetOff(); diff --git a/engines/sky/music/adlibchannel.cpp b/engines/sky/music/adlibchannel.cpp index c7acb9b6c1..2f44add466 100644 --- a/engines/sky/music/adlibchannel.cpp +++ b/engines/sky/music/adlibchannel.cpp @@ -23,7 +23,7 @@ #include "common/endian.h" #include "common/textconsole.h" -#include "common/util.h" +#include "audio/fmopl.h" #include "sky/music/adlibchannel.h" #include "sky/sky.h" diff --git a/engines/sky/music/adlibchannel.h b/engines/sky/music/adlibchannel.h index 4504e3b570..b190ba27dc 100644 --- a/engines/sky/music/adlibchannel.h +++ b/engines/sky/music/adlibchannel.h @@ -24,7 +24,10 @@ #define SKY_MUSIC_ADLIBCHANNEL_H #include "sky/music/musicbase.h" -#include "audio/fmopl.h" + +namespace OPL { +class OPL; +} namespace Sky { diff --git a/engines/sky/music/adlibmusic.cpp b/engines/sky/music/adlibmusic.cpp index be5e7b2353..1a2a91c82a 100644 --- a/engines/sky/music/adlibmusic.cpp +++ b/engines/sky/music/adlibmusic.cpp @@ -26,9 +26,13 @@ #include "sky/music/adlibmusic.h" #include "sky/music/adlibchannel.h" -#include "audio/mixer.h" +#include "audio/fmopl.h" #include "sky/sky.h" +namespace Audio { +class Mixer; +} + namespace Sky { AdLibMusic::AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) { diff --git a/engines/sky/music/adlibmusic.h b/engines/sky/music/adlibmusic.h index 7b51f2d3a0..ebfa038848 100644 --- a/engines/sky/music/adlibmusic.h +++ b/engines/sky/music/adlibmusic.h @@ -24,7 +24,10 @@ #define SKY_MUSIC_ADLIBMUSIC_H #include "sky/music/musicbase.h" -#include "audio/audiostream.h" + +namespace Audio { +class Mixer; +} namespace OPL { class OPL; diff --git a/engines/sky/sky.h b/engines/sky/sky.h index 56833004ac..374302b8d3 100644 --- a/engines/sky/sky.h +++ b/engines/sky/sky.h @@ -20,8 +20,8 @@ * */ -#ifndef SKY_H -#define SKY_H +#ifndef SKY_SKY_H +#define SKY_SKY_H #include "common/error.h" diff --git a/engines/sky/skydefs.h b/engines/sky/skydefs.h index 167b7dade2..ed07a5e2cd 100644 --- a/engines/sky/skydefs.h +++ b/engines/sky/skydefs.h @@ -45,6 +45,7 @@ namespace Sky { #define SKY_ITALIAN 5 #define SKY_PORTUGUESE 6 #define SKY_SPANISH 7 +#define SKY_RUSSIAN 8 #define ST_COLLISION_BIT 5 |
