aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicola Mettifogo2007-04-01 12:45:42 +0000
committerNicola Mettifogo2007-04-01 12:45:42 +0000
commitb7e499b64a1b1dc88c375a6151b7789d1970f4d5 (patch)
tree04c0b75a8af25cdf54bd4e919253bf6238c22b0d
parent20c2bba08411d5ce6e28a7a465425f60ebecc8db (diff)
downloadscummvm-rg350-b7e499b64a1b1dc88c375a6151b7789d1970f4d5.tar.gz
scummvm-rg350-b7e499b64a1b1dc88c375a6151b7789d1970f4d5.tar.bz2
scummvm-rg350-b7e499b64a1b1dc88c375a6151b7789d1970f4d5.zip
Implemented Disk routines for Amiga demo. Font are simulated with boxes, and frames aren't decoded properly yet. The engine will now show the first game screen, but crash as soon as the user clicks her mouse.
svn-id: r26341
-rw-r--r--engines/parallaction/disk.cpp263
-rw-r--r--engines/parallaction/disk.h5
2 files changed, 256 insertions, 12 deletions
diff --git a/engines/parallaction/disk.cpp b/engines/parallaction/disk.cpp
index bc12f480ec..eaedcf5017 100644
--- a/engines/parallaction/disk.cpp
+++ b/engines/parallaction/disk.cpp
@@ -684,49 +684,240 @@ AmigaDisk::~AmigaDisk() {
}
+// FIXME: unpacking doesn't work
+void AmigaDisk::unpackBitmap(byte *dst, byte *src, uint16 height, uint16 bytesPerPlane) {
+
+ byte s0, s1, s2, s3, s4, mask, t0, t1, t2, t3, t4;
+
+ for (uint32 k = 0; k < height; k++) {
+ for (uint32 i = 0; i < bytesPerPlane; i++) {
+ s0 = src[i];
+ s1 = src[i+bytesPerPlane];
+ s2 = src[i+bytesPerPlane*2];
+ s3 = src[i+bytesPerPlane*3];
+ s4 = src[i+bytesPerPlane*4];
+
+ for (uint32 j = 0; j < 8; j++) {
+ mask = 1 << (7 - j);
+ t0 = (s0 & mask ? 1 : 0);
+ t1 = (s1 & mask ? 1 : 0);
+ t2 = (s2 & mask ? 1 : 0);
+ t3 = (s3 & mask ? 1 : 0);
+ t4 = (s4 & mask ? 1 : 0);
+ *dst++ = t0 + (t1 << 1) + (t2 << 2) + (t3 << 3) + (t4 << 4);
+ }
+ }
+ }
+
+}
+
+StaticCnv* AmigaDisk::makeStaticCnv(Common::SeekableReadStream &stream) {
+#define NUM_PLANES 5
+
+ uint16 numFrames = stream.readByte();
+ uint16 width = stream.readByte();
+ uint16 height = stream.readByte();
+
+ assert(numFrames == 1 && (width & 7) == 0);
+
+ uint32 rawsize = (width * height * NUM_PLANES) / 8;
+ byte *buf = (byte*)malloc(rawsize);
+ stream.read(buf, rawsize);
+
+ uint32 decsize = width * height;
+ byte *data = (byte*)calloc(decsize, 1);
+
+ unpackBitmap(data, buf, height, width / 8);
+
+ free(buf);
+
+ StaticCnv *cnv = new StaticCnv();
+ cnv->_width = width;
+ cnv->_height = height;
+ cnv->_data0 = data;
+ cnv->_data1 = NULL;
+
+ return cnv;
+#undef NUM_PLANES
+}
+
+Cnv* AmigaDisk::makeCnv(Common::SeekableReadStream &stream) {
+#define NUM_PLANES 5
+
+ uint16 numFrames = stream.readByte();
+ uint16 width = stream.readByte();
+ uint16 height = stream.readByte();
+
+ assert((width & 7) == 0);
+
+ uint32 rawsize = (numFrames * width * height * NUM_PLANES) / 8;
+ byte *buf = (byte*)malloc(rawsize);
+ stream.read(buf, rawsize);
+
+ uint32 decsize = numFrames * width * height;
+ byte *data = (byte*)calloc(decsize, 1);
+
+ unpackBitmap(data, buf, height, width / 8);
+
+ free(buf);
+
+ return new Cnv(numFrames, width, height, data);
+#undef NUM_PLANES
+}
+
+
Script* AmigaDisk::loadLocation(const char *name) {
debugC(1, kDebugDisk, "AmigaDisk::loadLocation '%s'", name);
- return NULL;
+
+ char path[PATH_LEN];
+
+ sprintf(path, "%s%s%s.loc.pp", _vm->_characterName, _languageDir, name);
+
+ _languageDir[2] = '\0';
+ _archive.open(_languageDir);
+ _languageDir[2] = '/';
+
+ if (!_archive.openArchivedFile(path))
+ error("can't find location file '%s'", path);
+
+ DecrunchStream stream(_archive);
+
+ uint32 size = stream.size();
+ char *buf = (char*)malloc(size+1);
+ stream.read(buf, size);
+ buf[size] = '\0';
+
+ return new Script(buf, true);
}
Script* AmigaDisk::loadScript(const char* name) {
debugC(1, kDebugDisk, "AmigaDisk::loadScript '%s'", name);
- return NULL;
+
+ char vC8[PATH_LEN];
+
+ sprintf(vC8, "%s.script", name);
+
+ if (!_archive.openArchivedFile(vC8))
+ errorFileNotFound(vC8);
+
+ uint32 size = _archive.size();
+ char *buf = (char*)malloc(size+1);
+ _archive.read(buf, size);
+ buf[size] = '\0';
+
+ return new Script(buf, true);
}
Cnv* AmigaDisk::loadTalk(const char *name) {
debugC(1, kDebugDisk, "AmigaDisk::loadTalk '%s'", name);
- return NULL;
+
+ char path[PATH_LEN];
+ sprintf(path, "%s.talk.pp", name);
+ if (!_archive.openArchivedFile(path)) {
+ sprintf(path, "%s.talk.dd", name);
+ if (!_archive.openArchivedFile(path))
+ error("can't open talk '%s' from archive", path);
+ }
+
+ DecrunchStream stream(_archive);
+ return makeCnv(stream);
}
Cnv* AmigaDisk::loadObjects(const char *name) {
debugC(1, kDebugDisk, "AmigaDisk::loadObjects");
- return NULL;
+
+ char path[PATH_LEN];
+ sprintf(path, "%s.objs.pp", name);
+
+ if (!_archive.openArchivedFile(path))
+ error("can't open objects '%s' from archive", path);
+
+ DecrunchStream stream(_archive);
+ return makeCnv(stream);
}
+
StaticCnv* AmigaDisk::loadPointer() {
debugC(1, kDebugDisk, "AmigaDisk::loadPointer");
- return NULL;
+
+ Common::File stream;
+ if (!stream.open("pointer"))
+ error("can't open pointer file");
+
+ return makeStaticCnv(stream);
}
StaticCnv* AmigaDisk::loadHead(const char* name) {
debugC(1, kDebugDisk, "AmigaDisk::loadHead '%s'", name);
- return NULL;
+
+ char path[PATH_LEN];
+ sprintf(path, "%s.head", name);
+
+ if (!_archive.openArchivedFile(path))
+ error("can't open frames '%s' from archive", path);
+
+ DecrunchStream stream(_archive);
+ return makeStaticCnv(stream);
}
Cnv* AmigaDisk::loadFont(const char* name) {
debugC(1, kDebugDisk, "AmigaDisk::loadFont '%s'", name);
- return NULL;
+
+ char path[PATH_LEN];
+ if (scumm_stricmp(name, "topaz"))
+ sprintf(path, "%sfont", name);
+ else
+ strcpy(path, "introfont");
+
+ if (!_archive.openArchivedFile(path))
+ error("can't open font '%s' from archive", path);
+
+ // FIXME: actually read data from font file and create
+ // real font instead of this dummy one
+ byte *data = (byte*)malloc(256*8*8);
+ memset(data, 0, 256*8*8);
+ return new Cnv(256, 8, 8, data);
}
StaticCnv* AmigaDisk::loadStatic(const char* name) {
debugC(1, kDebugDisk, "AmigaDisk::loadStatic '%s'", name);
- return NULL;
+
+ if (!_archive.openArchivedFile(name))
+ error("can't open static '%s' from archive", name);
+
+ DecrunchStream stream(_archive);
+ return makeStaticCnv(stream);
}
Cnv* AmigaDisk::loadFrames(const char* name) {
debugC(1, kDebugDisk, "AmigaDisk::loadFrames '%s'", name);
- return NULL;
+
+ if (IS_MINI_CHARACTER(name))
+ return NULL;
+
+ Common::SeekableReadStream *s;
+ bool dispose = false;
+
+ char path[PATH_LEN];
+ sprintf(path, "%s.pp", name);
+ if (!_archive.openArchivedFile(path)) {
+ if (!_archive.openArchivedFile(name))
+ error("can't open frames '%s' from archive", name);
+
+ s = &_archive;
+ }
+ else {
+ DecrunchStream *stream = new DecrunchStream(_archive);
+ s = stream;
+ dispose = true;
+ }
+
+ Cnv *cnv = makeCnv(*s);
+
+ if (dispose)
+ delete s;
+
+ return cnv;
}
void AmigaDisk::loadSlide(const char *name) {
@@ -763,15 +954,62 @@ void AmigaDisk::loadSlide(const char *name) {
void AmigaDisk::loadScenery(const char* background, const char* mask) {
debugC(1, kDebugDisk, "AmigaDisk::loadScenery '%s', '%s'", background, mask);
+
+ Graphics::Surface surf;
+ byte *pal;
+ char path[PATH_LEN];
+ Graphics::ILBMDecoder *decoder;
+ DecrunchStream *stream;
+
+ sprintf(path, "%s.bkgnd.pp", background);
+ if (!_archive.openArchivedFile(path))
+ error("can't open background file %s", path);
+
+ stream = new DecrunchStream(_archive);
+ decoder = new Graphics::ILBMDecoder(*stream);
+ decoder->decode(surf, pal);
+ for (uint32 i = 0; i < PALETTE_SIZE; i++)
+ _vm->_gfx->_palette[i] = pal[i] >> 2;
+ free(pal);
+ _vm->_gfx->setPalette(_vm->_gfx->_palette);
+ _vm->_gfx->setBackground(static_cast<byte*>(surf.pixels));
+ surf.free();
+ delete decoder;
+ delete stream;
+
+ sprintf(path, "%s.mask.pp", background);
+ if (!_archive.openArchivedFile(path))
+ error("can't open mask file %s", path);
+ stream = new DecrunchStream(_archive);
+ decoder = new Graphics::ILBMDecoder(*stream);
+ decoder->decode(surf, pal);
+ _vm->_gfx->setMask(static_cast<byte*>(surf.pixels));
+ surf.free();
+ delete decoder;
+ delete stream;
+
+ sprintf(path, "%s.path.pp", background);
+ if (!_archive.openArchivedFile(path))
+ error("can't open path file %s", path);
+ stream = new DecrunchStream(_archive);
+ decoder = new Graphics::ILBMDecoder(*stream);
+ decoder->decode(surf, pal);
+ setPath(static_cast<byte*>(surf.pixels));
+ surf.free();
+ delete decoder;
+ delete stream;
+
return;
}
Table* AmigaDisk::loadTable(const char* name) {
-// printf("AmigaDisk::loadTable\n");
+ debugC(1, kDebugDisk, "AmigaDisk::loadTable '%s'", name);
char path[PATH_LEN];
sprintf(path, "%s.table", name);
+ bool dispose = false;
+
Common::SeekableReadStream *stream;
if (!scumm_stricmp(name, "global")) {
@@ -779,12 +1017,12 @@ Table* AmigaDisk::loadTable(const char* name) {
if (!s->open(path))
error("can't open %s", path);
+ dispose = true;
stream = s;
} else {
if (!_archive.openArchivedFile(path))
error("can't open archived file %s", path);
-// DecrunchStream *s = new DecrunchStream(_archive);
stream = &_archive;
}
@@ -796,7 +1034,8 @@ Table* AmigaDisk::loadTable(const char* name) {
fillBuffers(*stream);
}
- delete stream;
+ if (dispose)
+ delete stream;
return t;
}
diff --git a/engines/parallaction/disk.h b/engines/parallaction/disk.h
index e88443a1ef..c34933f683 100644
--- a/engines/parallaction/disk.h
+++ b/engines/parallaction/disk.h
@@ -142,6 +142,11 @@ public:
class AmigaDisk : public Disk {
+protected:
+ Cnv* makeCnv(Common::SeekableReadStream &stream);
+ StaticCnv* makeStaticCnv(Common::SeekableReadStream &stream);
+ void unpackBitmap(byte *dst, byte *src, uint16 height, uint16 bytesPerPlane);
+
public:
AmigaDisk(Parallaction *vm);
virtual ~AmigaDisk();