aboutsummaryrefslogtreecommitdiff
path: root/engines/cryomni3d
diff options
context:
space:
mode:
authorLe Philousophe2019-06-23 09:31:37 +0200
committerLe Philousophe2019-07-05 07:51:19 +0200
commit418cec512f177a0f523c80916770382dd0e4fdaf (patch)
tree2d7d35c48a9f135acccf9d00bfe5d9412a856b2f /engines/cryomni3d
parent57b74a2773ae083121e0e621eb555c19d666ea2a (diff)
downloadscummvm-rg350-418cec512f177a0f523c80916770382dd0e4fdaf.tar.gz
scummvm-rg350-418cec512f177a0f523c80916770382dd0e4fdaf.tar.bz2
scummvm-rg350-418cec512f177a0f523c80916770382dd0e4fdaf.zip
CRYOMNI3D: Add internationalization through external DAT file
Diffstat (limited to 'engines/cryomni3d')
-rw-r--r--engines/cryomni3d/cryomni3d.cpp21
-rw-r--r--engines/cryomni3d/cryomni3d.h4
-rw-r--r--engines/cryomni3d/datstream.cpp146
-rw-r--r--engines/cryomni3d/datstream.h58
-rw-r--r--engines/cryomni3d/module.mk1
-rw-r--r--engines/cryomni3d/versailles/data.cpp239
-rw-r--r--engines/cryomni3d/versailles/documentation.cpp23
-rw-r--r--engines/cryomni3d/versailles/documentation.h7
-rw-r--r--engines/cryomni3d/versailles/engine.cpp11
-rw-r--r--engines/cryomni3d/versailles/engine.h23
-rw-r--r--engines/cryomni3d/versailles/logic.cpp42
-rw-r--r--engines/cryomni3d/versailles/menus.cpp5
12 files changed, 314 insertions, 266 deletions
diff --git a/engines/cryomni3d/cryomni3d.cpp b/engines/cryomni3d/cryomni3d.cpp
index 334bcd3d4d..35a4cceb09 100644
--- a/engines/cryomni3d/cryomni3d.cpp
+++ b/engines/cryomni3d/cryomni3d.cpp
@@ -34,6 +34,7 @@
#include "graphics/palette.h"
#include "cryomni3d/cryomni3d.h"
+#include "cryomni3d/datstream.h"
#include "cryomni3d/image/hlz.h"
#include "cryomni3d/video/hnm_decoder.h"
@@ -79,6 +80,26 @@ void CryOmni3DEngine::pauseEngineIntern(bool pause) {
*/
}
+DATSeekableStream *CryOmni3DEngine::getStaticData(uint32 gameId, uint16 version) const {
+ Common::File *datFile = new Common::File();
+
+ if (!datFile->open("cryomni3d.dat")) {
+ delete datFile;
+ error("Failed to open cryomni3d.dat file");
+ return nullptr;
+ }
+
+ DATSeekableStream *gameStream = DATSeekableStream::getGame(datFile, gameId, version, getLanguage(),
+ getPlatform());
+ if (!gameStream) {
+ delete datFile;
+ error("Failed to find game in cryomni3d.dat file");
+ return nullptr;
+ }
+
+ return gameStream;
+}
+
Common::String CryOmni3DEngine::prepareFileName(const Common::String &baseName,
const char *const *extensions) const {
Common::String fname(baseName);
diff --git a/engines/cryomni3d/cryomni3d.h b/engines/cryomni3d/cryomni3d.h
index 95f3b54efc..86803a17fc 100644
--- a/engines/cryomni3d/cryomni3d.h
+++ b/engines/cryomni3d/cryomni3d.h
@@ -61,6 +61,8 @@ class ImageDecoder;
*/
namespace CryOmni3D {
+class DATSeekableStream;
+
enum CryOmni3DGameType {
GType_VERSAILLES
};
@@ -155,6 +157,8 @@ public:
virtual void setupPalette(const byte *colors, uint start, uint num) = 0;
protected:
+ DATSeekableStream *getStaticData(uint32 gameId, uint16 version) const;
+
void copySubPalette(byte *dst, const byte *src, uint start, uint num);
void setPalette(const byte *colors, uint start, uint num);
void lockPalette(uint startRW, uint endRW) { _lockPaletteStartRW = startRW; _lockPaletteEndRW = endRW; }
diff --git a/engines/cryomni3d/datstream.cpp b/engines/cryomni3d/datstream.cpp
new file mode 100644
index 0000000000..461146fd35
--- /dev/null
+++ b/engines/cryomni3d/datstream.cpp
@@ -0,0 +1,146 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "cryomni3d/datstream.h"
+
+namespace CryOmni3D {
+
+DATSeekableStream *DATSeekableStream::getGame(Common::SeekableReadStream *stream,
+ uint32 gameId, uint16 version, Common::Language lang, Common::Platform platform) {
+ if (stream == nullptr) {
+ return nullptr;
+ }
+
+ // Go to start of file
+ stream->seek(0, SEEK_SET);
+
+ // ALl of this should match devtools/create_cryomni3d_dat
+
+ // Check header
+ byte header[8];
+ memset(header, 0, sizeof(header));
+ stream->read(header, sizeof(header));
+ if (memcmp(header, "CY3DDATA", sizeof(header))) {
+ return nullptr;
+ }
+
+ // Check version
+ uint16 fileVersion = stream->readUint16LE();
+ if (fileVersion != kFileVersion) {
+ return nullptr;
+ }
+
+ uint16 langTranslated = translateLanguage(lang);
+ uint32 platformTranslated = translatePlatform(platform);
+
+ uint16 games = stream->readUint16LE();
+
+ // Padding to align to 16 bytes boundary
+ (void)stream->readUint32LE();
+
+ for (uint16 game = 0; game < games; game++) {
+ // Keep tag readable
+ uint32 readGameId = stream->readUint32BE();
+ uint16 readVersion = stream->readUint16LE();
+ // Keep tag readable
+ uint16 readLang = stream->readUint16BE();
+ uint32 readPlatforms = stream->readUint32LE();
+ uint32 offset = stream->readUint32LE();
+ uint32 size = stream->readUint32LE();
+
+ if (gameId != readGameId) {
+ continue;
+ }
+ if (version != readVersion) {
+ continue;
+ }
+ if (langTranslated != readLang) {
+ continue;
+ }
+ if (!(platformTranslated & readPlatforms)) {
+ continue;
+ }
+
+ // If we are there, we got a match
+ return new DATSeekableStream(stream, offset, offset + size);
+ }
+
+ // No match
+ return nullptr;
+}
+
+Common::String DATSeekableStream::readString16() {
+ char *buf;
+ uint16 len;
+
+ len = readUint16LE();
+ buf = (char *)malloc(len);
+ read(buf, len);
+
+ Common::String s(buf, len);
+ free(buf);
+
+ return s;
+}
+
+void DATSeekableStream::readString16Array16(Common::StringArray &array) {
+ uint16 items;
+ uint16 i;
+
+ items = readUint16LE();
+
+ array.reserve(items);
+ for (i = 0; i < items; i++) {
+ array.push_back(readString16());
+ }
+}
+
+uint16 DATSeekableStream::translateLanguage(Common::Language lang) {
+ switch (lang) {
+ case Common::FR_FRA:
+ return MKTAG16('f', 'r');
+ default:
+ // Invalid language
+ return 0;
+ }
+}
+
+uint32 DATSeekableStream::translatePlatform(Common::Platform platform) {
+ switch (platform) {
+ case Common::kPlatformWindows:
+ return 0x1;
+ case Common::kPlatformDOS:
+ return 0x2;
+ case Common::kPlatformMacintosh:
+ return 0x4;
+ case Common::kPlatformPSX:
+ return 0x8;
+ case Common::kPlatformSegaCD:
+ return 0x10;
+ default:
+ // Invalid platform
+ return 0;
+ }
+}
+
+} // End of namespace CryOmni3D
diff --git a/engines/cryomni3d/datstream.h b/engines/cryomni3d/datstream.h
new file mode 100644
index 0000000000..78614ef7d1
--- /dev/null
+++ b/engines/cryomni3d/datstream.h
@@ -0,0 +1,58 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef CRYOMNI3D_DATSTREAM_H
+#define CRYOMNI3D_DATSTREAM_H
+
+#include "common/language.h"
+#include "common/platform.h"
+#include "common/str.h"
+#include "common/str-array.h"
+#include "common/substream.h"
+
+namespace CryOmni3D {
+
+class DATSeekableStream : public Common::SeekableSubReadStream {
+public:
+
+ /* Parent stream must not be used after this call and will be disposed if fetch succeeded */
+ static DATSeekableStream *getGame(Common::SeekableReadStream *stream,
+ uint32 gameId, uint16 version, Common::Language lang, Common::Platform platform);
+
+ Common::String readString16();
+ void readString16Array16(Common::StringArray &array);
+
+private:
+ DATSeekableStream(SeekableReadStream *parentStream, uint32 start, uint32 end) :
+ SeekableSubReadStream(parentStream, start, end, DisposeAfterUse::YES) { }
+
+ static uint16 translateLanguage(Common::Language lang);
+ static uint32 translatePlatform(Common::Platform platform);
+
+ /* This is the version of the global file format
+ * Each game has then a version specific for its data */
+ static const uint16 kFileVersion = 1;
+};
+
+} // End of namespace CryOmni3D
+
+#endif
diff --git a/engines/cryomni3d/module.mk b/engines/cryomni3d/module.mk
index 30dd767fb5..830f4502f7 100644
--- a/engines/cryomni3d/module.mk
+++ b/engines/cryomni3d/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS = \
image/hlz.o \
video/hnm_decoder.o \
cryomni3d.o \
+ datstream.o \
detection.o \
dialogs_manager.o \
fixed_image.o \
diff --git a/engines/cryomni3d/versailles/data.cpp b/engines/cryomni3d/versailles/data.cpp
index af3dae45e4..f97e0da917 100644
--- a/engines/cryomni3d/versailles/data.cpp
+++ b/engines/cryomni3d/versailles/data.cpp
@@ -20,6 +20,8 @@
*
*/
+#include "cryomni3d/datstream.h"
+
#include "cryomni3d/versailles/engine.h"
namespace CryOmni3D {
@@ -69,224 +71,27 @@ const FakeTransitionActionPlace CryOmni3DEngine_Versailles::kFakeTransitions[] =
{0, 0} // Must be the last one
};
-void CryOmni3DEngine_Versailles::setupMessages() {
- _messages.resize(146);
-#define SET_MESSAGE(id, str) _messages[id] = str
- SET_MESSAGE(0, "Il est interdit d'ouvrir cette porte pour l'instant.");
- SET_MESSAGE(1, "Cette porte est ferm" "\x8e" "e " "\x88" " clef.");
- SET_MESSAGE(2, "Cette porte est ferm" "\x8e" "e.");
- SET_MESSAGE(3, "Ce tiroir est vide.");
- SET_MESSAGE(4, "Vous ne pouvez pas atteindre la b" "\x89" "che.");
- SET_MESSAGE(5, "Il n'y a rien dans cet oranger");
- SET_MESSAGE(6, "Ceci n'est pas un oranger!");
- SET_MESSAGE(7, "Il fait trop sombre. ");
- SET_MESSAGE(8, "Le coffre est ferm" "\x8e" ". ");
- SET_MESSAGE(9, "Vous pouvez ouvrir la porte");
- SET_MESSAGE(10, "Il faudrait quelque chose pour atteindre la bombe.");
- SET_MESSAGE(11, "Ce vase est vide.");
- SET_MESSAGE(12, "Maintenant, vous pouvez y aller.");
- SET_MESSAGE(13, "Vous n" "\xd5" "avez plus le temps de vous renseigner sur la Cour!");
- SET_MESSAGE(14, "Il est trop tard pour regarder les tableaux!");
- SET_MESSAGE(16, "Vous ne pouvez pas atteindre le papier.");
- SET_MESSAGE(15, "Attendez ! Transmettez donc vos indices " "\x88" " l'huissier.");
- SET_MESSAGE(17, "Vers l'apothicairerie");
- SET_MESSAGE(
- 18,
- "Attention : Vous allez pouvoir terminer ce niveau, mais vous n'avez pas effectu" "\x8e"
- " toutes les actions necessaires pour la suite. "
- "Il est conseill" "\x8e" " de SAUVEGARDER votre partie maintenant.");
- SET_MESSAGE(
- 19,
- "Attention : Vous allez pouvoir terminer ce niveau, mais vous n'avez peut-" "\x90" "tre"
- " pas effectu" "\x8e" " toutes les actions necessaires pour la suite. "
- "Il est conseill" "\x8e" " de SAUVEGARDER votre partie maintenant.");
- SET_MESSAGE(20, "Vous ne pouvez pas vous d" "\x8e" "placer en portant une " "\x8e" "chelle!");
- SET_MESSAGE(21, "Il n'y a plus rien ici");
- SET_MESSAGE(22, "Au revoir ...");
- SET_MESSAGE(23, "VERSAILLES,");
- SET_MESSAGE(24, "Complot " "\x88" " la Cour du Roi Soleil");
- SET_MESSAGE(27, " Commencer une nouvelle partie");
- SET_MESSAGE(26, " Reprendre la partie en cours");
- SET_MESSAGE(44, " Reprendre la visite en cours");
- SET_MESSAGE(28, " Charger une partie");
- SET_MESSAGE(46, " Charger une visite");
- SET_MESSAGE(29, " Sauver la partie");
- SET_MESSAGE(45, " Sauver la visite");
- SET_MESSAGE(25, "Consulter l'espace documentaire");
- SET_MESSAGE(42, "Visiter le ch" "\x89" "teau");
- SET_MESSAGE(48, " Omni3D : normal");
- SET_MESSAGE(51, " Omni3D : rapide");
- SET_MESSAGE(52, " Omni3D : tr" "\x8f" "s rapide");
- SET_MESSAGE(49, " Omni3D : lent");
- SET_MESSAGE(50, " Omni3D : tr" "\x8f" "s lent");
- SET_MESSAGE(30, " Afficher les sous-titres : OUI");
- SET_MESSAGE(31, " Afficher les sous-titres : NON");
- SET_MESSAGE(32, " Musique : OUI");
- SET_MESSAGE(33, " Musique : NON");
- SET_MESSAGE(35, " Toutes les musiques sur disque dur (92 Mo)");
- SET_MESSAGE(34, " Une seule musique sur disque dur (20 Mo)");
- SET_MESSAGE(36, " Aucune musique sur disque dur (lecture CD)");
- SET_MESSAGE(43, "Cr" "\x8e" "dits");
- SET_MESSAGE(39, "Volume");
- SET_MESSAGE(41, "");
- SET_MESSAGE(40, "Quitter le jeu");
- SET_MESSAGE(53, "Confirmer");
- SET_MESSAGE(54, "Annuler");
- SET_MESSAGE(55, "libre");
- SET_MESSAGE(56, "sans nom");
- SET_MESSAGE(57, "Attention : la partie en cours va " "\x90" "tre abandonn" "\x8e" "e.");
- SET_MESSAGE(58, "Retour");
- SET_MESSAGE(59, "Le chateau");
- SET_MESSAGE(60, "Retour Menu Principal");
- SET_MESSAGE(61, "Sommaire Espace documentaire");
- SET_MESSAGE(62, "Plan du ch" "\x89" "teau et des jardins");
- SET_MESSAGE(63, "Plan des int" "\x8e" "rieurs du ch" "\x89" "teau");
- SET_MESSAGE(64, "Probl" "\x8f" "me d'" "\x8e" "criture sur dique dur : disque plein ");
- SET_MESSAGE(66, "Veuillez ins" "\x8e" "rer le CD ");
- SET_MESSAGE(67, "Veuillez ins" "\x8e" "rer le CD %d et presser une touche");
- SET_MESSAGE(68, "Les arts");
- SET_MESSAGE(69, "Le r" "\x8f" "gne");
- SET_MESSAGE(70, "La Cour");
- SET_MESSAGE(71, "Vie de Ch" "\x89" "teau");
- SET_MESSAGE(72, "Le ch" "\x89" "teau et les jardins");
- SET_MESSAGE(73, "Chronologie");
- SET_MESSAGE(74, "Bassin d'Apollon");
- SET_MESSAGE(75, "Le Ch" "\x89" "teau");
- SET_MESSAGE(76, "Colonnade");
- SET_MESSAGE(77, "Labyrinthe");
- SET_MESSAGE(78, "Latone");
- SET_MESSAGE(79, "Orangerie");
- SET_MESSAGE(80, "Parterre d'eau");
- SET_MESSAGE(81, "Tapis vert");
- SET_MESSAGE(86, "Grand Canal");
- SET_MESSAGE(87, "Parterre du Midi");
- SET_MESSAGE(88, "Parterre du nord");
- SET_MESSAGE(89, "Potager du Roi");
- SET_MESSAGE(90, "Salle de bal");
- SET_MESSAGE(91, "Bassin de Neptune");
- SET_MESSAGE(92, "Pi" "\x8f" "ce d'eau des suisses");
- SET_MESSAGE(82, "Grandes Ecuries");
- SET_MESSAGE(83, "Petites Ecuries");
- SET_MESSAGE(84, "Les jardins");
- SET_MESSAGE(85, "Avant cour");
- SET_MESSAGE(93, "Aiguilles (Inutile!)");
- SET_MESSAGE(94, "Ciseaux");
- SET_MESSAGE(95, "Papier");
- SET_MESSAGE(96, "Pamphlet sur les arts");
- SET_MESSAGE(97, "Petite clef 1");
- SET_MESSAGE(98, "Papier r" "\x8e" "v" "\x8e" "l" "\x8e" "");
- SET_MESSAGE(99, "Papier t" "\x89" "ch" "\x8e" "");
- SET_MESSAGE(100, "Papier du coffre");
- SET_MESSAGE(101, "Pamphlet sur la lign" "\x8e" "e royale");
- SET_MESSAGE(102, "Bougie allum" "\x8e" "e");
- SET_MESSAGE(103, "Bougie");
- SET_MESSAGE(104, "Clef ");
- SET_MESSAGE(105, "Carton " "\x88" " dessin");
- SET_MESSAGE(106, "Carton " "\x88" " dessin");
- SET_MESSAGE(107, "Fausse esquisse");
- SET_MESSAGE(108, "Echelle");
- SET_MESSAGE(109, "Esquisse d" "\x8e" "truite");
- SET_MESSAGE(110, "pinceau");
- SET_MESSAGE(111, "pinceau Or");
- SET_MESSAGE(112, "pinceau Rouge");
- SET_MESSAGE(113, "Fusain");
- SET_MESSAGE(114, "Papier");
- SET_MESSAGE(115, "Pamphlet sur l" "\xd5" "architecture");
- SET_MESSAGE(116, "Petite clef 2");
- SET_MESSAGE(117, "Archer(inutile!)");
- SET_MESSAGE(118, "Partition");
- SET_MESSAGE(119, "Queue de billard");
- SET_MESSAGE(120, "Autorisation");
- SET_MESSAGE(121, "Reproduction des m" "\x8e" "dailles");
- SET_MESSAGE(122, "Tiroir " "\x88" " m" "\x8e" "dailles");
- SET_MESSAGE(123, "Clef de la petite porte d" "\xd5" "Apollon");
- SET_MESSAGE(124, "Nourriture");
- SET_MESSAGE(125, "Pamphlet sur la religion");
- SET_MESSAGE(126, "Epigraphe");
- SET_MESSAGE(127, "Pamphlet sur le gouvernement");
- SET_MESSAGE(128, "Plume");
- SET_MESSAGE(129, "Pense-b" "\x90" "te");
- SET_MESSAGE(130, "Lunette");
- SET_MESSAGE(131, "Plan Vauban");
- SET_MESSAGE(132, "Plan Vauban");
- SET_MESSAGE(133, "Cordon");
- SET_MESSAGE(134, "Gravure");
- SET_MESSAGE(135, "Petite clef 3");
- SET_MESSAGE(136, "Petite clef 4");
- SET_MESSAGE(137, "M" "\x8e" "morandum");
- SET_MESSAGE(138, "Plans du chateau");
- SET_MESSAGE(139, "Plans du chateau");
- SET_MESSAGE(140, "Clef des combles");
- SET_MESSAGE(141, "Fables");
- SET_MESSAGE(142, "Plan du Labyrinthe");
- SET_MESSAGE(143, "Outil");
- SET_MESSAGE(144, "M" "\x8e" "dicament");
- SET_MESSAGE(145, "Eteignoir");
-#undef SET_MESSAGE
-}
+void CryOmni3DEngine_Versailles::loadStaticData() {
+ // This should match data in devtools/create_cryomni3d_dat
+ DATSeekableStream *data = getStaticData(MKTAG('V', 'R', 'S', 'L'), 1);
+
+ // In the dat file we have
+ // file names
+ data->readString16Array16(_localizedFilenames);
+ assert(_localizedFilenames.size() == LocalizedFilenames::kMax);
+
+ // epigraph settings, bomb password
+ _epigraphContent = data->readString16();
+ _epigraphPassword = data->readString16();
+ _bombPassword = data->readString16();
+
+ // messages, paintings titles
+ data->readString16Array16(_messages);
+ assert(_messages.size() == 146);
+ data->readString16Array16(_paintingsTitles);
+ assert(_paintingsTitles.size() == 48);
-void CryOmni3DEngine_Versailles::setupPaintingsTitles() {
- _paintingsTitles.reserve(48);
-#define SET_PAINTING_TITLE(str) _paintingsTitles.push_back(str)
- SET_PAINTING_TITLE("\"Entr" "\x8e" "e des animaux dans l'arche\"\rGerolamo Bassano"); // 0: 41201
- SET_PAINTING_TITLE("\"Le repas d'Emma" "\x9f" "s\"\rJacopo Bassano"); // 1: 41202
- SET_PAINTING_TITLE("\"La Madeleine aux pieds de J" "\x8e" "sus Christ\"\rSustris"); // 2: 41203
- SET_PAINTING_TITLE("\"La sortie de l'arche\"\rGerolamo Bassano"); // 3: 41204
- SET_PAINTING_TITLE("\"Le frappement du rocher\"\rJacopo Bassano"); // 4: 41205
- SET_PAINTING_TITLE("\"La Bataille d'Arbelles\"\rJoseph Parrocel"); // 5: 41301
- SET_PAINTING_TITLE("\"Alexandre Le Grand vainqueur de Darius " "\x88"
- " la bataille d'Arbelles\"\rLe Bourguignon"); // 6: 41302
- SET_PAINTING_TITLE("\"Le Combat de Leuze\"\rJoseph Parrocel"); // 7: 42401
- SET_PAINTING_TITLE("\"Sainte C" "\x8e"
- "cile avec un ange tenant une partition musicale\"\rDominiquin"); // 8: 42901
- SET_PAINTING_TITLE("\"Don Francisco du Moncada \"\rVan Dyck"); // 9: 42902
- SET_PAINTING_TITLE("\"Le Petit Saint Jean Baptiste\"\rLe Carrache"); // 10: 42903
- SET_PAINTING_TITLE("\"Saint Mathieu\"\rValentin"); // 11: 42904
- SET_PAINTING_TITLE("\"Le Denier de C" "\x8e" "sar \"\rValentin"); // 12: 42905
- SET_PAINTING_TITLE("\"Saint Luc\"\rValentin"); // 13: 42906
- SET_PAINTING_TITLE("\"Le mariage mystique de Sainte Catherine\"\r Alessandro Turchi"); // 14: 42907
- SET_PAINTING_TITLE("\"R" "\x8e" "union de buveurs\"\rNicolas Tournier"); // 15: 42908
- SET_PAINTING_TITLE("\"La diseuse de Bonne aventure \"\rValentin"); // 16: 42909
- SET_PAINTING_TITLE("\"le roi David jouant de la harpe \"\rDominiquin"); // 17: 42910
- SET_PAINTING_TITLE("\"Sainte Madeleine\"\rDominiquin"); // 18: 42911
- SET_PAINTING_TITLE("\"Autoportrait \"\rVan Dyck"); // 19: 42912
- SET_PAINTING_TITLE("\"Saint Jean l'" "\x8e" "vang" "\x8e" "liste\"\r Valentin"); // 20: 42913
- SET_PAINTING_TITLE("\"Agar secouru par un ange \"\rGiovanni Lanfranco"); // 21: 42914
- SET_PAINTING_TITLE("\"Saint Marc \"\rValentin"); // 22: 42915
- SET_PAINTING_TITLE("\"M" "\x8e" "l" "\x8e" "agre ayant " "\x88"
- " ses pieds la hure du sanglier de Calydon\"\r Jacques Rousseau"); // 23: 43090
- SET_PAINTING_TITLE("\"Le Roi en costume romain\"\rJean Warin"); // 24: 43091
- SET_PAINTING_TITLE("\"attalante\"\rJacques Rousseau"); // 25: 43092
- SET_PAINTING_TITLE("\"En" "\x8e" "e portant Anchise\"\rSpada"); // 26: 43100
- SET_PAINTING_TITLE("\"David et Bethsab" "\x8e" "e\"\rV" "\x8e" "ron" "\x8f" "se"); // 27: 43101
- SET_PAINTING_TITLE("\"La fuite en Egypte\"\rGuido R" "\x8e" "ni "); // 28: 43102
- SET_PAINTING_TITLE("\"Louis XIV " "\x88" " cheval\"\rPierre Mignard"); // 29: 43103
- SET_PAINTING_TITLE("\"La magnificience royale & le progr" "\x8f"
- "s des beaux arts\"\rHouasse"); // 30: 43104
- SET_PAINTING_TITLE("\"Le Sacrifice d'Iphig" "\x8e" "nie\"\rCharles de la Fosse"); // 31: 43130
- SET_PAINTING_TITLE("\"Buste de Louis XIV\"\rsculpt" "\x8e"
- " par le Chevalier Bernin "); // 32: 43131
- SET_PAINTING_TITLE("\"Diane d" "\x8e" "couvrant son berger Endymion endormi dans les bras de Morph"
- "\x8e" "e\"\rGabriel Blanchard"); // 33: 43132
- SET_PAINTING_TITLE("\"La vierge & Saint Pierre\"\rGuerchin"); // 34: 43140
- SET_PAINTING_TITLE("\"Les P" "\x8e" "lerins d'Emma" "\x9f" "s\"\rV" "\x8e" "ron" "\x8f"
- "se"); // 35: 43141
- SET_PAINTING_TITLE("\"La sainte Famille\"\rV" "\x8e" "ron" "\x8f" "se"); // 36: 43142
- SET_PAINTING_TITLE("\"La famille de Darius aux pieds d'Alexandre\"\rCharles LeBrun"); // 37: 43143
- SET_PAINTING_TITLE("\"Saint Jean-Baptiste\"\rRapha" "\x91" "l"); // 38: 43144
- SET_PAINTING_TITLE("\"Marie de m" "\x8e" "dicis\"\rVan Dyck"); // 39: 43150
- SET_PAINTING_TITLE("\"Hercule luttant contre Achelous\"\rGuido R" "\x8e" "ni"); // 40: 43151
- SET_PAINTING_TITLE("\"Le Centaure Nessus porte Dejanire\"\rGuido R" "\x8e" "ni"); // 41: 43152
- SET_PAINTING_TITLE("\"Saint Fran" "\x8d" "ois d'Assise r" "\x8e" "confort" "\x8e" " apr" "\x8f"
- "s sa stigmatisation\"\rSeghers"); // 42: 43153
- SET_PAINTING_TITLE("\"Thomiris faisant tremper la t" "\x90"
- "te de Cyrus dans le sang\"\rRubens"); // 43: 43154
- SET_PAINTING_TITLE("\"Hercule tuant l'Hydre\"\rGuido R" "\x8e" "ni"); // 44: 43155
- SET_PAINTING_TITLE("\"Hercule sur le b" "\x9e" "cher\"\rGuido R" "\x8e" "ni"); // 45: 43156
- SET_PAINTING_TITLE("\"Portrait du Prince Palatin & de son fr" "\x8f"
- "re le Prince Robert\"\rVan Dyck"); // 46: 43157
- SET_PAINTING_TITLE("\"La descente de Croix \"\rCharles Lebrun"); // 47: 45260
-#undef SET_PAINTING_TITLE
+ delete data;
}
struct VideoSubSetting {
diff --git a/engines/cryomni3d/versailles/documentation.cpp b/engines/cryomni3d/versailles/documentation.cpp
index c74aaa90c7..c207d9df12 100644
--- a/engines/cryomni3d/versailles/documentation.cpp
+++ b/engines/cryomni3d/versailles/documentation.cpp
@@ -35,8 +35,6 @@
namespace CryOmni3D {
namespace Versailles {
-const char *Versailles_Documentation::kAllDocsFile = "tous_doc.txt";
-const char *Versailles_Documentation::kLinksDocsFile = "lien_doc.txt";
const Versailles_Documentation::TimelineEntry Versailles_Documentation::kTimelineEntries[] = {
{ "1638", 340, 15 },
{ "1643", 470, 30 },
@@ -84,17 +82,20 @@ const Versailles_Documentation::TimelineEntry Versailles_Documentation::kTimelin
};
void Versailles_Documentation::init(const Sprites *sprites, FontManager *fontManager,
- const Common::StringArray *messages, CryOmni3DEngine *engine) {
+ const Common::StringArray *messages, CryOmni3DEngine *engine,
+ const Common::String &allDocsFileName, const Common::String &linksDocsFileName) {
_sprites = sprites;
_fontManager = fontManager;
_messages = messages;
_engine = engine;
+ _allDocsFileName = allDocsFileName;
+ _linksDocsFileName = linksDocsFileName;
// Build list of records
Common::File allDocsFile;
- if (!allDocsFile.open(kAllDocsFile)) {
- error("Can't open %s", kAllDocsFile);
+ if (!allDocsFile.open(_allDocsFileName)) {
+ error("Can't open %s", _allDocsFileName.c_str());
}
uint allDocsSize = allDocsFile.size();
@@ -1940,8 +1941,8 @@ Common::String Versailles_Documentation::getRecordTitle(const Common::String &re
const RecordInfo &recordInfo = it->_value;
Common::File allDocsFile;
- if (!allDocsFile.open(kAllDocsFile)) {
- error("Can't open %s", kAllDocsFile);
+ if (!allDocsFile.open(_allDocsFileName)) {
+ error("Can't open %s", _allDocsFileName.c_str());
}
allDocsFile.seek(recordInfo.position);
@@ -1969,8 +1970,8 @@ Common::String Versailles_Documentation::getRecordData(const Common::String &rec
const RecordInfo &recordInfo = it->_value;
Common::File allDocsFile;
- if (!allDocsFile.open(kAllDocsFile)) {
- error("Can't open %s", kAllDocsFile);
+ if (!allDocsFile.open(_allDocsFileName)) {
+ error("Can't open %s", _allDocsFileName.c_str());
}
allDocsFile.seek(recordInfo.position);
@@ -2014,8 +2015,8 @@ void Versailles_Documentation::loadLinksFile() {
}
Common::File linksFile;
- if (!linksFile.open(kLinksDocsFile)) {
- error("Can't open links file: %s", kLinksDocsFile);
+ if (!linksFile.open(_linksDocsFileName)) {
+ error("Can't open links file: %s", _linksDocsFileName.c_str());
}
_linksSize = linksFile.size();
diff --git a/engines/cryomni3d/versailles/documentation.h b/engines/cryomni3d/versailles/documentation.h
index 1808956e2e..dd889e1469 100644
--- a/engines/cryomni3d/versailles/documentation.h
+++ b/engines/cryomni3d/versailles/documentation.h
@@ -44,7 +44,8 @@ public:
~Versailles_Documentation() { delete [] _linksData; }
void init(const Sprites *sprites, FontManager *fontManager, const Common::StringArray *messages,
- CryOmni3DEngine *engine);
+ CryOmni3DEngine *engine, const Common::String &allDocsFileName,
+ const Common::String &linksDocsFileName);
void handleDocArea();
void handleDocInGame(const Common::String &record);
@@ -109,8 +110,8 @@ private:
void loadLinksFile();
void getLinks(const Common::String &record, Common::Array<LinkInfo> &links);
- static const char *kAllDocsFile;
- static const char *kLinksDocsFile;
+ Common::String _allDocsFileName;
+ Common::String _linksDocsFileName;
static const uint kPopupMenuMargin = 5;
diff --git a/engines/cryomni3d/versailles/engine.cpp b/engines/cryomni3d/versailles/engine.cpp
index 98a34e31d5..7fba90102c 100644
--- a/engines/cryomni3d/versailles/engine.cpp
+++ b/engines/cryomni3d/versailles/engine.cpp
@@ -122,17 +122,18 @@ Common::Error CryOmni3DEngine_Versailles::run() {
SearchMan.add("__fallbackFiles", fallbackFiles);
- setupMessages();
+ // First thing, load all data that was originally in the executable
+ // We don't need anything prepared for that
+ loadStaticData();
_dialogsMan.init(138, _messages[22]);
_gameVariables.resize(GameVariables::kMax);
_omni3dMan.init(75. / 180. * M_PI);
- _dialogsMan.loadGTO("DIALOG1.GTO");
+ _dialogsMan.loadGTO(_localizedFilenames[LocalizedFilenames::kDialogs]);
setupDialogVariables();
setupDialogShows();
- setupPaintingsTitles();
setupImgScripts();
_mainPalette = new byte[3 * 256];
@@ -162,7 +163,9 @@ Common::Error CryOmni3DEngine_Versailles::run() {
// Documentation is needed by noone at init time, let's do it last
initDocPeopleRecord();
- _docManager.init(&_sprites, &_fontManager, &_messages, this);
+ _docManager.init(&_sprites, &_fontManager, &_messages, this,
+ _localizedFilenames[LocalizedFilenames::kAllDocs],
+ _localizedFilenames[LocalizedFilenames::kLinksDocs]);
_countdownSurface.create(40, 15, Graphics::PixelFormat::createFormatCLUT8());
diff --git a/engines/cryomni3d/versailles/engine.h b/engines/cryomni3d/versailles/engine.h
index ff00dfd385..95747ced42 100644
--- a/engines/cryomni3d/versailles/engine.h
+++ b/engines/cryomni3d/versailles/engine.h
@@ -168,6 +168,17 @@ struct SoundIds {
};
};
+struct LocalizedFilenames {
+ enum {
+ kDialogs = 0,
+ kAllDocs,
+ kLinksDocs,
+ kCredits,
+ kLeb001,
+ kMax
+ };
+};
+
struct PlaceState {
typedef void (CryOmni3DEngine_Versailles::*InitFunc)();
typedef bool (CryOmni3DEngine_Versailles::*FilterEventFunc)(uint *event);
@@ -242,11 +253,10 @@ private:
void setupSprites();
void loadCursorsPalette();
void calculateTransparentMapping();
- void setupMessages();
void setupObjects();
void setupDialogVariables();
void setupImgScripts();
- void setupPaintingsTitles();
+ void loadStaticData();
void syncOmni3DSettings();
void syncSoundSettings();
@@ -340,6 +350,7 @@ private:
void musicStop();
void musicSetQuiet(bool quiet);
+ Common::StringArray _localizedFilenames;
Common::StringArray _messages;
static const uint kSpritesMapTable[];
static const uint kSpritesMapTableSize;
@@ -509,8 +520,8 @@ private:
IMG_CB(44161e);
IMG_CB(44161f);
static const uint kEpigraphMaxLetters = 32;
- static const char *kEpigraphContent;
- static const char *kEpigraphPassword;
+ Common::String _epigraphContent;
+ Common::String _epigraphPassword;
bool handleEpigraph(ZonFixedImage *fimg);
void drawEpigraphLetters(Graphics::ManagedSurface &surface,
const Graphics::Surface(&bmpLetters)[28], const Common::String &letters);
@@ -531,13 +542,13 @@ private:
IMG_CB(88003d);
IMG_CB(88003e);
IMG_CB(88003f);
+ Common::String _bombPassword;
static const uint kBombPasswordSmallLength = 40;
static const uint kBombPasswordMaxLength = 60;
static const uint16 kBombLettersPos[2][kBombPasswordMaxLength][2];
- static const char *kBombPassword;
bool handleBomb(ZonFixedImage *fimg);
void drawBombLetters(Graphics::ManagedSurface &surface, const Graphics::Surface(&bmpLetters)[28],
- const uint kBombPasswordLength,
+ const uint bombPasswordLength,
const unsigned char (&bombPossibilites)[kBombPasswordMaxLength][5],
const unsigned char (&bombCurrentLetters)[kBombPasswordMaxLength]);
IMG_CB(88004);
diff --git a/engines/cryomni3d/versailles/logic.cpp b/engines/cryomni3d/versailles/logic.cpp
index e46c1a7ca0..952489c41e 100644
--- a/engines/cryomni3d/versailles/logic.cpp
+++ b/engines/cryomni3d/versailles/logic.cpp
@@ -187,7 +187,7 @@ void CryOmni3DEngine_Versailles::obj_126hk(Graphics::ManagedSurface &surface) {
Graphics::Surface bmpLetters[28];
loadBMPs("bomb_%02d.bmp", bmpLetters, 28);
- drawEpigraphLetters(surface, bmpLetters, kEpigraphPassword);
+ drawEpigraphLetters(surface, bmpLetters, _epigraphPassword);
for (uint i = 0; i < 28; i++) {
bmpLetters[i].free();
@@ -2361,7 +2361,7 @@ bool CryOmni3DEngine_Versailles::handleEpigraph(ZonFixedImage *fimg) {
continue;
}
// Find which letter got clicked
- char letter = kEpigraphContent[fimg->_currentZone];
+ char letter = _epigraphContent[fimg->_currentZone];
password += letter;
// Reset the surface and redraw digits on it
tempSurf.blitFrom(*fimgSurface);
@@ -2379,7 +2379,7 @@ bool CryOmni3DEngine_Versailles::handleEpigraph(ZonFixedImage *fimg) {
}
if (keyCode >= Common::KEYCODE_a &&
keyCode <= Common::KEYCODE_z &&
- strchr(kEpigraphContent, keyCode - Common::KEYCODE_a + 'A')) {
+ _epigraphContent.contains(keyCode - Common::KEYCODE_a + 'A')) {
password += keyCode - Common::KEYCODE_a + 'A';
} else {
continue;
@@ -2391,7 +2391,7 @@ bool CryOmni3DEngine_Versailles::handleEpigraph(ZonFixedImage *fimg) {
fimg->updateSurface(&tempSurf.rawSurface());
}
- if (password == kEpigraphPassword) {
+ if (password == _epigraphPassword) {
success = true;
break;
}
@@ -2403,9 +2403,6 @@ bool CryOmni3DEngine_Versailles::handleEpigraph(ZonFixedImage *fimg) {
return success;
}
-const char *CryOmni3DEngine_Versailles::kEpigraphContent = "FELIXFORTUNADIVINUMEXPLORATUMACTUIIT";
-const char *CryOmni3DEngine_Versailles::kEpigraphPassword = "LELOUPETLATETE";
-
void CryOmni3DEngine_Versailles::drawEpigraphLetters(Graphics::ManagedSurface &surface,
const Graphics::Surface(&bmpLetters)[28], const Common::String &letters) {
for (uint i = 0; i < letters.size() && i < kEpigraphMaxLetters; i++) {
@@ -2934,14 +2931,14 @@ bool CryOmni3DEngine_Versailles::handleBomb(ZonFixedImage *fimg) {
unsigned char bombCurrentLetters[60];
Graphics::ManagedSurface tempSurf;
- const uint kBombPasswordLength = strlen(kBombPassword);
- if (kBombPasswordLength >= kBombPasswordMaxLength) {
+ const uint bombPasswordLength = _bombPassword.size();
+ if (bombPasswordLength >= kBombPasswordMaxLength) {
error("Bomb password is too long");
}
loadBMPs("bomb_%02d.bmp", bmpLetters, 28);
- for (uint i = 0; i < kBombPasswordLength; i++) {
- bombPossibilites[i][0] = toupper(kBombPassword[i]);
+ for (uint i = 0; i < bombPasswordLength; i++) {
+ bombPossibilites[i][0] = toupper(_bombPassword[i]);
for (uint j = 1; j < 5; j++) {
bool foundSameLetter;
do {
@@ -2957,7 +2954,7 @@ bool CryOmni3DEngine_Versailles::handleBomb(ZonFixedImage *fimg) {
bombCurrentLetters[i] = rnd.getRandomNumber(4);
}
- if (kBombPasswordLength <= kBombPasswordSmallLength) {
+ if (bombPasswordLength <= kBombPasswordSmallLength) {
fimg->load("70z_16.GIF");
} else {
fimg->load("70z_17.GIF");
@@ -2965,7 +2962,7 @@ bool CryOmni3DEngine_Versailles::handleBomb(ZonFixedImage *fimg) {
const Graphics::Surface *fimgSurface = fimg->surface();
tempSurf.create(fimgSurface->w, fimgSurface->h, fimgSurface->format);
tempSurf.blitFrom(*fimgSurface);
- drawBombLetters(tempSurf, bmpLetters, kBombPasswordLength, bombPossibilites, bombCurrentLetters);
+ drawBombLetters(tempSurf, bmpLetters, bombPasswordLength, bombPossibilites, bombCurrentLetters);
drawCountdown(&tempSurf);
fimg->updateSurface(&tempSurf.rawSurface());
@@ -2975,12 +2972,12 @@ bool CryOmni3DEngine_Versailles::handleBomb(ZonFixedImage *fimg) {
break;
}
if (fimg->_zoneUse) {
- if (fimg->_currentZone < kBombPasswordLength) {
+ if (fimg->_currentZone < bombPasswordLength) {
// Safe digit
bombCurrentLetters[fimg->_currentZone] = (bombCurrentLetters[fimg->_currentZone] + 1) % 5;
// Reset the surface and redraw letters on it
tempSurf.blitFrom(*fimgSurface);
- drawBombLetters(tempSurf, bmpLetters, kBombPasswordLength, bombPossibilites, bombCurrentLetters);
+ drawBombLetters(tempSurf, bmpLetters, bombPasswordLength, bombPossibilites, bombCurrentLetters);
drawCountdown(&tempSurf);
fimg->updateSurface(&tempSurf.rawSurface());
@@ -2988,9 +2985,9 @@ bool CryOmni3DEngine_Versailles::handleBomb(ZonFixedImage *fimg) {
// Check if password is OK
success = true;
- for (uint i = 0; i < kBombPasswordLength; i++) {
+ for (uint i = 0; i < bombPasswordLength; i++) {
unsigned char letterChar = bombPossibilites[i][bombCurrentLetters[i]];
- if (letterChar != kBombPassword[i]) {
+ if (letterChar != _bombPassword[i]) {
success = false;
break;
}
@@ -3013,7 +3010,6 @@ bool CryOmni3DEngine_Versailles::handleBomb(ZonFixedImage *fimg) {
return success;
}
-const char *CryOmni3DEngine_Versailles::kBombPassword = "JEMENVAISMAISLETATDEMEURERATOUJOURS";
const uint16 CryOmni3DEngine_Versailles::kBombLettersPos[2][kBombPasswordMaxLength][2] = {
{
{26, 91},
@@ -3122,11 +3118,11 @@ const uint16 CryOmni3DEngine_Versailles::kBombLettersPos[2][kBombPasswordMaxLeng
};
void CryOmni3DEngine_Versailles::drawBombLetters(Graphics::ManagedSurface &surface,
- const Graphics::Surface(&bmpLetters)[28], const uint kBombPasswordLength,
+ const Graphics::Surface(&bmpLetters)[28], const uint bombPasswordLength,
const unsigned char (&bombPossibilites)[kBombPasswordMaxLength][5],
const unsigned char (&bombCurrentLetters)[kBombPasswordMaxLength]) {
- uint table = kBombPasswordLength <= kBombPasswordSmallLength ? 0 : 1;
- for (uint i = 0; i < kBombPasswordLength; i++) {
+ uint table = bombPasswordLength <= kBombPasswordSmallLength ? 0 : 1;
+ for (uint i = 0; i < bombPasswordLength; i++) {
unsigned char letterChar = bombPossibilites[i][bombCurrentLetters[i]];
uint letterId = 0;
if (letterChar >= 'A' && letterChar <= 'Z') {
@@ -3232,8 +3228,8 @@ FILTER_EVENT(1, 2) {
INIT_PLACE(1, 3) {
if (!_gameVariables[GameVariables::kHasPlayedLebrun]) {
Common::File *audioFile = new Common::File();
- if (!audioFile->open("LEB001__.WAV")) {
- warning("Failed to open sound file %s", "LEB001__.WAV");
+ if (!audioFile->open(_localizedFilenames[LocalizedFilenames::kLeb001])) {
+ warning("Failed to open sound file %s", _localizedFilenames[LocalizedFilenames::kLeb001].c_str());
delete audioFile;
return;
}
diff --git a/engines/cryomni3d/versailles/menus.cpp b/engines/cryomni3d/versailles/menus.cpp
index 9e072e8262..2459882657 100644
--- a/engines/cryomni3d/versailles/menus.cpp
+++ b/engines/cryomni3d/versailles/menus.cpp
@@ -956,8 +956,9 @@ void CryOmni3DEngine_Versailles::displayCredits() {
_fontManager.setSurface(&creditsSurface);
Common::File creditsFile;
- if (!creditsFile.open("credits.txt")) {
- warning("Failed to open credits file: %s", "credits.txt");
+ if (!creditsFile.open(_localizedFilenames[LocalizedFilenames::kCredits])) {
+ warning("Failed to open credits file: %s",
+ _localizedFilenames[LocalizedFilenames::kCredits].c_str());
delete imageDecoder;
return;
}