diff options
Diffstat (limited to 'engines/prince/prince.cpp')
-rw-r--r-- | engines/prince/prince.cpp | 219 |
1 files changed, 166 insertions, 53 deletions
diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 29c434e9c9..55f12a6560 100644 --- a/engines/prince/prince.cpp +++ b/engines/prince/prince.cpp @@ -61,6 +61,7 @@ #include "prince/animation.h" #include "prince/option_text.h" #include "prince/curve_values.h" +#include "prince/detection.h" namespace Prince { @@ -95,7 +96,8 @@ PrinceEngine::PrinceEngine(OSystem *syst, const PrinceGameDescription *gameDesc) _tracePointFirstPointFlag(false), _coordsBuf2(nullptr), _coords2(nullptr), _coordsBuf3(nullptr), _coords3(nullptr), _shanLen(0), _directionTable(nullptr), _currentMidi(0), _lightX(0), _lightY(0), _curveData(nullptr), _curvPos(0), _creditsData(nullptr), _creditsDataSize(0), _currentTime(0), _zoomBitmap(nullptr), _shadowBitmap(nullptr), _transTable(nullptr), - _flcFrameSurface(nullptr), _shadScaleValue(0), _shadLineLen(0), _scaleValue(0), _dialogImage(nullptr) { + _flcFrameSurface(nullptr), _shadScaleValue(0), _shadLineLen(0), _scaleValue(0), _dialogImage(nullptr), _mobTranslationData(nullptr), + _mobTranslationSize(0) { // Debug/console setup DebugMan.addDebugChannel(DebugChannel::kScript, "script", "Prince Script debug channel"); @@ -204,6 +206,8 @@ PrinceEngine::~PrinceEngine() { _dialogImage->free(); delete _dialogImage; } + + free(_mobTranslationData); } GUI::Debugger *PrinceEngine::getDebugger() { @@ -213,11 +217,11 @@ GUI::Debugger *PrinceEngine::getDebugger() { void PrinceEngine::init() { const Common::FSNode gameDataDir(ConfMan.get("path")); - + debugEngine("Adding all path: %s", gameDataDir.getPath().c_str()); PtcArchive *all = new PtcArchive(); - if (!all->open("all/databank.ptc")) + if (!all->open("all/databank.ptc")) error("Can't open all/databank.ptc"); PtcArchive *voices = new PtcArchive(); @@ -228,11 +232,20 @@ void PrinceEngine::init() { if (!sound->open("sound/databank.ptc")) error("Can't open sound/databank.ptc"); + PtcArchive *translation = new PtcArchive(); + if (getLanguage() != Common::PL_POL && getLanguage() != Common::DE_DEU) { + if (!translation->openTranslation("all/prince_translation.dat")) + error("Can't open prince_translation.dat"); + } + SearchMan.addSubDirectoryMatching(gameDataDir, "all"); SearchMan.add("all", all); SearchMan.add("voices", voices); SearchMan.add("sound", sound); + if (getLanguage() != Common::PL_POL && getLanguage() != Common::DE_DEU) { + SearchMan.add("translation", translation); + } _graph = new GraphicsMan(this); @@ -260,15 +273,24 @@ void PrinceEngine::init() { _debugger = new Debugger(this, _flags); _variaTxt = new VariaTxt(); - Resource::loadResource(_variaTxt, "variatxt.dat", true); - + if (getLanguage() == Common::PL_POL || getLanguage() == Common::DE_DEU) { + Resource::loadResource(_variaTxt, "variatxt.dat", true); + } else { + Resource::loadResource(_variaTxt, "variatxt_translate.dat", true); + } + _cursor1 = new Cursor(); Resource::loadResource(_cursor1, "mouse1.cur", true); _cursor3 = new Cursor(); Resource::loadResource(_cursor3, "mouse2.cur", true); - Common::SeekableReadStream *talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat"); + Common::SeekableReadStream *talkTxtStream; + if (getLanguage() == Common::PL_POL || getLanguage() == Common::DE_DEU) { + talkTxtStream = SearchMan.createReadStreamForMember("talktxt.dat"); + } else { + talkTxtStream = SearchMan.createReadStreamForMember("talktxt_translate.dat"); + } if (!talkTxtStream) { error("Can't load talkTxtStream"); return; @@ -279,7 +301,12 @@ void PrinceEngine::init() { delete talkTxtStream; - Common::SeekableReadStream *invTxtStream = SearchMan.createReadStreamForMember("invtxt.dat"); + Common::SeekableReadStream *invTxtStream; + if (getLanguage() == Common::PL_POL || getLanguage() == Common::DE_DEU) { + invTxtStream = SearchMan.createReadStreamForMember("invtxt.dat"); + } else { + invTxtStream = SearchMan.createReadStreamForMember("invtxt_translate.dat"); + } if (!invTxtStream) { error("Can't load invTxtStream"); return; @@ -354,7 +381,12 @@ void PrinceEngine::init() { _shadowLine = (byte *)malloc(kShadowLineArraySize); - Common::SeekableReadStream *creditsDataStream = SearchMan.createReadStreamForMember("credits.dat"); + Common::SeekableReadStream *creditsDataStream; + if (getLanguage() == Common::PL_POL || getLanguage() == Common::DE_DEU) { + creditsDataStream = SearchMan.createReadStreamForMember("credits.dat"); + } else { + creditsDataStream = SearchMan.createReadStreamForMember("credits_translate.dat"); + } if (!creditsDataStream) { error("Can't load creditsDataStream"); return; @@ -363,11 +395,14 @@ void PrinceEngine::init() { _creditsData = (byte *)malloc(_creditsDataSize); creditsDataStream->read(_creditsData, _creditsDataSize); delete creditsDataStream; + + if (getLanguage() != Common::PL_POL && getLanguage() != Common::DE_DEU) { + loadMobTranslationTexts(); + } } void PrinceEngine::showLogo() { MhwanhDecoder logo; - _system->delayMillis(1000 / kFPS * 20); if (Resource::loadResource(&logo, "logo.raw", true)) { loadSample(0, "LOGO.WAV"); playSample(0, 0); @@ -375,21 +410,58 @@ void PrinceEngine::showLogo() { _graph->change(); _graph->update(_graph->_frontScreen); setPalette(logo.getPalette()); - _system->delayMillis(1000 / kFPS * 70); + + uint32 logoStart = _system->getMillis(); + while (_system->getMillis() < logoStart + 5000) { + Common::Event event; + Common::EventManager *eventMan = _system->getEventManager(); + while (eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + if (event.kbd.keycode == Common::KEYCODE_ESCAPE) { + stopSample(0); + return; + } + break; + case Common::EVENT_LBUTTONDOWN: + stopSample(0); + return; + default: + break; + } + } + + if (shouldQuit()) { + return; + } + } } } Common::Error PrinceEngine::run() { - + syncSoundSettings(); + int startGameSlot = ConfMan.hasKey("save_slot") ? ConfMan.getInt("save_slot") : -1; init(); - - showLogo(); - + if (startGameSlot == -1) { + showLogo(); + } else { + loadLocation(59); // load intro location - easiest way to set everything up + loadGame(startGameSlot); + } mainLoop(); - return Common::kNoError; } +void PrinceEngine::pauseEngineIntern(bool pause) { + Engine::pauseEngineIntern(pause); + if (pause) { + _midiPlayer->pause(); + } + else { + _midiPlayer->resume(); + } +} + bool AnimListItem::loadFromStream(Common::SeekableReadStream &stream) { int32 pos = stream.pos(); @@ -469,13 +541,17 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { loadMobPriority("mobpri"); _mobList.clear(); - if (getLanguage() == Common::DE_DEU) { + if (getGameType() == kPrinceDataDE) { const Common::String mobLstName = Common::String::format("mob%02d.lst", _locationNr); debug("name: %s", mobLstName.c_str()); Resource::loadResource(_mobList, mobLstName.c_str(), false); - } else { + } else if (getGameType() == kPrinceDataPL) { Resource::loadResource(_mobList, "mob.lst", false); } + if (getLanguage() != Common::PL_POL && getLanguage() != Common::DE_DEU) { + // update Mob texts for translated version + setMobTranslationTexts(); + } _animList.clear(); Resource::loadResource(_animList, "anim.lst", false); @@ -678,7 +754,11 @@ void PrinceEngine::playSample(uint16 sampleId, uint16 loopType) { return; } _audioStream[sampleId]->rewind(); - _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO); + if (sampleId < 28) { + _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO); + } else { + _mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle[sampleId], _audioStream[sampleId], sampleId, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO); + } } } @@ -705,7 +785,7 @@ void PrinceEngine::freeAllSamples() { } bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamName) { - // FIXME: This is just a workaround streamName is a path + // FIXME: This is just a workaround streamName is a path // SOUND\\SCIERKA1.WAV for now only last path component is used Common::String normalizedPath = lastPathComponent(streamName, '\\'); @@ -730,8 +810,8 @@ bool PrinceEngine::loadSample(uint32 sampleSlot, const Common::String &streamNam bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::String &streamName) { debugEngine("Loading wav %s slot %d", streamName.c_str(), slot); - if (slot > kMaxTexts) { - error("Text slot bigger than MAXTEXTS %d", kMaxTexts); + if (slot >= kMaxTexts) { + error("Text slot bigger than MAXTEXTS %d", kMaxTexts - 1); return false; } @@ -756,7 +836,7 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin } id = sampleStream->readUint32LE(); - debugEngine("SetVoice slot %d time %04x", slot, id); + debugEngine("SetVoice slot %d time %04x", slot, id); id <<= 3; id /= 22050; id += 2; @@ -768,7 +848,7 @@ bool PrinceEngine::loadVoice(uint32 slot, uint32 sampleSlot, const Common::Strin _secondHero->_talkTime = id; } - debugEngine("SetVoice slot %d time %04x", slot, id); + debugEngine("SetVoice slot %d time %04x", slot, id); sampleStream->seek(SEEK_SET); _audioStream[sampleSlot] = Audio::makeWAVStream(sampleStream, DisposeAfterUse::NO); delete sampleStream; @@ -947,6 +1027,45 @@ bool PrinceEngine::loadMobPriority(const char *resourceName) { return true; } +void PrinceEngine::loadMobTranslationTexts() { + Common::SeekableReadStream *mobTranslationStream = SearchMan.createReadStreamForMember("mob_translate.dat"); + if (!mobTranslationStream) { + error("Can't load mob_translate.dat"); + } + _mobTranslationSize = mobTranslationStream->size(); + _mobTranslationData = (byte *)malloc(_mobTranslationSize); + mobTranslationStream->read(_mobTranslationData, _mobTranslationSize); + delete mobTranslationStream; +} + +void PrinceEngine::setMobTranslationTexts() { + int locationOffset = READ_UINT16(_mobTranslationData + (_locationNr - 1) * 2); + if (locationOffset) { + byte *locationText = _mobTranslationData + locationOffset; + for (uint i = 0; i < _mobList.size(); i++) { + byte c; + locationText++; + _mobList[i]._name.clear(); + while ((c = *locationText)) { + _mobList[i]._name += c; + locationText++; + } + locationText++; + _mobList[i]._examText.clear(); + c = *locationText; + locationText++; + if (c) { + _mobList[i]._examText += c; + do { + c = *locationText; + _mobList[i]._examText += c; + locationText++; + } while (c != 255); + } + } + } +} + void PrinceEngine::keyHandler(Common::Event event) { uint16 nChar = event.kbd.keycode; switch (nChar) { @@ -1506,7 +1625,7 @@ void PrinceEngine::setBackAnim(Anim &backAnim) { } void PrinceEngine::showBackAnims() { - for (uint i = 0; i < kMaxBackAnims; i++) { + for (int i = 0; i < kMaxBackAnims; i++) { BAS &seq = _backAnimList[i]._seq; int activeSubAnim = seq._currRelative; if (!_backAnimList[i].backAnims.empty()) { @@ -1893,7 +2012,7 @@ void PrinceEngine::blackPalette() { free(blackPalette1); return; } - pause(); + pausePrinceEngine(); } free(paletteBackup); free(blackPalette1); @@ -1901,41 +2020,34 @@ void PrinceEngine::blackPalette() { void PrinceEngine::setPalette(const byte *palette) { if (palette != nullptr) { - byte *blackPalette = (byte *)malloc(256 * 3); + byte *blackPalette_ = (byte *)malloc(256 * 3); int fadeStep = 0; for (int i = 0; i <= kFadeStep; i++) { for (int j = 0; j < 256; j++) { - blackPalette[3 * j] = palette[3 * j] * fadeStep / 4; - blackPalette[3 * j + 1] = palette[3 * j + 1] * fadeStep / 4; - blackPalette[3 * j + 2] = palette[3 * j + 2] * fadeStep / 4; + blackPalette_[3 * j] = palette[3 * j] * fadeStep / 4; + blackPalette_[3 * j + 1] = palette[3 * j + 1] * fadeStep / 4; + blackPalette_[3 * j + 2] = palette[3 * j + 2] * fadeStep / 4; } fadeStep++; - _graph->setPalette(blackPalette); + _graph->setPalette(blackPalette_); _system->updateScreen(); Common::Event event; Common::EventManager *eventMan = _system->getEventManager(); eventMan->pollEvent(event); if (shouldQuit()) { _graph->setPalette(palette); - free(blackPalette); + free(blackPalette_); return; } - pause(); + pausePrinceEngine(); } _graph->setPalette(palette); - free(blackPalette); + free(blackPalette_); } } -void PrinceEngine::pause() { - int delay = 1000 / kFPS - int32(_system->getMillis() - _currentTime); - delay = delay < 0 ? 0 : delay; - _system->delayMillis(delay); - _currentTime = _system->getMillis(); -} - -void PrinceEngine::pause2() { - int delay = 1000 / (kFPS * 2) - int32(_system->getMillis() - _currentTime); +void PrinceEngine::pausePrinceEngine(int fps) { + int delay = 1000 / fps - int32(_system->getMillis() - _currentTime); delay = delay < 0 ? 0 : delay; _system->delayMillis(delay); _currentTime = _system->getMillis(); @@ -2048,7 +2160,7 @@ void PrinceEngine::addInvObj() { if (shouldQuit()) { return; } - pause(); + pausePrinceEngine(); } while (_mst_shadow2 > 256) { rememberScreenInv(); @@ -2062,7 +2174,7 @@ void PrinceEngine::addInvObj() { if (shouldQuit()) { return; } - pause(); + pausePrinceEngine(); } } else { //CURSEBLINK: @@ -2080,7 +2192,7 @@ void PrinceEngine::addInvObj() { if (shouldQuit()) { return; } - pause(); + pausePrinceEngine(); } while (_mst_shadow2 > 256) { rememberScreenInv(); @@ -2094,7 +2206,7 @@ void PrinceEngine::addInvObj() { if (shouldQuit()) { return; } - pause(); + pausePrinceEngine(); } } } @@ -2110,7 +2222,7 @@ void PrinceEngine::addInvObj() { if (shouldQuit()) { return; } - pause(); + pausePrinceEngine(); } } @@ -2305,6 +2417,7 @@ void PrinceEngine::moveRunHero(int heroId, int x, int y, int dir, bool runHeroFl } void PrinceEngine::leftMouseButton() { + _flags->setFlagValue(Flags::ESCAPED2, 1); // skip intro animation _flags->setFlagValue(Flags::LMOUSE, 1); if (_flags->getFlagValue(Flags::POWERENABLED)) { _flags->setFlagValue(Flags::MBFLAG, 1); @@ -2738,7 +2851,7 @@ void PrinceEngine::displayInventory() { getDebugger()->onFrame(); _graph->update(_graph->_screenForInventory); - pause(); + pausePrinceEngine(); } if (_currentPointerNumber == 2) { @@ -2863,7 +2976,7 @@ void PrinceEngine::dialogRun() { getDebugger()->onFrame(); _graph->update(_graph->_frontScreen); - pause(); + pausePrinceEngine(); } _dialogImage->free(); delete _dialogImage; @@ -3122,7 +3235,7 @@ void PrinceEngine::scrollCredits() { } _graph->change(); _graph->update(_graph->_frontScreen); - pause2(); + pausePrinceEngine(kFPS * 2); } char letter2; byte *scan2 = scrollAdress; @@ -4106,7 +4219,7 @@ int PrinceEngine::checkRightUpDir() { } bool PrinceEngine::tracePath(int x1, int y1, int x2, int y2) { - for (int i = 0; i < kPathBitmapLen; i++) { + for (uint i = 0; i < kPathBitmapLen; i++) { _roomPathBitmapTemp[i] = 0; } if (x1 != x2 || y1 != y2) { @@ -4321,7 +4434,7 @@ int PrinceEngine::scanDirectionsFindNext(byte *tempCoordsBuf, int xDiff, int yDi tempCoordsBuf += 4; if (tempCoordsBuf == _coords) { - direction = tempX; + direction = tempX; break; } @@ -4726,7 +4839,7 @@ void PrinceEngine::mainLoop() { openInventoryCheck(); - pause(); + pausePrinceEngine(); } } |