diff options
-rw-r--r-- | engines/prince/archive.cpp | 22 | ||||
-rw-r--r-- | engines/prince/archive.h | 1 | ||||
-rw-r--r-- | engines/prince/detection.h | 38 | ||||
-rw-r--r-- | engines/prince/prince.cpp | 92 | ||||
-rw-r--r-- | engines/prince/prince.h | 6 |
5 files changed, 149 insertions, 10 deletions
diff --git a/engines/prince/archive.cpp b/engines/prince/archive.cpp index 7a4a35abd8..a01f824df8 100644 --- a/engines/prince/archive.cpp +++ b/engines/prince/archive.cpp @@ -79,6 +79,28 @@ bool PtcArchive::open(const Common::String &filename) { return true; } +bool PtcArchive::openTranslation(const Common::String &filename) { + _stream = SearchMan.createReadStreamForMember(filename); + if (!_stream) + return false; + + Common::Array<Common::String> translationNames; + Common::String translationFileName; + const int kTranslationFiles = 5; + for (int i = 0; i < kTranslationFiles; i++) { + translationFileName = _stream->readLine(); + translationNames.push_back(translationFileName); + } + FileEntry item; + for (int i = 0; i < kTranslationFiles; i++) { + item._offset = _stream->readUint32LE(); + item._size = _stream->readUint32LE(); + _items[translationNames[i]] = item; + } + + return true; +} + void PtcArchive::close() { delete _stream; _stream = nullptr; diff --git a/engines/prince/archive.h b/engines/prince/archive.h index e211036ed6..a640b77911 100644 --- a/engines/prince/archive.h +++ b/engines/prince/archive.h @@ -35,6 +35,7 @@ public: ~PtcArchive(); bool open(const Common::String &filename); + bool openTranslation(const Common::String &filename); void close(); bool isOpen() const { return _stream != 0; } diff --git a/engines/prince/detection.h b/engines/prince/detection.h index 5cc0d32be4..6720e5e0b7 100644 --- a/engines/prince/detection.h +++ b/engines/prince/detection.h @@ -28,9 +28,15 @@ namespace Prince { +enum PrinceGameType { + UNK_DATA, + DE_DATA, + PL_DATA +}; + struct PrinceGameDescription { ADGameDescription desc; - int gameType; + PrinceGameType gameType; }; static const PlainGameDescriptor princeGames[] = { @@ -49,7 +55,7 @@ static const PrinceGameDescription gameDescriptions[] = { ADGF_TESTING, GUIO1(GUIO_NONE) }, - 0 + DE_DATA }, { { @@ -61,9 +67,33 @@ static const PrinceGameDescription gameDescriptions[] = { ADGF_TESTING, GUIO1(GUIO_NONE) }, - 1 + PL_DATA + }, + { + { + "prince", + "The Prince and the Coward", + AD_ENTRY1s("databank.ptc", "5fa03833177331214ec1354761b1d2ee", 3565031), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_TESTING, + GUIO1(GUIO_NONE) + }, + DE_DATA + }, + { + { + "prince", + "The Prince and the Coward", + AD_ENTRY1s("databank.ptc", "48ec9806bda9d152acbea8ce31c93c49", 3435298), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_TESTING, + GUIO1(GUIO_NONE) + }, + PL_DATA }, - { AD_TABLE_END_MARKER, 0 } + { AD_TABLE_END_MARKER, UNK_DATA } }; const static char *directoryGlobs[] = { diff --git a/engines/prince/prince.cpp b/engines/prince/prince.cpp index 04a482c570..a6197260e4 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() { @@ -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); @@ -261,6 +274,11 @@ void PrinceEngine::init() { _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); @@ -268,7 +286,12 @@ void PrinceEngine::init() { _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 +302,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 +382,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,6 +396,10 @@ 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() { @@ -469,13 +506,17 @@ bool PrinceEngine::loadLocation(uint16 locationNr) { loadMobPriority("mobpri"); _mobList.clear(); - if (getLanguage() == Common::DE_DEU) { + if (getGameType() == PrinceGameType::DE_DATA) { 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() == PrinceGameType::PL_DATA) { 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); @@ -947,6 +988,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) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 930c3c7bd3..48491c63bd 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -285,6 +285,9 @@ public: uint32 _talkTxtSize; byte *_talkTxt; + uint32 _mobTranslationSize; + byte *_mobTranslationData; + bool loadLocation(uint16 locationNr); bool loadAnim(uint16 animNr, bool loop); bool loadVoice(uint32 textSlot, uint32 sampleSlot, const Common::String &name); @@ -294,6 +297,9 @@ public: bool loadTrans(byte *transTable, const char *resourceName); bool loadMobPriority(const char *resourceName); + void loadMobTranslationTexts(); + void setMobTranslationTexts(); + bool loadMusic(int musNumber); void stopMusic(); |