2017-05-26 05:24:38 +02: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 .
*
* 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 .
*
*/
2017-05-27 20:16:54 +02:00
# include "common/file.h"
2017-05-30 09:59:56 +02:00
# include "common/debug.h"
2017-06-05 19:10:47 +02:00
# include "sludge/stringy.h"
# include "sludge/allfiles.h"
# include "sludge/moreio.h"
# include "sludge/newfatal.h"
# include "sludge/sludge.h"
# include "sludge/CommonCode/version.h"
2017-05-27 20:16:54 +02:00
2017-05-26 21:25:11 +02:00
namespace Sludge {
2017-05-26 05:24:38 +02:00
bool sliceBusy = true ;
2017-05-27 20:16:54 +02:00
Common : : File * bigDataFile = NULL ;
2017-06-05 19:58:32 +02:00
uint32 startOfDataIndex , startOfTextIndex , startOfSubIndex , startOfObjectIndex ;
2017-05-26 05:24:38 +02:00
bool openSubSlice ( int num ) {
// FILE * dbug = fopen ("debuggy.txt", "at");
// fprintf (dbug, "\nTrying to open sub %i\n", num);
if ( sliceBusy ) {
fatal ( " Can't read from data file " , " I'm already reading something " ) ;
return false ;
}
// fprintf (dbug, "Going to position %li\n", startOfSubIndex + (num << 2));
2017-05-27 20:16:54 +02:00
bigDataFile - > seek ( startOfSubIndex + ( num < < 2 ) , 0 ) ;
2017-05-30 09:59:56 +02:00
bigDataFile - > seek ( bigDataFile - > readUint32LE ( ) , 0 ) ;
2017-05-26 05:24:38 +02:00
// fprintf (dbug, "Told to skip forward to %li\n", ftell (bigDataFile));
// fclose (dbug);
return sliceBusy = true ;
}
bool openObjectSlice ( int num ) {
// FILE * dbug = fopen ("debuggy.txt", "at");
// fprintf (dbug, "\nTrying to open object %i\n", num);
if ( sliceBusy ) {
fatal ( " Can't read from data file " , " I'm already reading something " ) ;
return false ;
}
// fprintf (dbug, "Going to position %li\n", startOfObjectIndex + (num << 2));
2017-05-27 20:16:54 +02:00
bigDataFile - > seek ( startOfObjectIndex + ( num < < 2 ) , 0 ) ;
2017-05-30 09:59:56 +02:00
bigDataFile - > seek ( bigDataFile - > readUint32LE ( ) , 0 ) ;
2017-05-26 05:24:38 +02:00
// fprintf (dbug, "Told to skip forward to %li\n", ftell (bigDataFile));
// fclose (dbug);
return sliceBusy = true ;
}
2017-07-10 21:44:14 +02:00
uint openFileFromNum ( int num ) {
2017-05-26 05:24:38 +02:00
// FILE * dbug = fopen ("debuggy.txt", "at");
if ( sliceBusy ) {
fatal ( " Can't read from data file " , " I'm already reading something " ) ;
return 0 ;
}
// fprintf (dbug, "\nTrying to open file %i\n", num);
// fprintf (dbug, "Jumping to %li (for index) \n", startOfDataIndex + (num << 2));
2017-05-27 20:16:54 +02:00
bigDataFile - > seek ( startOfDataIndex + ( num < < 2 ) , 0 ) ;
2017-05-30 09:59:56 +02:00
bigDataFile - > seek ( bigDataFile - > readUint32LE ( ) , 1 ) ;
2017-05-26 05:24:38 +02:00
// fprintf (dbug, "Jumping to %li (for data) \n", ftell (bigDataFile));
sliceBusy = true ;
// fclose (dbug);
2017-05-30 09:59:56 +02:00
return bigDataFile - > readUint32LE ( ) ;
2017-05-26 05:24:38 +02:00
}
// Converts a string from Windows CP-1252 to UTF-8.
// This is needed for old games.
char * convertString ( char * s ) {
2017-05-27 20:16:54 +02:00
#if 0
2017-05-26 05:24:38 +02:00
static char * buf = NULL ;
if ( ! buf ) {
buf = new char [ 65536 ] ;
if ( ! checkNew ( buf ) ) return NULL ;
}
char * * tmp1 = ( char * * ) & s ;
char * * tmp2 = ( char * * ) & buf ;
char * sOrig = s ;
char * bufOrig = buf ;
# if defined __unix__ && !(defined __APPLE__)
iconv_t convert = iconv_open ( " UTF-8 " , " ISO8859-2 " ) ;
# else
iconv_t convert = iconv_open ( " UTF-8 " , " CP1250 " ) ;
# endif
if ( convert = = ( iconv_t ) - 1 ) {
switch ( errno ) {
2017-05-29 08:02:59 +02:00
case EINVAL :
2017-05-26 05:24:38 +02:00
fprintf ( stderr , " Error: Encoding not supported by iconv. \n " ) ;
break ;
2017-05-29 08:02:59 +02:00
default :
2017-05-26 05:24:38 +02:00
fprintf ( stderr , " Error: Could not open iconv conversion descriptor. \n " ) ;
}
}
2017-07-10 21:44:14 +02:00
uint len1 = strlen ( s ) + 1 ;
uint len2 = 65535 ;
uint iconv_value =
2017-05-26 05:24:38 +02:00
# ifdef _WIN32
2017-05-29 08:02:59 +02:00
iconv ( convert , ( const char * * ) tmp1 , & len1 , tmp2 , & len2 ) ;
2017-05-26 05:24:38 +02:00
# else
2017-05-29 08:02:59 +02:00
iconv ( convert , ( char * * ) tmp1 , & len1 , tmp2 , & len2 ) ;
2017-05-26 05:24:38 +02:00
# endif
2017-07-10 21:44:14 +02:00
if ( iconv_value = = ( uint ) - 1 ) {
2017-05-26 05:24:38 +02:00
switch ( errno ) {
2017-05-29 08:02:59 +02:00
/* See "man 3 iconv" for an explanation. */
case EILSEQ :
2017-05-26 05:24:38 +02:00
fprintf ( stderr , " Invalid multibyte sequence. \n " ) ;
break ;
2017-05-29 08:02:59 +02:00
case EINVAL :
2017-05-26 05:24:38 +02:00
fprintf ( stderr , " Incomplete multibyte sequence. \n " ) ;
break ;
2017-05-29 08:02:59 +02:00
case E2BIG :
2017-05-26 05:24:38 +02:00
fprintf ( stderr , " No more room. \n " ) ;
break ;
2017-05-29 08:02:59 +02:00
default :
2017-05-26 05:24:38 +02:00
fprintf ( stderr , " Error: %s. \n " , strerror ( errno ) ) ;
}
fatal ( " Conversion to Unicode failed. This can be fixed by recompiling the game in a current version of the SLUDGE Development Kit, but this error should never happen. Congratulations, you've found a bug in the SLUDGE engine! Please let us know about it. " ) ;
}
iconv_close ( convert ) ;
delete [ ] sOrig ;
return copyString ( buf = bufOrig ) ;
2017-05-27 20:16:54 +02:00
# endif
2017-05-29 08:02:59 +02:00
return s ; //TODO: false value
2017-05-26 05:24:38 +02:00
}
char * getNumberedString ( int value ) {
if ( sliceBusy ) {
fatal ( " Can't read from data file " , " I'm already reading something " ) ;
return NULL ;
}
2017-05-27 20:16:54 +02:00
bigDataFile - > seek ( ( value < < 2 ) + startOfTextIndex , 0 ) ;
2017-05-30 09:59:56 +02:00
value = bigDataFile - > readUint32LE ( ) ;
2017-05-27 20:16:54 +02:00
bigDataFile - > seek ( value , 0 ) ;
2017-05-26 05:24:38 +02:00
char * s = readString ( bigDataFile ) ;
if ( gameVersion < VERSION ( 2 , 2 ) ) {
// This is an older game - We need to convert the string to UTF-8
s = convertString ( s ) ;
}
return s ;
}
bool startAccess ( ) {
int wasBusy = sliceBusy ;
sliceBusy = true ;
return wasBusy ;
}
void finishAccess ( ) {
sliceBusy = false ;
}
int32_t startIndex ;
2017-07-10 21:44:14 +02:00
void setFileIndices ( Common : : File * fp , int numLanguages , uint skipBefore ) {
2017-05-26 05:24:38 +02:00
if ( fp ) {
// Keep hold of the file handle, and let things get at it
bigDataFile = fp ;
2017-05-27 20:16:54 +02:00
startIndex = fp - > pos ( ) ;
2017-05-26 05:24:38 +02:00
} else {
// No file pointer - this means that we reuse the bigDataFile
fp = bigDataFile ;
2017-05-27 20:16:54 +02:00
fp - > seek ( startIndex , SEEK_SET ) ;
2017-05-26 05:24:38 +02:00
}
sliceBusy = false ;
if ( skipBefore > numLanguages ) {
warning ( " Not a valid language ID! Using default instead. " ) ;
skipBefore = 0 ;
}
// STRINGS
int skipAfter = numLanguages - skipBefore ;
while ( skipBefore ) {
2017-05-30 09:59:56 +02:00
fp - > seek ( fp - > readUint32LE ( ) , SEEK_SET ) ;
2017-05-29 08:02:59 +02:00
skipBefore - - ;
2017-05-26 05:24:38 +02:00
}
2017-05-27 20:16:54 +02:00
startOfTextIndex = fp - > pos ( ) + 4 ;
2017-05-30 09:59:56 +02:00
debug ( kSludgeDebugDataLoad , " startOfTextIndex: %i " , startOfTextIndex ) ;
2017-05-26 05:24:38 +02:00
2017-05-30 09:59:56 +02:00
fp - > seek ( fp - > readUint32LE ( ) , SEEK_SET ) ;
2017-05-26 05:24:38 +02:00
while ( skipAfter ) {
2017-05-30 09:59:56 +02:00
fp - > seek ( fp - > readUint32LE ( ) , SEEK_SET ) ;
2017-05-29 08:02:59 +02:00
skipAfter - - ;
2017-05-26 05:24:38 +02:00
}
2017-05-27 20:16:54 +02:00
startOfSubIndex = fp - > pos ( ) + 4 ;
2017-05-30 09:59:56 +02:00
fp - > seek ( fp - > readUint32LE ( ) , SEEK_CUR ) ;
2017-06-28 16:30:05 +02:00
debug ( kSludgeDebugDataLoad , " startOfSubIndex: %i " , startOfSubIndex ) ;
2017-05-26 05:24:38 +02:00
2017-05-27 20:16:54 +02:00
startOfObjectIndex = fp - > pos ( ) + 4 ;
2017-05-30 09:59:56 +02:00
fp - > seek ( fp - > readUint32LE ( ) , SEEK_CUR ) ;
2017-06-28 16:30:05 +02:00
debug ( kSludgeDebugDataLoad , " startOfObjectIndex: %i " , startOfObjectIndex ) ;
2017-05-26 05:24:38 +02:00
// Remember that the data section starts here
2017-05-27 20:16:54 +02:00
startOfDataIndex = fp - > pos ( ) ;
2017-06-28 16:30:05 +02:00
debug ( kSludgeDebugDataLoad , " startOfDataIndex: %i " , startOfDataIndex ) ;
2017-05-26 05:24:38 +02:00
}
2017-05-26 21:25:11 +02:00
} // End of namespace Sludge