aboutsummaryrefslogtreecommitdiff
path: root/engines/sky
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sky')
-rw-r--r--engines/sky/compact.cpp29
-rw-r--r--engines/sky/compact.h2
-rw-r--r--engines/sky/control.cpp39
-rw-r--r--engines/sky/control.h2
-rw-r--r--engines/sky/detection.cpp4
-rw-r--r--engines/sky/logic.cpp130
-rw-r--r--engines/sky/logic.h2
-rw-r--r--engines/sky/music/adlibchannel.cpp2
-rw-r--r--engines/sky/music/adlibchannel.h5
-rw-r--r--engines/sky/music/adlibmusic.cpp6
-rw-r--r--engines/sky/music/adlibmusic.h5
-rw-r--r--engines/sky/sky.h4
-rw-r--r--engines/sky/skydefs.h1
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