aboutsummaryrefslogtreecommitdiff
path: root/engines/chewy
diff options
context:
space:
mode:
authorFilippos Karapetis2016-09-26 13:19:37 +0300
committerFilippos Karapetis2016-10-03 00:34:05 +0300
commit94a942755e745bc3553b3d8cc83e533688d867fa (patch)
tree264175e1708ccea286f18953b17e1dd5c81aea01 /engines/chewy
parent1de9019665d8e1d2791684ae84d4ca45f652bb38 (diff)
downloadscummvm-rg350-94a942755e745bc3553b3d8cc83e533688d867fa.tar.gz
scummvm-rg350-94a942755e745bc3553b3d8cc83e533688d867fa.tar.bz2
scummvm-rg350-94a942755e745bc3553b3d8cc83e533688d867fa.zip
CHEWY: Initial support for game sprites
Diffstat (limited to 'engines/chewy')
-rw-r--r--engines/chewy/chewy.cpp13
-rw-r--r--engines/chewy/graphics.cpp20
-rw-r--r--engines/chewy/graphics.h3
-rw-r--r--engines/chewy/resource.cpp105
-rw-r--r--engines/chewy/resource.h38
5 files changed, 158 insertions, 21 deletions
diff --git a/engines/chewy/chewy.cpp b/engines/chewy/chewy.cpp
index e5dd7ec265..94cbee4559 100644
--- a/engines/chewy/chewy.cpp
+++ b/engines/chewy/chewy.cpp
@@ -79,22 +79,35 @@ Common::Error ChewyEngine::run() {
//_graphics->playVideo(0);
_graphics->drawImage("episode1.tgp", 0);
+ _graphics->showCursor();
+ _graphics->setCursor(0);
//_sound->playSpeech(1);
//_sound->playSound(1);
//_sound->playMusic(2);
// Run a dummy loop
Common::Event event;
+ uint curCursor = 0;
+ const uint maxCursors = 41;
while (!shouldQuit()) {
while (g_system->getEventManager()->pollEvent(event)) {
if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
g_engine->quitGame();
+ if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_SPACE) || event.type == Common::EVENT_RBUTTONUP) {
+ curCursor++;
+ if (curCursor == maxCursors)
+ curCursor = 0;
+ _graphics->setCursor(curCursor);
+ }
+
if (event.type == Common::EVENT_KEYDOWN && event.kbd.flags & Common::KBD_CTRL && event.kbd.keycode == Common::KEYCODE_d)
_console->attach();
}
_console->onFrame();
+
+ g_system->updateScreen();
g_system->delayMillis(10);
}
diff --git a/engines/chewy/graphics.cpp b/engines/chewy/graphics.cpp
index fda46a3e7a..84e6002dc9 100644
--- a/engines/chewy/graphics.cpp
+++ b/engines/chewy/graphics.cpp
@@ -22,6 +22,7 @@
#include "common/system.h"
#include "common/events.h"
+#include "graphics/cursorman.h"
#include "graphics/palette.h"
#include "chewy/graphics.h"
@@ -85,4 +86,23 @@ void Graphics::playVideo(uint num) {
cfoDecoder->close();
}
+void Graphics::setCursor(uint num) {
+ SpriteResource *res = new SpriteResource("cursor.taf");
+ TAFChunk *cursor = res->getSprite(num);
+
+ CursorMan.replaceCursor(cursor->data, cursor->width, cursor->height, 0, 0, 0);
+
+ delete[] cursor->data;
+ delete cursor;
+ delete res;
+}
+
+void Graphics::showCursor() {
+ CursorMan.showMouse(true);
+}
+
+void Graphics::hideCursor() {
+ CursorMan.showMouse(false);
+}
+
} // End of namespace Chewy
diff --git a/engines/chewy/graphics.h b/engines/chewy/graphics.h
index c7d303d2a2..64c4255324 100644
--- a/engines/chewy/graphics.h
+++ b/engines/chewy/graphics.h
@@ -34,6 +34,9 @@ public:
void drawImage(Common::String filename, int imageNum);
void playVideo(uint num);
+ void setCursor(uint num);
+ void showCursor();
+ void hideCursor();
private:
};
diff --git a/engines/chewy/resource.cpp b/engines/chewy/resource.cpp
index 23ac5c2ef2..13bd9d2e97 100644
--- a/engines/chewy/resource.cpp
+++ b/engines/chewy/resource.cpp
@@ -50,18 +50,23 @@ Resource::Resource(Common::String filename) {
const uint32 headerGeneric = MKTAG('N', 'G', 'S', '\0');
const uint32 headerTxtDec = MKTAG('T', 'C', 'F', '\0');
const uint32 headerTxtEnc = MKTAG('T', 'C', 'F', '\1');
+ const uint32 headerSprite = MKTAG('T', 'A', 'F', '\0');
_stream.open(filename);
uint32 header = _stream.readUint32BE();
- bool isText = header == headerTxtDec || header == headerTxtEnc;
+ bool isText = (header == headerTxtDec || header == headerTxtEnc);
+ bool isSprite = (header == headerSprite);
- if (header != headerGeneric && !isText)
+ if (header != headerGeneric && !isSprite && !isText)
error("Invalid resource - %s", filename.c_str());
if (isText) {
_resType = kResourceTCF;
_encrypted = (header == headerTxtEnc);
+ } else if (isSprite) {
+ initSprite(filename);
+ return;
} else {
_resType = (ResourceType)_stream.readUint16LE();
_encrypted = false;
@@ -112,6 +117,83 @@ byte *Resource::getChunkData(uint num) {
return data;
}
+void Resource::initSprite(Common::String filename) {
+ uint16 screenMode;;
+ uint32 nextSpriteOffset;
+
+ // TAF (sprite) resources are much different than the rest, so we have a
+ // separate initializer for them here
+
+ _resType = kResourceTAF;
+ _encrypted = false;
+ screenMode = _stream.readUint16LE();
+ _chunkCount = _stream.readUint16LE();
+ _stream.skip(4); // total size of all sprites
+ _stream.skip(3 * 256); // palette
+ nextSpriteOffset = _stream.readUint32LE();
+ _stream.skip(2 + 1); // correction table, padding
+ if ((int32)nextSpriteOffset != _stream.pos())
+ error("Invalid sprite resource - %s", filename.c_str());
+
+ for (uint i = 0; i < _chunkCount; i++) {
+ Chunk cur;
+
+ cur.pos = _stream.pos();
+ cur.type = kResourceTAF;
+
+ _stream.skip(2 + 2 + 2); // compression flag, width, height
+ uint32 nextSpriteOffset = _stream.readUint32LE();
+ uint32 spriteImageOffset = _stream.readUint32LE();
+ _stream.skip(1); // padding
+
+ if ((int32)spriteImageOffset != _stream.pos())
+ error("Invalid sprite resource - %s", filename.c_str());
+
+ cur.size = nextSpriteOffset - cur.pos - 15; // 15 = sizeof(TAFChunk)
+
+ _stream.skip(cur.size);
+ _chunkList.push_back(cur);
+ }
+}
+
+void Resource::unpackRLE(byte *buffer, uint32 compressedSize, uint32 uncompressedSize) {
+ // Compressed images are packed using a very simple RLE compression
+ byte count;
+ byte value;
+ uint32 outPos = 0;
+
+ for (uint i = 0; i < (compressedSize) / 2 && outPos < uncompressedSize; i++) {
+ count = _stream.readByte();
+ value = _stream.readByte();
+ for (byte j = 0; j < count; j++) {
+ buffer[outPos++] = value;
+ }
+ }
+}
+
+TAFChunk *SpriteResource::getSprite(uint num) {
+ assert(num < _chunkList.size());
+
+ Chunk *chunk = &_chunkList[num];
+ TAFChunk *taf = new TAFChunk();
+
+ _stream.seek(chunk->pos, SEEK_SET);
+
+ taf->compressionFlag = _stream.readUint16LE();
+ taf->width = _stream.readUint16LE();
+ taf->height = _stream.readUint16LE();
+ _stream.skip(4 + 4 + 1); // nextSpriteOffset, spriteImageOffset, padding
+
+ taf->data = new byte[taf->width * taf->height];
+
+ if (!taf->compressionFlag)
+ _stream.read(taf->data, chunk->size);
+ else
+ unpackRLE(taf->data, chunk->size, taf->width * taf->height);
+
+ return taf;
+}
+
TBFChunk *BackgroundResource::getImage(uint num) {
assert(num < _chunkList.size());
@@ -133,23 +215,10 @@ TBFChunk *BackgroundResource::getImage(uint num) {
tbf->data = new byte[tbf->size];
- if (!tbf->compressionFlag) {
+ if (!tbf->compressionFlag)
_stream.read(tbf->data, chunk->size);
- }
- else {
- // Compressed images are packed using a very simple RLE compression
- byte count;
- byte value;
- uint32 outPos = 0;
-
- for (uint i = 0; i < (chunk->size) / 2 && outPos < tbf->size; i++) {
- count = _stream.readByte();
- value = _stream.readByte();
- for (byte j = 0; j < count; j++) {
- tbf->data[outPos++] = value;
- }
- }
- }
+ else
+ unpackRLE(tbf->data, chunk->size, tbf->size);
return tbf;
}
diff --git a/engines/chewy/resource.h b/engines/chewy/resource.h
index d9665ceb4a..b869840975 100644
--- a/engines/chewy/resource.h
+++ b/engines/chewy/resource.h
@@ -65,9 +65,6 @@ enum ResourceType {
kResourceTCF = 26 // error messages, used in err/err_e.tcf (English) and err/err_d.tcf (German)
};
-// 4 + 2 + 2 + 4 + 2 + 2 + 768 = 784 bytes
-#define TBF_CHUNK_HEADER_SIZE 784
-
// Generic chunk header
struct Chunk {
uint32 size;
@@ -89,6 +86,30 @@ struct TBFChunk {
byte *data;
};
+// TAF (sprite) chunk header
+/*struct TAFHeader {
+ // TAF chunk header
+ // ID (TAF, followed by a zero)
+ uint16 screenMode;
+ uint16 spriteCount;
+ uint32 size; // total size (width * height) of all sprites
+ byte palette[3 * 256];
+ uint32 nextSpriteOffset;
+ uint16 correctionTable;
+ // 1 byte padding
+};*/
+
+// TAF (sprite) image data chunk header - 15 bytes
+struct TAFChunk {
+ uint16 compressionFlag;
+ uint16 width;
+ uint16 height;
+ // 4 bytes next sprite offset
+ // 4 bytes sprite image offset
+ // 1 byte padding
+ byte *data;
+};
+
// Sound chunk header
struct SoundChunk {
uint32 size;
@@ -125,6 +146,9 @@ public:
virtual byte *getChunkData(uint num);
protected:
+ void initSprite(Common::String filename);
+ void unpackRLE(byte *buffer, uint32 compressedSize, uint32 uncompressedSize);
+
Common::File _stream;
uint16 _chunkCount;
ResourceType _resType;
@@ -133,6 +157,14 @@ protected:
ChunkList _chunkList;
};
+class SpriteResource : public Resource {
+public:
+ SpriteResource(Common::String filename) : Resource(filename) {}
+ ~SpriteResource() {}
+
+ TAFChunk *getSprite(uint num);
+};
+
class BackgroundResource : public Resource {
public:
BackgroundResource(Common::String filename) : Resource(filename) {}