aboutsummaryrefslogtreecommitdiff
path: root/engines/tinsel
diff options
context:
space:
mode:
authorPaul Gilbert2010-11-20 03:14:03 +0000
committerPaul Gilbert2010-11-20 03:14:03 +0000
commita2367d26f9d7f8523c313a7b82d0b719de1e6e15 (patch)
treee63bfc6e1a8bd82f00ed24fdf167c6259676cc38 /engines/tinsel
parentb2ba35124c707ca33e0372690a0eb25e316bce8a (diff)
downloadscummvm-rg350-a2367d26f9d7f8523c313a7b82d0b719de1e6e15.tar.gz
scummvm-rg350-a2367d26f9d7f8523c313a7b82d0b719de1e6e15.tar.bz2
scummvm-rg350-a2367d26f9d7f8523c313a7b82d0b719de1e6e15.zip
TINSEL: Preliminary functionality for reading BE data files
svn-id: r54392
Diffstat (limited to 'engines/tinsel')
-rw-r--r--engines/tinsel/detection_tables.h23
-rw-r--r--engines/tinsel/dialogs.cpp15
-rw-r--r--engines/tinsel/drives.cpp32
-rw-r--r--engines/tinsel/drives.h23
-rw-r--r--engines/tinsel/handle.cpp8
-rw-r--r--engines/tinsel/scn.cpp9
-rw-r--r--engines/tinsel/sound.cpp8
-rw-r--r--engines/tinsel/strres.cpp2
-rw-r--r--engines/tinsel/tinsel.cpp8
-rw-r--r--engines/tinsel/tinsel.h9
10 files changed, 113 insertions, 24 deletions
diff --git a/engines/tinsel/detection_tables.h b/engines/tinsel/detection_tables.h
index 239e06c8dd..2a523470cc 100644
--- a/engines/tinsel/detection_tables.h
+++ b/engines/tinsel/detection_tables.h
@@ -77,7 +77,26 @@ static const TinselGameDescription gameDescriptions[] = {
GF_CD,
TINSEL_V1,
},
-
+#if 0
+ { // Macintosh CD Demo V1 version, with *.scn files
+ {
+ "dw",
+ "CD Demo",
+ {
+ {"dw.scn", 0, "ae291aa4ed7f7caacbfb711b6ff2c8bd", 1286264},
+ {"english.smp", 0, NULL, -1},
+ },
+ Common::EN_ANY,
+ Common::kPlatformMacintosh,
+ ADGF_DEMO,
+ GUIO_NONE
+ },
+ GID_DW1,
+ 0,
+ GF_CD | GF_BIG_ENDIAN,
+ TINSEL_V1,
+ },
+#endif
{ // Multilingual Floppy V1 with *.gra files.
// Note: It contains no english subtitles.
{
@@ -444,7 +463,7 @@ static const TinselGameDescription gameDescriptions[] = {
},
GID_DW1,
0,
- GF_CD | GF_SCNFILES | GF_ENHANCED_AUDIO_SUPPORT,
+ GF_CD | GF_SCNFILES | GF_ENHANCED_AUDIO_SUPPORT | GF_BIG_ENDIAN,
TINSEL_V1,
},
diff --git a/engines/tinsel/dialogs.cpp b/engines/tinsel/dialogs.cpp
index 0a02924f12..73cad7a68f 100644
--- a/engines/tinsel/dialogs.cpp
+++ b/engines/tinsel/dialogs.cpp
@@ -5551,6 +5551,21 @@ extern void RegisterIcons(void *cptr, int num) {
memmove(destP, srcP, 12);
destP->attribute = 0;
}
+ } else if (TinselV1Mac) {
+ // Macintosh version has BE encoded resources, so the values need to be byte swapped
+ MEM_NODE *node = MemoryAllocFixed(numObjects * sizeof(INV_OBJECT));
+ assert(node);
+ invObjects = (INV_OBJECT *)MemoryDeref(node);
+ assert(invObjects);
+ INV_OBJECT *srcP = (INV_OBJECT *)cptr;
+ INV_OBJECT *destP = (INV_OBJECT *)invObjects;
+
+ for (int i = 0; i < num; ++i, ++destP, ++srcP) {
+ destP->id = FROM_BE_32(srcP->id);
+ destP->hIconFilm = FROM_BE_32(srcP->hIconFilm);
+ destP->hScript = FROM_BE_32(srcP->hScript);
+ destP->attribute = FROM_BE_32(srcP->attribute);
+ }
} else if (TinselV2) {
if (invFilms == NULL) {
// First time - allocate memory
diff --git a/engines/tinsel/drives.cpp b/engines/tinsel/drives.cpp
index 61da0345a8..58d0978426 100644
--- a/engines/tinsel/drives.cpp
+++ b/engines/tinsel/drives.cpp
@@ -24,6 +24,7 @@
* CD/drive handling functions
*/
+#include "common/config-manager.h"
#include "gui/message.h"
#include "tinsel/drives.h"
#include "tinsel/scene.h"
@@ -151,13 +152,29 @@ bool GotoCD() {
bool TinselFile::_warningShown = false;
-bool TinselFile::open(const Common::String &filename) {
- if (Common::File::open(filename)) {
- // If it's the sample file, strip off the CD number from the filename
+TinselFile::TinselFile() {
+ _stream = NULL;
+}
+
+TinselFile::~TinselFile() {
+ delete _stream;
+}
+
+bool TinselFile::openInternal(const Common::String &filename) {
+ const Common::FSNode gameDataDir(ConfMan.get("path"));
+ const Common::FSNode fsNode = gameDataDir.getChild(filename);
+ Common::SeekableReadStream *stream = fsNode.createReadStream();
+ if (!stream)
+ return false;
+ _stream = new Common::SeekableSubReadStreamEndian(stream, 0, stream->size(),
+ (_vm->getFeatures() & GF_BIG_ENDIAN) != 0, DisposeAfterUse::YES);
+ return true;
+}
+bool TinselFile::open(const Common::String &filename) {
+ if (openInternal(filename))
return true;
- }
if (!TinselV2)
return false;
@@ -175,7 +192,12 @@ bool TinselFile::open(const Common::String &filename) {
strncpy(newFilename, fname, p - fname);
strcpy(newFilename + (p - fname), p + 1);
- return Common::File::open(newFilename);
+ return openInternal(newFilename);
+}
+
+void TinselFile::close() {
+ delete _stream;
+ _stream = NULL;
}
} // End of namespace Tinsel
diff --git a/engines/tinsel/drives.h b/engines/tinsel/drives.h
index 81111265fa..061dae625f 100644
--- a/engines/tinsel/drives.h
+++ b/engines/tinsel/drives.h
@@ -27,6 +27,8 @@
#ifndef TINSEL_DRIVES_H
#define TINSEL_DRIVES_H
+#include "common/memstream.h"
+#include "common/substream.h"
#include "common/file.h"
#include "tinsel/dw.h"
#include "tinsel/coroutine.h"
@@ -59,12 +61,29 @@ void SetNextCD(int cdNumber);
bool GotoCD();
-class TinselFile: public Common::File {
+class TinselFile {
private:
static bool _warningShown;
+ Common::SeekableSubReadStreamEndian *_stream;
+ bool openInternal(const Common::String &filename);
public:
- virtual bool open(const Common::String &filename);
+ TinselFile();
+ ~TinselFile();
+ bool open(const Common::String &filename);
+ void close();
char getCdNumber();
+
+ FORCEINLINE int32 pos() const { assert(_stream); return _stream->pos(); }
+ FORCEINLINE int32 size() const { assert(_stream); return _stream->size(); }
+ FORCEINLINE bool seek(int32 offset, int whence = SEEK_SET) { assert(_stream); return _stream->seek(offset, whence); }
+ FORCEINLINE bool eos() const { assert(_stream); return _stream->eos(); }
+ FORCEINLINE bool err() const { return _stream->err(); }
+ FORCEINLINE uint32 readUint32() { assert(_stream); return _stream->readUint32(); }
+ FORCEINLINE int16 readSint16() { assert(_stream); return _stream->readUint16(); }
+ FORCEINLINE int32 readSint32() { assert(_stream); return _stream->readUint32(); }
+ FORCEINLINE Common::SeekableReadStream *readStream(uint32 dataSize) { assert(_stream); return _stream->readStream(dataSize); }
+ FORCEINLINE uint32 read(void *dataPtr, uint32 dataSize) { assert(_stream); return _stream->read(dataPtr, dataSize); }
+ FORCEINLINE bool skip(uint32 offset) { return seek(offset, SEEK_CUR); }
};
diff --git a/engines/tinsel/handle.cpp b/engines/tinsel/handle.cpp
index 9461cf8c1c..2307d95a61 100644
--- a/engines/tinsel/handle.cpp
+++ b/engines/tinsel/handle.cpp
@@ -102,11 +102,13 @@ void SetupHandleTable() {
int len;
uint i;
MEMHANDLE *pH;
- Common::File f;
+ TinselFile f;
if (f.open(TinselV1PSX? PSX_INDEX_FILENAME : INDEX_FILENAME)) {
// get size of index file
len = f.size();
+ if (TinselV1Mac)
+ len -= 2; // Macintosh version has two redundant ending bytes
if (len > 0) {
if ((len % RECORD_SIZE) != 0) {
@@ -126,13 +128,13 @@ void SetupHandleTable() {
// load data
for (i = 0; i < numHandles; i++) {
f.read(handleTable[i].szName, 12);
- handleTable[i].filesize = f.readUint32LE();
+ handleTable[i].filesize = f.readUint32();
// The pointer should always be NULL. We don't
// need to read that from the file.
handleTable[i]._node = NULL;
f.seek(4, SEEK_CUR);
// For Discworld 2, read in the flags2 field
- handleTable[i].flags2 = t2Flag ? f.readUint32LE() : 0;
+ handleTable[i].flags2 = t2Flag ? f.readUint32() : 0;
}
if (f.eos() || f.err()) {
diff --git a/engines/tinsel/scn.cpp b/engines/tinsel/scn.cpp
index 0c89819ca0..326fd9e750 100644
--- a/engines/tinsel/scn.cpp
+++ b/engines/tinsel/scn.cpp
@@ -46,6 +46,8 @@ byte *FindChunk(SCNHANDLE handle, uint32 chunk) {
byte *bptr = LockMem(handle);
uint32 *lptr = (uint32 *)bptr;
uint32 add;
+ bool bigEndian = (_vm->getFeatures() & GF_BIG_ENDIAN) != 0;
+ assert(!bigEndian); // Big endian data not yet supported
// Initial adjustmnet for Tinsel 1 chunk types
if ((TinselVersion != TINSEL_V2) && (chunk >= CHUNK_SCENE) &&
@@ -60,14 +62,17 @@ byte *FindChunk(SCNHANDLE handle, uint32 chunk) {
chunk -= 0x2L;
while (1) {
- if (READ_LE_UINT32(lptr) == chunk)
+ if (READ_32(lptr) == chunk)
return (byte *)(lptr + 2);
++lptr;
- add = READ_LE_UINT32(lptr);
+ add = READ_32(lptr);
+
if (!add)
+ // End of file reached
return NULL;
+ // Move to next chunk
lptr = (uint32 *)(bptr + add);
}
}
diff --git a/engines/tinsel/sound.cpp b/engines/tinsel/sound.cpp
index 0624409f92..7fab3624a4 100644
--- a/engines/tinsel/sound.cpp
+++ b/engines/tinsel/sound.cpp
@@ -105,7 +105,7 @@ bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::Sound
error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
// read the length of the sample
- uint32 sampleLen = _sampleStream.readUint32LE();
+ uint32 sampleLen = _sampleStream.readUint32();
if (_sampleStream.eos() || _sampleStream.err())
error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
@@ -264,7 +264,7 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p
error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
// read the length of the sample
- uint32 sampleLen = _sampleStream.readUint32LE();
+ uint32 sampleLen = _sampleStream.readUint32();
if (_sampleStream.eos() || _sampleStream.err())
error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
@@ -277,12 +277,12 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p
// Skipping
for (int32 i = 0; i < sub; i++) {
- sampleLen = _sampleStream.readUint32LE();
+ sampleLen = _sampleStream.readUint32();
_sampleStream.skip(sampleLen);
if (_sampleStream.eos() || _sampleStream.err())
error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
}
- sampleLen = _sampleStream.readUint32LE();
+ sampleLen = _sampleStream.readUint32();
if (_sampleStream.eos() || _sampleStream.err())
error(FILE_IS_CORRUPT, _vm->getSampleFile(sampleLanguage));
}
diff --git a/engines/tinsel/strres.cpp b/engines/tinsel/strres.cpp
index 7ed9a773bc..aa303a5391 100644
--- a/engines/tinsel/strres.cpp
+++ b/engines/tinsel/strres.cpp
@@ -111,7 +111,7 @@ void ChangeLanguage(LANGUAGE newLang) {
// Check whether the file is compressed or not - for compressed files the
// first long is the filelength and for uncompressed files it is the chunk
// identifier
- textLen = f.readUint32LE();
+ textLen = f.readUint32();
if (f.eos() || f.err())
error(FILE_IS_CORRUPT, _vm->getTextFile(newLang));
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index aa5a9282fa..0e1001b398 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -722,15 +722,15 @@ void LoadBasicChunks() {
// CHUNK_TOTAL_ACTORS seems to be missing in the released version, hard coding a value
// TODO: Would be nice to just change 511 to MAX_SAVED_ALIVES
cptr = FindChunk(MASTER_SCNHANDLE, CHUNK_TOTAL_ACTORS);
- RegisterActors((cptr != NULL) ? READ_LE_UINT32(cptr) : 511);
+ RegisterActors((cptr != NULL) ? READ_32(cptr) : 511);
// CHUNK_TOTAL_GLOBALS seems to be missing in some versions.
// So if it is missing, set a reasonably high value for the number of globals.
cptr = FindChunk(MASTER_SCNHANDLE, CHUNK_TOTAL_GLOBALS);
- RegisterGlobals((cptr != NULL) ? READ_LE_UINT32(cptr) : 512);
+ RegisterGlobals((cptr != NULL) ? READ_32(cptr) : 512);
cptr = FindChunk(INV_OBJ_SCNHANDLE, CHUNK_TOTAL_OBJECTS);
- numObjects = (cptr != NULL) ? READ_LE_UINT32(cptr) : 0;
+ numObjects = (cptr != NULL) ? READ_32(cptr) : 0;
cptr = FindChunk(INV_OBJ_SCNHANDLE, CHUNK_OBJECTS);
@@ -763,7 +763,7 @@ void LoadBasicChunks() {
// CdPlay() stuff
cptr = FindChunk(MASTER_SCNHANDLE, CHUNK_CDPLAY_HANDLE);
assert(cptr);
- uint32 playHandle = READ_LE_UINT32(cptr);
+ uint32 playHandle = READ_32(cptr);
assert(playHandle < 512);
SetCdPlayHandle(playHandle);
}
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index c4f4a3bc13..b4f77d18f2 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -81,7 +81,9 @@ enum TinselGameFeatures {
// None of these defined -> 1 language, in ENGLISH.TXT
GF_USE_3FLAGS = 1 << 6, // French, German, Spanish
GF_USE_4FLAGS = 1 << 7, // French, German, Spanish, Italian
- GF_USE_5FLAGS = 1 << 8 // All 5 flags
+ GF_USE_5FLAGS = 1 << 8, // All 5 flags
+
+ GF_BIG_ENDIAN = 1 << 9
};
/**
@@ -139,8 +141,13 @@ typedef bool (*KEYFPTR)(const Common::KeyState &);
#define TinselV1 (TinselVersion == TINSEL_V1)
#define TinselV2 (TinselVersion == TINSEL_V2)
#define TinselV1PSX (TinselVersion == TINSEL_V1 && _vm->getPlatform() == Common::kPlatformPSX)
+#define TinselV1Mac (TinselVersion == TINSEL_V1 && _vm->getPlatform() == Common::kPlatformMacintosh)
+
#define IsDemo (_vm->getFeatures() & GF_DEMO)
+#define READ_16(v) ((_vm->getFeatures() & GF_BIG_ENDIAN) ? READ_BE_UINT16(v) : READ_LE_UINT16(v))
+#define READ_32(v) ((_vm->getFeatures() & GF_BIG_ENDIAN) ? READ_BE_UINT32(v) : READ_LE_UINT32(v))
+
// Global reference to the TinselEngine object
extern TinselEngine *_vm;