[Scummvm-cvs-logs] SF.net SVN: scummvm: [26311] scummvm/trunk/engines/parallaction/disk.cpp
peres001 at users.sourceforge.net
peres001 at users.sourceforge.net
Wed Mar 28 00:02:09 CEST 2007
Revision: 26311
http://scummvm.svn.sourceforge.net/scummvm/?rev=26311&view=rev
Author: peres001
Date: 2007-03-27 15:02:07 -0700 (Tue, 27 Mar 2007)
Log Message:
-----------
added code to load amiga background slides
Modified Paths:
--------------
scummvm/trunk/engines/parallaction/disk.cpp
Modified: scummvm/trunk/engines/parallaction/disk.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/disk.cpp 2007-03-27 19:45:09 UTC (rev 26310)
+++ scummvm/trunk/engines/parallaction/disk.cpp 2007-03-27 22:02:07 UTC (rev 26311)
@@ -25,6 +25,7 @@
#include "parallaction/parallaction.h"
#include "parallaction/disk.h"
#include "parallaction/walk.h"
+#include "graphics/ilbm.h"
namespace Parallaction {
@@ -427,7 +428,9 @@
void DosDisk::parseBackground(Common::SeekableReadStream &stream) {
- stream.read(_vm->_gfx->_palette, PALETTE_SIZE);
+ byte pal[96];
+ stream.read(pal, PALETTE_SIZE);
+ _vm->_gfx->setPalette(pal);
parseDepths(stream);
@@ -555,7 +558,167 @@
#pragma mark -
+/* the decoder presented here is taken from pplib by Stuart Caie. The
+ * following statement comes from the original source.
+ *
+ * pplib 1.0: a simple PowerPacker decompression and decryption library
+ * placed in the Public Domain on 2003-09-18 by Stuart Caie.
+ */
+#define PP_READ_BITS(nbits, var) do { \
+ bit_cnt = (nbits); (var) = 0; \
+ while (bits_left < bit_cnt) { \
+ if (buf < src) return 0; \
+ bit_buffer |= *--buf << bits_left; \
+ bits_left += 8; \
+ } \
+ bits_left -= bit_cnt; \
+ while (bit_cnt--) { \
+ (var) = ((var) << 1) | (bit_buffer & 1); \
+ bit_buffer >>= 1; \
+ } \
+} while (0)
+
+#define PP_BYTE_OUT(byte) do { \
+ if (out <= dest) return 0; \
+ *--out = (byte); written++; \
+} while (0)
+
+
+class DecrunchStream : public Common::SeekableReadStream {
+
+ SeekableReadStream *_stream;
+ bool _dispose;
+
+private:
+ int ppDecrunchBuffer(byte *src, byte *dest, uint32 src_len, uint32 dest_len) {
+
+ byte *buf, *out, *dest_end, *off_lens, bits_left = 0, bit_cnt;
+ uint32 bit_buffer = 0, x, todo, offbits, offset, written = 0;
+
+ if (src == NULL || dest == NULL) return 0;
+
+ /* set up input and output pointers */
+ off_lens = src; src = &src[4];
+ buf = &src[src_len];
+
+ out = dest_end = &dest[dest_len];
+
+ /* skip the first few bits */
+ PP_READ_BITS(src[src_len + 3], x);
+
+ /* while there are input bits left */
+ while (written < dest_len) {
+ PP_READ_BITS(1, x);
+ if (x == 0) {
+ /* bit==0: literal, then match. bit==1: just match */
+ todo = 1; do { PP_READ_BITS(2, x); todo += x; } while (x == 3);
+ while (todo--) { PP_READ_BITS(8, x); PP_BYTE_OUT(x); }
+
+ /* should we end decoding on a literal, break out of the main loop */
+ if (written == dest_len) break;
+ }
+
+ /* match: read 2 bits for initial offset bitlength / match length */
+ PP_READ_BITS(2, x);
+ offbits = off_lens[x];
+ todo = x+2;
+ if (x == 3) {
+ PP_READ_BITS(1, x);
+ if (x == 0) offbits = 7;
+ PP_READ_BITS(offbits, offset);
+ do { PP_READ_BITS(3, x); todo += x; } while (x == 7);
+ }
+ else {
+ PP_READ_BITS(offbits, offset);
+ }
+ if (&out[offset] >= dest_end) return 0; /* match_overflow */
+ while (todo--) { x = out[offset]; PP_BYTE_OUT(x); }
+ }
+
+ /* all output bytes written without error */
+ return 1;
+ }
+
+ uint16 getCrunchType(uint32 signature) {
+
+ byte eff;
+
+ switch (signature) {
+ case 0x50503230: /* PP20 */
+ eff = 4;
+ break;
+ case 0x50504C53: /* PPLS */
+ error("PPLS crunched files are not supported");
+ eff = 8;
+ break;
+ case 0x50583230: /* PX20 */
+ error("PX20 crunched files are not supported");
+ eff = 6;
+ break;
+ default:
+ eff = 0;
+
+ }
+
+ return eff;
+ }
+
+public:
+ DecrunchStream(Common::SeekableReadStream &stream) {
+
+ _dispose = false;
+
+ uint32 signature = stream.readUint32BE();
+ if (getCrunchType(signature) == 0) {
+ stream.seek(0, SEEK_SET);
+ _stream = &stream;
+ return;
+ }
+
+ stream.seek(4, SEEK_END);
+ uint32 decrlen = stream.readUint32BE() >> 8;
+ byte *dest = (byte*)malloc(decrlen);
+
+ uint32 crlen = stream.size() - 4;
+ byte *src = (byte*)malloc(crlen);
+ stream.seek(4, SEEK_SET);
+ stream.read(src, crlen);
+
+ ppDecrunchBuffer(src, dest, crlen-8, decrlen);
+
+ free(src);
+ _stream = new Common::MemoryReadStream(dest, decrlen, true);
+ _dispose = true;
+ }
+
+ ~DecrunchStream() {
+ if (_dispose) delete _stream;
+ }
+
+ uint32 size() const {
+ return _stream->size();
+ }
+
+ uint32 pos() const {
+ return _stream->pos();
+ }
+
+ bool eos() const {
+ return _stream->eos();
+ }
+
+ void seek(int32 offs, int whence = SEEK_SET) {
+ _stream->seek(offs, whence);
+ }
+
+ uint32 read(void *dataPtr, uint32 dataSize) {
+ return _stream->read(dataPtr, dataSize);
+ }
+};
+
+
+
AmigaDisk::AmigaDisk(Parallaction *vm) : Disk(vm) {
}
@@ -566,64 +729,119 @@
}
Script* AmigaDisk::loadLocation(const char *name) {
+ debugC(1, kDebugDisk, "AmigaDisk::loadLocation '%s'", name);
return NULL;
}
Script* AmigaDisk::loadScript(const char* name) {
+ debugC(1, kDebugDisk, "AmigaDisk::loadScript '%s'", name);
return NULL;
}
Cnv* AmigaDisk::loadTalk(const char *name) {
+ debugC(1, kDebugDisk, "AmigaDisk::loadTalk '%s'", name);
return NULL;
}
Cnv* AmigaDisk::loadObjects(const char *name) {
+ debugC(1, kDebugDisk, "AmigaDisk::loadObjects '%s'", name);
return NULL;
}
StaticCnv* AmigaDisk::loadPointer() {
+ debugC(1, kDebugDisk, "AmigaDisk::loadPointer");
return NULL;
}
StaticCnv* AmigaDisk::loadHead(const char* name) {
+ debugC(1, kDebugDisk, "AmigaDisk::loadHead '%s'", name);
return NULL;
}
Cnv* AmigaDisk::loadFont(const char* name) {
+ debugC(1, kDebugDisk, "AmigaDisk::loadFont '%s'", name);
return NULL;
}
StaticCnv* AmigaDisk::loadStatic(const char* name) {
+ debugC(1, kDebugDisk, "AmigaDisk::loadStatic '%s'", name);
return NULL;
}
Cnv* AmigaDisk::loadFrames(const char* name) {
+ debugC(1, kDebugDisk, "AmigaDisk::loadFrames '%s'", name);
return NULL;
}
-void AmigaDisk::loadSlide(const char *filename) {
+void AmigaDisk::loadSlide(const char *name) {
+ debugC(1, kDebugDisk, "AmigaDisk::loadSlide '%s'", name);
+
+ char path[PATH_LEN];
+ sprintf(path, "%s.pp", name);
+
+ if (!_archive.openArchivedFile(path))
+ error("can't open archived file %s", path);
+
+ DecrunchStream stream(_archive);
+
+ Graphics::Surface surf;
+ byte *pal;
+
+ // CRNG headers may be safely ignored for slides
+ Graphics::ILBMDecoder decoder(stream);
+ decoder.decode(surf, pal);
+
+ for (uint32 i = 0; i < 96; i++)
+ pal[i] >>= 2;
+
+
+ _vm->_gfx->setPalette(pal);
+ free(pal);
+
+ _vm->_gfx->setBackground(static_cast<byte*>(surf.pixels));
+
+ surf.free();
+
return;
}
void AmigaDisk::loadScenery(const char* background, const char* mask) {
+ debugC(1, kDebugDisk, "AmigaDisk::loadScenery '%s', '%s'", background, mask);
return;
}
Table* AmigaDisk::loadTable(const char* name) {
+ printf("AmigaDisk::loadTable\n");
char path[PATH_LEN];
sprintf(path, "%s.table", name);
- _archive.openArchivedFile(path);
+ Common::SeekableReadStream *stream;
+ if (!scumm_stricmp(name, "global")) {
+ Common::File *s = new Common::File;
+ if (!s->open(path))
+ error("can't open %s", path);
+
+ stream = s;
+ } else {
+ if (!_archive.openArchivedFile(path))
+ error("can't open archived file %s", path);
+
+// DecrunchStream *s = new DecrunchStream(_archive);
+ stream = &_archive;
+ }
+
Table *t = new Table(100);
- fillBuffers(_archive);
+ fillBuffers(*stream);
while (scumm_stricmp(_tokens[0], "ENDTABLE")) {
t->addData(_tokens[0]);
- fillBuffers(_archive);
+ fillBuffers(*stream);
}
+ delete stream;
+
return t;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list