aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorathrxx2019-03-25 21:46:18 +0100
committerathrxx2019-04-13 18:55:00 +0200
commit02000cfe371784fe5eb46e063a0391fa1ec2001f (patch)
tree7eb1b3b63285fea3c823c06a6ba705daaf79d5f2 /engines
parentc94b6a438952c9d20b9a07d0a8712e9e2be25c7c (diff)
downloadscummvm-rg350-02000cfe371784fe5eb46e063a0391fa1ec2001f.tar.gz
scummvm-rg350-02000cfe371784fe5eb46e063a0391fa1ec2001f.tar.bz2
scummvm-rg350-02000cfe371784fe5eb46e063a0391fa1ec2001f.zip
KYRA: (EOB2/Amiga) - add special gfx decoder for localized version
Diffstat (limited to 'engines')
-rw-r--r--engines/kyra/engine/eobcommon.cpp36
-rw-r--r--engines/kyra/engine/scene_eob.cpp7
-rw-r--r--engines/kyra/graphics/screen_eob.cpp144
-rw-r--r--engines/kyra/graphics/screen_eob.h3
-rw-r--r--engines/kyra/sequence/sequences_darkmoon.cpp6
5 files changed, 167 insertions, 29 deletions
diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp
index 792cf10008..1c75c78d70 100644
--- a/engines/kyra/engine/eobcommon.cpp
+++ b/engines/kyra/engine/eobcommon.cpp
@@ -1346,10 +1346,15 @@ void EoBCoreEngine::npcSequence(int npcIndex) {
drawNpcScene(npcIndex);
Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
- if (s)
+ if (s) {
_screen->loadFileDataToPage(s, 5, 32000);
- else
- _screen->loadBitmap("TEXT.CPS", 5, 5, 0, true);
+ } else {
+ s = _res->createReadStream("TEXT.CPS");
+ if (s->readSint32BE() + 12 == s->size())
+ _screen->loadSpecialAmigaCPS("TEXT.CPS", 5, false);
+ else
+ _screen->loadBitmap("TEXT.CPS", 5, 5, 0, true);
+ }
delete s;
gui_drawBox(0, 121, 320, 79, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
@@ -1597,12 +1602,18 @@ void EoBCoreEngine::initDialogueSequence() {
snd_stopSound();
Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
- if (s)
+ if (s) {
_screen->loadFileDataToPage(s, 5, 32000);
- else
- _screen->loadBitmap("TEXT.CPS", 5, 5, 0, true);
- _txt->setupField(9, 0);
+ } else {
+ s = _res->createReadStream("TEXT.CPS");
+ if (s->readSint32BE() + 12 == s->size())
+ _screen->loadSpecialAmigaCPS("TEXT.CPS", 5, false);
+ else
+ _screen->loadBitmap("TEXT.CPS", 5, 5, 0, true);
+ }
delete s;
+
+ _txt->setupField(9, 0);
}
void EoBCoreEngine::restoreAfterDialogueSequence() {
@@ -1804,10 +1815,15 @@ void EoBCoreEngine::displayParchment(int id) {
if (id >= 0) {
// display text
Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
- if (s)
+ if (s) {
_screen->loadFileDataToPage(s, 5, 32000);
- else
- _screen->loadBitmap("TEXT.CPS", 5, 5, 0, true);
+ } else {
+ s = _res->createReadStream("TEXT.CPS");
+ if (s->readSint32BE() + 12 == s->size())
+ _screen->loadSpecialAmigaCPS("TEXT.CPS", 5, false);
+ else
+ _screen->loadBitmap("TEXT.CPS", 5, 5, 0, true);
+ }
delete s;
_screen->set16bitShadingLevel(4);
gui_drawBox(0, 0, 176, 175, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
diff --git a/engines/kyra/engine/scene_eob.cpp b/engines/kyra/engine/scene_eob.cpp
index f010069f63..9a2f4e2f93 100644
--- a/engines/kyra/engine/scene_eob.cpp
+++ b/engines/kyra/engine/scene_eob.cpp
@@ -132,7 +132,12 @@ void EoBCoreEngine::readLevelFileData(int level) {
if (s) {
s->seek(0);
- _screen->loadFileDataToPage(s, 5, 15000);
+ if (s->readSint32BE() + 12 == s->size()) {
+ _screen->loadSpecialAmigaCPS(file.c_str(), 5, false);
+ } else {
+ s->seek(0);
+ _screen->loadFileDataToPage(s, 5, 15000);
+ }
delete s;
}
}
diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp
index b3c0393e8a..2e2674d9dd 100644
--- a/engines/kyra/graphics/screen_eob.cpp
+++ b/engines/kyra/graphics/screen_eob.cpp
@@ -29,9 +29,11 @@
#include "kyra/engine/eobcommon.h"
#include "kyra/resource/resource.h"
+#include "kyra/engine/util.h"
#include "common/system.h"
#include "common/translation.h"
+#include "common/memstream.h"
#include "graphics/cursorman.h"
#include "graphics/palette.h"
@@ -267,9 +269,10 @@ void Screen_EoB::loadEoBBitmap(const char *file, const uint8 *cgaMapping, int te
if (s->size() == 0) {
loadAlternative = true;
- // This check is due to EOB II Amiga German.That version simply checks
- // for certain file names which aren't actual CPS files. The files contain
- // raw data. I check the header size info to identify these.
+ // This check is due to EOB II Amiga German. That version simply checks
+ // for certain file names which aren't actual CPS files. These files use
+ // a diffenrent format and compression type. I check the header size
+ // info to identify these.
} else if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
// Tolerance for diffenrences up to 2 bytes is needed in some cases
if ((((s->readUint16LE()) + 5) & ~3) != (((s->size()) + 3) & ~3))
@@ -291,18 +294,7 @@ void Screen_EoB::loadEoBBitmap(const char *file, const uint8 *cgaMapping, int te
loadBitmap(tmp.c_str(), tempPage, destPage, 0);
} else if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
- s = _vm->resource()->createReadStream(tmp);
- if (!s)
- error("Screen_EoB::loadEoBBitmap(): Failed to load file '%s'", file);
-
- // See comment above. In addition to checking for certain file names which
- // aren't real CPS files the EOB II Amiga German makes a specific check for CHARGEN.CPS
- // which contains palette data at the beginning. For now I haven't come up
- // with a way of avoiding this hack.
- if (tmp.equals("CHARGEN.CPS"))
- _palettes[0]->loadAmigaPalette(*s, 0, 32);
-
- loadFileDataToPage(s, destPage, 40000);
+ loadSpecialAmigaCPS(tmp.c_str(), destPage, true);
} else {
tmp.setChar('X', 0);
@@ -1529,6 +1521,128 @@ void Screen_EoB::shadeRect(int x1, int y1, int x2, int y2, int shadingLevel) {
_16bitShadingLevel = l;
}
+static uint32 _decodeFrameAmiga_x = 0;
+
+bool decodeFrameAmiga_readNextBit(const uint8 *&data, uint32 &code, uint32 &chk) {
+ _decodeFrameAmiga_x = code & 1;
+ code >>= 1;
+ if (code)
+ return _decodeFrameAmiga_x;
+
+ data -= 4;
+ code = READ_BE_UINT32(data);
+ chk ^= code;
+ _decodeFrameAmiga_x = code & 1;
+ code = (code >> 1) | (1 << 31);
+
+ return _decodeFrameAmiga_x;
+}
+
+uint32 decodeFrameAmiga_readBits(const uint8 *&data, uint32 &code, uint32 &chk, int count) {
+ uint32 res = 0;
+ while (count--) {
+ decodeFrameAmiga_readNextBit(data, code, chk);
+ uint32 bt1 = _decodeFrameAmiga_x;
+ _decodeFrameAmiga_x = res >> 31;
+ res = (res << 1) | bt1;
+ }
+ return res;
+}
+
+void Screen_EoB::loadSpecialAmigaCPS(const char *fileName, int destPage, bool isGraphics) {
+ uint32 fileSize = 0;
+ const uint8 *file = _vm->resource()->fileData(fileName, &fileSize);
+
+ if (!file)
+ error("Screen_EoB::loadSpecialAmigaCPS(): Failed to load file '%s'", file);
+
+ uint32 inSize = READ_BE_UINT32(file);
+ const uint8 *pos = file;
+
+ // Check whether the file starts with the actual compression header.
+ // If this is not the case, there should a palette before the header.
+ // Unlike normal CPS files these files never have more than one palette.
+ if (((inSize + 15) & ~3) != ((fileSize + 3) & ~3)) {
+ Common::MemoryReadStream in(pos, 64);
+ _palettes[0]->loadAmigaPalette(in, 0, 32);
+ pos += 64;
+ }
+
+ inSize = READ_BE_UINT32(pos);
+ uint32 outSize = READ_BE_UINT32(pos + 4);
+ uint32 chk = READ_BE_UINT32(pos + 8);
+
+ pos = pos + 8 + inSize;
+ uint8 *dstStart = _pagePtrs[destPage];
+ uint8 *dst = dstStart + outSize;
+
+ uint32 val = READ_BE_UINT32(pos);
+ _decodeFrameAmiga_x = 0;
+ chk ^= val;
+
+ while (dst > dstStart) {
+ int para = -1;
+ int para2 = 0;
+
+ if (decodeFrameAmiga_readNextBit(pos, val, chk)) {
+ uint32 code = decodeFrameAmiga_readBits(pos, val, chk, 2);
+
+ if (code == 3) {
+ para = para2 = 8;
+ } else {
+ int cnt = 0;
+ if (code < 2) {
+ cnt = 3 + code;
+ para2 = 9 + code;
+ } else {
+ cnt = decodeFrameAmiga_readBits(pos, val, chk, 8) + 1;
+ para2 = 12;
+ }
+
+ code = decodeFrameAmiga_readBits(pos, val, chk, para2);
+ while (cnt--) {
+ dst--;
+ *dst = dst[code & 0xFFFF];
+ }
+ }
+ } else {
+ if (decodeFrameAmiga_readNextBit(pos, val, chk)) {
+ uint32 code = decodeFrameAmiga_readBits(pos, val, chk, 8);
+ dst--;
+ *dst = dst[code & 0xFFFF];
+ dst--;
+ *dst = dst[code & 0xFFFF];
+
+ } else {
+ para = 3;
+ }
+ }
+
+ if (para > 0) {
+ uint32 code = decodeFrameAmiga_readBits(pos, val, chk, para);
+ uint32 cnt = (code & 0xFFFF) + para2 + 1;
+
+ while (cnt--) {
+ for (int i = 0; i < 8; ++i) {
+ decodeFrameAmiga_readNextBit(pos, val, chk);
+ uint32 bt1 = _decodeFrameAmiga_x;
+ _decodeFrameAmiga_x = code >> 31;
+ code = (code << 1) | bt1;
+ }
+ *(--dst) = code & 0xFF;
+ }
+ }
+ }
+
+ delete[] file;
+
+ if (chk)
+ error("Screen_EoB::loadSpecialAmigaCPS(): Checksum error");
+
+ if (isGraphics)
+ convertAmigaGfx(_pagePtrs[destPage], 320, 200);
+}
+
void Screen_EoB::updateDirtyRects() {
if (!_useHiResEGADithering) {
Screen::updateDirtyRects();
diff --git a/engines/kyra/graphics/screen_eob.h b/engines/kyra/graphics/screen_eob.h
index 42a03ca225..66efc25cc0 100644
--- a/engines/kyra/graphics/screen_eob.h
+++ b/engines/kyra/graphics/screen_eob.h
@@ -90,6 +90,9 @@ public:
void convertToHiColor(int page);
void shadeRect(int x1, int y1, int x2, int y2, int shadingLevel);
+ // Amiga specific
+ void loadSpecialAmigaCPS(const char *fileName, int destPage, bool isGraphics);
+
private:
void updateDirtyRects();
void ditherRect(const uint8 *src, uint8 *dst, int dstPitch, int srcW, int srcH, int colorKey = -1);
diff --git a/engines/kyra/sequence/sequences_darkmoon.cpp b/engines/kyra/sequence/sequences_darkmoon.cpp
index 86e837ec51..b92eb74fde 100644
--- a/engines/kyra/sequence/sequences_darkmoon.cpp
+++ b/engines/kyra/sequence/sequences_darkmoon.cpp
@@ -131,7 +131,7 @@ int DarkMoonEngine::mainMenu() {
while (menuChoice >= 0 && !shouldQuit()) {
switch (menuChoice) {
case 0: {
- if (_flags.platform == Common::kPlatformFMTowns) {
+ if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformAmiga) {
_screen->loadPalette("MENU.PAL", _screen->getPalette(0));
_screen->setScreenPalette(_screen->getPalette(0));
_screen->loadEoBBitmap("MENU", 0, 3, 3, 2);
@@ -1341,8 +1341,8 @@ void DarkmoonSequenceHelper::loadScene(int index, int pageNum, bool ignorePalett
_screen->loadBitmap(_config->cpsFiles[index], pageNum | 1, pageNum | 1, ignorePalette ? 0 : _palettes[0]);
} else if (s && _vm->gameFlags().platform == Common::kPlatformAmiga) {
- _screen->loadFileDataToPage(s, 5, 64000);
- _screen->decodeLocalizedAmigaPage(5, pageNum, true);
+ delete s;
+ _screen->loadSpecialAmigaCPS(_config->cpsFiles[index], pageNum | 1, true);
} else {
if (!s) {