2007-05-30 21:56:52 +00:00
/* 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 .
2003-12-16 02:10:15 +00:00
*
* 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 .
2014-02-18 02:34:25 +01:00
*
2003-12-16 02:10:15 +00:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
2008-01-05 12:45:14 +00:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
2003-12-16 02:10:15 +00:00
* GNU General Public License for more details .
2014-02-18 02:34:25 +01:00
*
2003-12-16 02:10:15 +00:00
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
2005-10-18 01:30:26 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
2003-12-16 02:10:15 +00:00
*
*/
2007-09-19 08:40:12 +00:00
2011-04-24 11:34:27 +03:00
# include "common/textconsole.h"
2003-12-16 02:10:15 +00:00
# include "common/util.h"
2006-03-29 15:59:37 +00:00
# include "sword1/objectman.h"
2004-10-21 12:43:49 +00:00
# include "sword1/sworddefs.h"
# include "sword1/swordres.h"
# include "sword1/sword1.h"
2003-12-16 02:10:15 +00:00
2004-01-11 15:47:41 +00:00
namespace Sword1 {
2003-12-16 02:10:15 +00:00
ObjectMan : : ObjectMan ( ResMan * pResourceMan ) {
_resMan = pResourceMan ;
2003-12-20 09:12:54 +00:00
}
2009-11-02 21:54:57 +00:00
void ObjectMan : : initialize ( ) {
2003-12-23 00:59:18 +00:00
uint16 cnt ;
for ( cnt = 0 ; cnt < TOTAL_SECTIONS ; cnt + + )
2003-12-20 09:12:54 +00:00
_liveList [ cnt ] = 0 ; // we don't need to close the files here. When this routine is
2011-09-07 23:54:34 +02:00
// called, the memory was flushed() anyways, so these resources
// already *are* closed.
2003-12-20 09:12:54 +00:00
2003-12-16 02:10:15 +00:00
_liveList [ 128 ] = _liveList [ 129 ] = _liveList [ 130 ] = _liveList [ 131 ] = _liveList [ 133 ] =
2011-09-07 23:54:34 +02:00
_liveList [ 134 ] = _liveList [ 145 ] = _liveList [ 146 ] = _liveList [ TEXT_sect ] = 1 ;
2005-07-30 21:11:48 +00:00
2003-12-23 00:59:18 +00:00
for ( cnt = 0 ; cnt < TOTAL_SECTIONS ; cnt + + ) {
2003-12-16 02:10:15 +00:00
if ( _liveList [ cnt ] )
2011-09-07 23:54:34 +02:00
_cptData [ cnt ] = ( uint8 * ) _resMan - > cptResOpen ( _objectList [ cnt ] ) + sizeof ( Header ) ;
2003-12-16 02:10:15 +00:00
else
_cptData [ cnt ] = NULL ;
}
}
2009-11-02 21:54:57 +00:00
ObjectMan : : ~ ObjectMan ( ) {
2003-12-16 02:10:15 +00:00
for ( uint16 cnt = 0 ; cnt < TOTAL_SECTIONS ; cnt + + )
if ( _liveList [ cnt ] )
_resMan - > resClose ( _objectList [ cnt ] ) ;
}
bool ObjectMan : : sectionAlive ( uint16 section ) {
return ( _liveList [ section ] > 0 ) ;
}
void ObjectMan : : megaEntering ( uint16 section ) {
_liveList [ section ] + + ;
if ( _liveList [ section ] = = 1 )
2011-09-07 23:54:34 +02:00
_cptData [ section ] = ( ( uint8 * ) _resMan - > cptResOpen ( _objectList [ section ] ) ) + sizeof ( Header ) ;
2003-12-16 02:10:15 +00:00
}
void ObjectMan : : megaLeaving ( uint16 section , int id ) {
if ( _liveList [ section ] = = 0 )
error ( " mega %d is leaving empty section %d " , id , section ) ;
_liveList [ section ] - - ;
if ( ( _liveList [ section ] = = 0 ) & & ( id ! = PLAYER ) ) {
2003-12-17 01:47:47 +00:00
_resMan - > resClose ( _objectList [ section ] ) ;
2003-12-16 02:10:15 +00:00
_cptData [ section ] = NULL ;
}
/* if the player is leaving the section then we have to close the resources after
mainloop ends , because the screen will still need the resources */
}
uint8 ObjectMan : : fnCheckForTextLine ( uint32 textId ) {
uint8 retVal = 0 ;
if ( ! _textList [ textId / ITM_PER_SEC ] [ 0 ] )
return 0 ; // section does not exist
uint8 lang = SwordEngine : : _systemVars . language ;
2011-09-07 23:54:34 +02:00
uint32 * textData = ( uint32 * ) ( ( uint8 * ) _resMan - > openFetchRes ( _textList [ textId / ITM_PER_SEC ] [ lang ] ) + sizeof ( Header ) ) ;
2006-11-12 19:05:51 +00:00
if ( ( textId & ITM_ID ) < _resMan - > readUint32 ( textData ) ) {
2003-12-16 02:10:15 +00:00
textData + + ;
if ( textData [ textId & ITM_ID ] )
retVal = 1 ;
}
_resMan - > resClose ( _textList [ textId / ITM_PER_SEC ] [ lang ] ) ;
return retVal ;
}
char * ObjectMan : : lockText ( uint32 textId ) {
uint8 lang = SwordEngine : : _systemVars . language ;
2012-06-07 01:46:32 +01:00
char * text = lockText ( textId , lang ) ;
if ( text = = 0 ) {
if ( lang ! = BS1_ENGLISH ) {
text = lockText ( textId , BS1_ENGLISH ) ;
if ( text ! = 0 )
warning ( " Missing translation for textId %u ( \" %s \" ) " , textId , text ) ;
unlockText ( textId , BS1_ENGLISH ) ;
}
2012-09-26 04:17:31 +02:00
2012-06-07 01:46:32 +01:00
return _missingSubTitleStr ;
}
return text ;
}
char * ObjectMan : : lockText ( uint32 textId , uint8 lang ) {
2011-09-07 23:54:34 +02:00
char * addr = ( char * ) _resMan - > openFetchRes ( _textList [ textId / ITM_PER_SEC ] [ lang ] ) ;
2009-02-27 05:52:22 +00:00
if ( addr = = 0 )
2012-06-07 01:46:32 +01:00
return NULL ;
2009-02-27 05:52:22 +00:00
addr + = sizeof ( Header ) ;
2006-11-12 19:05:51 +00:00
if ( ( textId & ITM_ID ) > = _resMan - > readUint32 ( addr ) ) {
2016-02-14 10:27:44 +01:00
// Workaround for missing sentences in some languages in the demo.
2012-06-26 21:19:16 +01:00
switch ( textId ) {
case 8455194 :
return const_cast < char * > ( _translationId8455194 [ lang ] ) ;
case 8455195 :
return const_cast < char * > ( _translationId8455195 [ lang ] ) ;
case 8455196 :
return const_cast < char * > ( _translationId8455196 [ lang ] ) ;
case 8455197 :
return const_cast < char * > ( _translationId8455197 [ lang ] ) ;
case 8455198 :
return const_cast < char * > ( _translationId8455198 [ lang ] ) ;
case 8455199 :
return const_cast < char * > ( _translationId8455199 [ lang ] ) ;
case 8455200 :
return const_cast < char * > ( _translationId8455200 [ lang ] ) ;
case 8455201 :
return const_cast < char * > ( _translationId8455201 [ lang ] ) ;
case 8455202 :
return const_cast < char * > ( _translationId8455202 [ lang ] ) ;
case 8455203 :
return const_cast < char * > ( _translationId8455203 [ lang ] ) ;
case 8455204 :
return const_cast < char * > ( _translationId8455204 [ lang ] ) ;
case 8455205 :
return const_cast < char * > ( _translationId8455205 [ lang ] ) ;
case 6488080 :
return const_cast < char * > ( _translationId6488080 [ lang ] ) ;
case 6488081 :
return const_cast < char * > ( _translationId6488081 [ lang ] ) ;
case 6488082 :
return const_cast < char * > ( _translationId6488082 [ lang ] ) ;
case 6488083 :
return const_cast < char * > ( _translationId6488083 [ lang ] ) ;
2019-10-20 15:39:58 +01:00
default :
break ;
2012-06-26 21:19:16 +01:00
}
2006-11-12 19:05:51 +00:00
warning ( " ObjectMan::lockText(%d): only %d texts in file " , textId & ITM_ID , _resMan - > readUint32 ( addr ) ) ;
2012-06-07 01:46:32 +01:00
return NULL ;
2003-12-16 02:10:15 +00:00
}
2011-09-07 23:54:34 +02:00
uint32 offset = _resMan - > readUint32 ( addr + ( ( textId & ITM_ID ) + 1 ) * 4 ) ;
2004-10-21 03:47:15 +00:00
if ( offset = = 0 ) {
2016-02-14 10:27:44 +01:00
// Workaround bug for missing sentence in some languages in Syria (see bug #1977094).
2009-02-27 05:20:37 +00:00
// We use the hardcoded text in this case.
if ( textId = = 2950145 )
2011-09-07 23:54:34 +02:00
return const_cast < char * > ( _translationId2950145 [ lang ] ) ;
2012-09-26 04:17:31 +02:00
2003-12-16 02:10:15 +00:00
warning ( " ObjectMan::lockText(%d): text number has no text lines " , textId ) ;
2012-06-07 01:46:32 +01:00
return NULL ;
2004-10-21 03:47:15 +00:00
}
2003-12-16 02:10:15 +00:00
return addr + offset ;
}
void ObjectMan : : unlockText ( uint32 textId ) {
2012-06-07 01:46:32 +01:00
unlockText ( textId , SwordEngine : : _systemVars . language ) ;
}
void ObjectMan : : unlockText ( uint32 textId , uint8 lang ) {
_resMan - > resClose ( _textList [ textId / ITM_PER_SEC ] [ lang ] ) ;
2003-12-16 02:10:15 +00:00
}
uint32 ObjectMan : : lastTextNumber ( int section ) {
2011-09-07 23:54:34 +02:00
uint8 * data = ( uint8 * ) _resMan - > openFetchRes ( _textList [ section ] [ SwordEngine : : _systemVars . language ] ) + sizeof ( Header ) ;
2006-11-12 19:05:51 +00:00
uint32 result = _resMan - > readUint32 ( data ) - 1 ;
2003-12-16 02:10:15 +00:00
_resMan - > resClose ( _textList [ section ] [ SwordEngine : : _systemVars . language ] ) ;
return result ;
}
2004-01-11 15:47:41 +00:00
Object * ObjectMan : : fetchObject ( uint32 id ) {
2003-12-16 02:10:15 +00:00
uint8 * addr = _cptData [ id / ITM_PER_SEC ] ;
if ( ! addr )
2009-05-31 10:02:16 +00:00
error ( " fetchObject: section %d is not open " , id / ITM_PER_SEC ) ;
2003-12-16 02:10:15 +00:00
id & = ITM_ID ;
// DON'T do endian conversion here. it's already done.
2011-09-07 23:54:34 +02:00
return ( Object * ) ( addr + * ( uint32 * ) ( addr + ( id + 1 ) * 4 ) ) ;
2003-12-16 02:10:15 +00:00
}
uint32 ObjectMan : : fetchNoObjects ( int section ) {
if ( _cptData [ section ] = = NULL )
2009-05-31 10:02:16 +00:00
error ( " fetchNoObjects: section %d is not open " , section ) ;
2011-09-07 23:54:34 +02:00
return * ( uint32 * ) _cptData [ section ] ;
2003-12-16 02:10:15 +00:00
}
void ObjectMan : : closeSection ( uint32 screen ) {
2011-09-07 23:54:34 +02:00
if ( _liveList [ screen ] = = 0 ) // close the section that PLAYER has just left, if it's empty now
2003-12-16 02:10:15 +00:00
_resMan - > resClose ( _objectList [ screen ] ) ;
}
2003-12-20 09:12:54 +00:00
void ObjectMan : : loadLiveList ( uint16 * src ) {
for ( uint16 cnt = 0 ; cnt < TOTAL_SECTIONS ; cnt + + ) {
if ( _liveList [ cnt ] ) {
_resMan - > resClose ( _objectList [ cnt ] ) ;
_cptData [ cnt ] = NULL ;
}
_liveList [ cnt ] = src [ cnt ] ;
if ( _liveList [ cnt ] )
2011-09-07 23:54:34 +02:00
_cptData [ cnt ] = ( ( uint8 * ) _resMan - > cptResOpen ( _objectList [ cnt ] ) ) + sizeof ( Header ) ;
2003-12-20 09:12:54 +00:00
}
}
void ObjectMan : : saveLiveList ( uint16 * dest ) {
memcpy ( dest , _liveList , TOTAL_SECTIONS * sizeof ( uint16 ) ) ;
}
2004-01-11 15:47:41 +00:00
2009-02-27 05:20:37 +00:00
// String displayed when a subtitle sentence is missing in the cluster file.
2016-02-14 10:27:44 +01:00
// It happens with at least one sentence in Syria in some languages (see bug
2009-02-27 05:20:37 +00:00
// #1977094).
// Note: an empty string or a null pointer causes a crash.
char ObjectMan : : _missingSubTitleStr [ ] = " " ;
// Missing translation for textId 2950145 (see bug #1977094).
// Currently text is missing for Portuguese languages. (It's possible that it
// is not needed. The English version of the game does not include Portuguese
// so I cannot check.)
2011-09-08 00:05:09 +02:00
const char * const ObjectMan : : _translationId2950145 [ 7 ] = {
2009-02-27 05:20:37 +00:00
" Oh? " , // English (not needed)
" Quoi? " , // French
" Oh? " , // German
" Eh? " , // Italian
" \277 Eh? " , // Spanish
" Ano? " , // Czech
2012-06-26 21:19:16 +01:00
NULL // Portuguese
} ;
2012-06-26 21:31:12 +01:00
// The translations for the next texts are missing in the demo but are present
// in the full game. The translations were therefore extracted from the full game.
2012-06-26 21:19:16 +01:00
// Missing translation for textId 8455194 (in the demo).
const char * const ObjectMan : : _translationId8455194 [ 7 ] = {
NULL , // "Who was the guy you were supposed to meet?", // English (not needed)
" Qui \351 tait l'homme que vous deviez rencontrer? " , // French
" Wer war der Typ, den Du treffen wolltest? " , // German
" Chi dovevi incontrare? " , // Italian
" \277 Qui \351 n era el hombre con el que ten \355 as que encontrarte? " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 8455195 (in the demo).
const char * const ObjectMan : : _translationId8455195 [ 7 ] = {
NULL , // "His name was Plantard. I didn't know him, but he called me last night.", // English (not needed)
" Son nom \351 tait Plantard. Je ne le connaissais pas, mais il m'avait t \351 l \351 phon \351 la veille. " , // French
" Sein Name war Plantard. Ich kannte ihn nicht, aber er hat mich letzte Nacht angerufen. " , // German
" Si chiamava Plantard. Mi ha chiamato ieri sera, ma non lo conoscevo. " , // Italian
" Su nombre era Plantard. Yo no lo conoc \355 a pero \351 l me llam \363 ayer por la noche. " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 8455196 (in the demo).
const char * const ObjectMan : : _translationId8455196 [ 7 ] = {
NULL , // "He said he had a story which would interest me.", // English (not needed)
" Il a dit qu'il avait une histoire qui devrait m'int \351 resser. " , // French
" Er sagte, er h \344 tte eine Story, die mich interessieren w \374 rde. " , // German
" Mi disse che aveva una storia che mi poteva interessare. " , // Italian
" Dijo que ten \355 a una historia que me interesar \355 a. " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 8455197 (in the demo).
const char * const ObjectMan : : _translationId8455197 [ 7 ] = {
NULL , // "He asked me to meet him at the caf\351.", // English (not needed)
" Il m'a demand \351 de le rencontrer au caf \351 . " , // French
" Er fragte mich, ob wir uns im Caf \351 treffen k \366 nnten. " , // German
" Mi chiese di incontrarci al bar. " , // Italian
" Me pidi \363 que nos encontr \341 ramos en el caf \351 . " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 8455198 (in the demo).
const char * const ObjectMan : : _translationId8455198 [ 7 ] = {
NULL , // "I guess I'll never know what he wanted to tell me...", // English (not needed)
" Je suppose que je ne saurai jamais ce qu'il voulait me dire... " , // French
" Ich werde wohl nie erfahren, was er mir sagen wollte... " , // German
" Penso che non sapr \362 mai che cosa voleva dirmi... " , // Italian
" Supongo que nunca sabr \351 qu \351 me quer \355 a contar... " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 8455199 (in the demo).
const char * const ObjectMan : : _translationId8455199 [ 7 ] = {
NULL , // "Not unless you have Rosso's gift for psychic interrogation.", // English (not needed)
" Non, \340 moins d'avoir les dons de Rosso pour les interrogatoires psychiques. " , // French
" Es sei denn, Du h \344 ttest Rosso's Gabe der parapsychologischen Befragung. " , // German
" A meno che tu non riesca a fare interrogatori telepatici come Rosso. " , // Italian
" A no ser que tengas el don de Rosso para la interrogaci \363 n ps \355 quica. " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 8455200 (in the demo).
const char * const ObjectMan : : _translationId8455200 [ 7 ] = {
NULL , // "How did Plantard get your name?", // English (not needed)
" Comment Plantard a-t-il obtenu votre nom? " , // French
" Woher hat Plantard Deinen Namen? " , // German
" Come ha fatto Plantard a sapere il tuo nome? " , // Italian
" \277 C \363 mo consigui \363 Plantard tu nombre? " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 8455201 (in the demo).
const char * const ObjectMan : : _translationId8455201 [ 7 ] = {
NULL , // "Through the newspaper - La Libert\351.", // English (not needed)
" Par mon journal... La Libert \351 . " , // French
" \334 ber die Zeitung - La Libert \351 . " , // German
" Tramite il giornale La Libert \351 . " , // Italian
" Por el peri \363 dico - La Libert \351 . " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 8455202 (in the demo).
const char * const ObjectMan : : _translationId8455202 [ 7 ] = {
NULL , // "I'd written an article linking two unsolved murders, one in Italy, the other in Japan.", // English (not needed)
" J'ai \351 crit un article o \371 je faisais le lien entre deux meurtres inexpliqu \351 s, en Italie et au japon. " , // French
" Ich habe einen Artikel geschrieben, in dem ich zwei ungel \366 ste Morde miteinander in Verbindung bringe, einen in Italien, einen anderen in Japan. " , // German
" Ho scritto un articolo che metteva in collegamento due omicidi insoluti in Italia e Giappone. " , // Italian
" Yo hab \355 a escrito un art \355 culo conectando dos asesinatos sin resolver, uno en Italia, el otro en Jap \363 n. " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 8455203 (in the demo).
const char * const ObjectMan : : _translationId8455203 [ 7 ] = {
NULL , // "The cases were remarkably similar...", // English (not needed)
" Les affaires \351 taient quasiment identiques... " , // French
" Die F \344 lle sind sich bemerkenswert \344 hnlich... " , // German
" I casi erano sorprendentemente uguali... " , // Italian
" Los casos eran incre \355 blemente parecidos... " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 8455204 (in the demo).
const char * const ObjectMan : : _translationId8455204 [ 7 ] = {
NULL , // "...a wealthy victim, no apparent motive, and a costumed killer.", // English (not needed)
" ...une victime riche, pas de motif apparent, et un tueur d \351 guis \351 . " , // French
" ...ein wohlhabendes Opfer, kein offensichtliches Motiv, und ein verkleideter Killer. " , // German
" ...una vittima ricca, nessun motivo apparente e un assassino in costume. " , // Italian
" ...una v \355 ctima rica, sin motivo aparente, y un asesino disfrazado. " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 8455205 (in the demo).
const char * const ObjectMan : : _translationId8455205 [ 7 ] = {
NULL , // "Plantard said he could supply me with more information.", // English (not needed)
" Plantard m'a dit qu'il pourrait me fournir des renseignements. " , // French
" Plantard sagte, er k \366 nne mir weitere Informationen beschaffen. " , // German
" Plantard mi disse che mi avrebbe fornito ulteriori informazioni. " , // Italian
" Plantard dijo que \351 l me pod \355 a proporcionar m \341 s informaci \363 n. " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 6488080 (in the demo).
const char * const ObjectMan : : _translationId6488080 [ 7 ] = {
NULL , // "I wasn't going to head off all over Paris until I'd investigated some more.", // English (not needed)
" Je ferais mieux d'enqu \351 ter un peu par ici avant d'aller me promener ailleurs. " , // French
" Ich durchquere nicht ganz Paris, bevor ich etwas mehr herausgefunden habe. " , // German
" Non mi sarei incamminato per tutta Parigi prima di ulteriori indagini. " , // Italian
" No iba a ponerme a recorrer Par \355 s sin haber investigado un poco m \341 s. " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
2012-06-26 21:31:12 +01:00
// The next three sentences are specific to the demo and only the english text is present.
// The translations were provided by:
// French: Thierry Crozat
// German: Simon Sawatzki
// Italian: Matteo Angelino
// Spanish: Tomás Maidagan
2012-06-26 21:19:16 +01:00
// Missing translation for textId 6488081 (in the demo).
const char * const ObjectMan : : _translationId6488081 [ 7 ] = {
NULL , // "I wasn't sure what I was going to do when I caught up with that clown...", // English (not needed)
" Je ne savais pas ce que je ferais quand je rattraperais le clown... " , // French
" Ich wu \337 te nicht, worauf ich mich einlie \337 , als ich dem Clown nachjagte... " , // German
" Non sapevo cosa avrei fatto una volta raggiunto quel clown... " , // Italian
" No sab \355 a muy bien qu \351 es lo que har \355 a cuando alcanzara al payaso... " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 6488082 (in the demo).
const char * const ObjectMan : : _translationId6488082 [ 7 ] = {
NULL , // "...but before I knew it, I was drawn into a desperate race between two ruthless enemies.", // English (not needed)
" ...mais avant de m'en rendre compte je me retrouvais happ \351 dans une course effr \351 n \351 e entre deux ennemis impitoyables. " , // French
" ... doch bevor ich mich versah, war ich inmitten eines Wettlaufs von zwei r \374 cksichtslosen Feinden. " , // German
" ... ma prima che me ne rendessi conto, fui trascinato in una corsa disperata con due spietati nemici. " , // Italian
" ...pero sin darme cuenta, acab \351 en medio de una desesperada carrera entre dos despiadados enemigos. " , // Spanish
NULL , // Czech
NULL // Portuguese
} ;
// Missing translation for textId 6488083 (in the demo).
const char * const ObjectMan : : _translationId6488083 [ 7 ] = {
NULL , // "The goal: the mysterious power of the Broken Sword.", // English (not needed)
" Le but: les pouvoirs myst \351 rieux de l' \351 p \351 e bris \351 e. " , // French
" Das Ziel: die geheimnisvolle Macht des zerbrochenen Schwertes. " , // German
" Obiettivo: il misterioso potere della Spada spezzata. " , // Italian
" El objetivo: el misterioso poder de la Espada Rota. " , // Spanish
NULL , // Czech
NULL // Portuguese
2009-02-27 05:20:37 +00:00
} ;
2004-10-21 03:47:15 +00:00
2004-01-11 15:47:41 +00:00
} // End of namespace Sword1