aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlukaslw2014-10-28 19:20:56 +0100
committerlukaslw2014-10-28 20:59:11 +0100
commit9ad2135ff960da2bbc1882ac50f2188b5a9e228e (patch)
treecdb7ec4d95eed38d733900dce6e232c07b1ba03d
parent7126374b428ebb2feb7b431bdf5c906482d248dd (diff)
downloadscummvm-rg350-9ad2135ff960da2bbc1882ac50f2188b5a9e228e.tar.gz
scummvm-rg350-9ad2135ff960da2bbc1882ac50f2188b5a9e228e.tar.bz2
scummvm-rg350-9ad2135ff960da2bbc1882ac50f2188b5a9e228e.zip
PRINCE: Allow to load translation file - prince_translation.dat
Update detection file to allow English language with both PL and DE data files. Add setMobTranslationTexts() to update mob names to translated ones in each location
-rw-r--r--engines/prince/archive.cpp22
-rw-r--r--engines/prince/archive.h1
-rw-r--r--engines/prince/detection.h38
-rw-r--r--engines/prince/prince.cpp92
-rw-r--r--engines/prince/prince.h6
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();