aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
authorJohannes Schickel2007-03-12 20:43:56 +0000
committerJohannes Schickel2007-03-12 20:43:56 +0000
commit689ea77c0d8be927d2d5c9874239e444267a4999 (patch)
tree7fda88544f04a37df366c4c77fde21d0062a3fca /engines/kyra
parent39cbdc7a31600c091da80d5f072637b006985984 (diff)
downloadscummvm-rg350-689ea77c0d8be927d2d5c9874239e444267a4999.tar.gz
scummvm-rg350-689ea77c0d8be927d2d5c9874239e444267a4999.tar.bz2
scummvm-rg350-689ea77c0d8be927d2d5c9874239e444267a4999.zip
WIP code for Amiga version:
- Font displaying is not yet supported. - Intro should be glitch free - all other things are *untested* svn-id: r26113
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/kyra.cpp3
-rw-r--r--engines/kyra/plugin.cpp3
-rw-r--r--engines/kyra/scene.cpp10
-rw-r--r--engines/kyra/screen.cpp134
-rw-r--r--engines/kyra/screen.h4
-rw-r--r--engines/kyra/seqplayer.cpp66
-rw-r--r--engines/kyra/sequences_v1.cpp99
-rw-r--r--engines/kyra/sprites.cpp5
-rw-r--r--engines/kyra/staticres.cpp12
-rw-r--r--engines/kyra/wsamovie.cpp140
-rw-r--r--engines/kyra/wsamovie.h13
11 files changed, 418 insertions, 71 deletions
diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp
index eeeabbab84..fe85a439a8 100644
--- a/engines/kyra/kyra.cpp
+++ b/engines/kyra/kyra.cpp
@@ -794,7 +794,8 @@ void KyraEngine::freeShapes123() {
#pragma mark -
Movie *KyraEngine::createWSAMovie() {
- // for kyra2 here could be added then WSAMovieV2
+ if (_flags.platform == Common::kPlatformAmiga)
+ return new WSAMovieAmiga(this);
return new WSAMovieV1(this);
}
diff --git a/engines/kyra/plugin.cpp b/engines/kyra/plugin.cpp
index f7a14ceb57..0cd959a51a 100644
--- a/engines/kyra/plugin.cpp
+++ b/engines/kyra/plugin.cpp
@@ -39,6 +39,7 @@ namespace {
#define FLAGS(x, y, z, a, id) { Common::UNK_LANG, Common::kPlatformUnknown, x, y, z, a, id }
#define KYRA1_FLOPPY_FLAGS FLAGS(false, false, false, false, Kyra::GI_KYRA1)
+#define KYRA1_AMIGA_FLAGS FLAGS(false, false, false, false, Kyra::GI_KYRA1)
#define KYRA1_TOWNS_FLAGS FLAGS(false, true, false, false, Kyra::GI_KYRA1)
#define KYRA1_TOWNS_SJIS_FLAGS FLAGS(false, true, false, true, Kyra::GI_KYRA1)
#define KYRA1_CD_FLAGS FLAGS(false, true, true, false, Kyra::GI_KYRA1)
@@ -59,7 +60,7 @@ const KYRAGameDescription adGameDescs[] = {
{ { "kyra1", 0, AD_ENTRY1("GEMCUT.EMC", "747861d2a9c643c59fdab570df5b9093"), Common::ES_ESP, Common::kPlatformPC, Common::ADGF_NO_FLAGS }, KYRA1_FLOPPY_FLAGS }, // floppy 1.8 from clemmy
{ { "kyra1", 0, AD_ENTRY1("GEMCUT.EMC", "ef08c8c237ee1473fd52578303fc36df"), Common::IT_ITA, Common::kPlatformPC, Common::ADGF_NO_FLAGS }, KYRA1_FLOPPY_FLAGS }, // from gourry
- //{ { "kyra1", 0, AD_ENTRY1("GEMCUT.PAK", "2bd1da653eaefd691e050e4a9eb68a64"), Common::EN_ANY, Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, KYRA1_FLOPPY_FLAGS },
+ { { "kyra1", 0, AD_ENTRY1("GEMCUT.PAK", "2bd1da653eaefd691e050e4a9eb68a64"), Common::EN_ANY, Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, KYRA1_AMIGA_FLAGS },
{ { "kyra1", 0, AD_ENTRY1("TWMUSIC.PAK", "e53bca3a3e3fb49107d59463ec387a59"), Common::EN_ANY, Common::kPlatformFMTowns, Common::ADGF_NO_FLAGS }, KYRA1_TOWNS_FLAGS },
{ { "kyra1", 0, AD_ENTRY1("TWMUSIC.PAK", "e53bca3a3e3fb49107d59463ec387a59"), Common::JA_JPN, Common::kPlatformFMTowns, Common::ADGF_NO_FLAGS }, KYRA1_TOWNS_SJIS_FLAGS },
diff --git a/engines/kyra/scene.cpp b/engines/kyra/scene.cpp
index 3ab9b6b09b..f3212d517a 100644
--- a/engines/kyra/scene.cpp
+++ b/engines/kyra/scene.cpp
@@ -448,7 +448,8 @@ void KyraEngine::startSceneScript(int brandonAlive) {
char fileNameBuffer[32];
strcpy(fileNameBuffer, _roomFilenameTable[tableId]);
strcat(fileNameBuffer, ".CPS");
- _screen->loadBitmap(fileNameBuffer, 3, 3, 0);
+ // FIXME: check this hack for amiga version
+ _screen->loadBitmap(fileNameBuffer, 3, 3, (_flags.platform == Common::kPlatformAmiga ? _screen->getPalette(1) : 0));
_sprites->loadSceneShapes();
_exitListPtr = 0;
@@ -846,6 +847,13 @@ void KyraEngine::initSceneScreen(int brandonAlive) {
memset(_screen->getPalette(0), 0, 768);
}
}
+
+ // FIXME: hack to get the room palette working
+ if (_flags.platform == Common::kPlatformAmiga) {
+ memcpy(_screen->getPalette(0), _screen->getPalette(1), 32*3);
+ _screen->setScreenPalette(_screen->getPalette(0));
+ }
+
// really call this here?
_screen->updateScreen();
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 1ca67fc1d1..ca736aac7b 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -793,6 +793,10 @@ bool Screen::loadFont(FontId fontId, const char *filename) {
debugC(9, kDebugLevelScreen, "Screen::loadFont(%d, '%s')", fontId, filename);
Font *fnt = &_fonts[fontId];
+ // FIXME: add font support for amiga version
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ return true;
+
if (!fnt)
error("fontId %d is invalid", fontId);
@@ -827,14 +831,23 @@ Screen::FontId Screen::setFont(FontId fontId) {
}
int Screen::getFontHeight() const {
+ // FIXME: add font support for amiga version
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ return 0;
return *(_fonts[_currentFont].fontData + _fonts[_currentFont].charSizeOffset + 4);
}
int Screen::getFontWidth() const {
+ // FIXME: add font support for amiga version
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ return 0;
return *(_fonts[_currentFont].fontData + _fonts[_currentFont].charSizeOffset + 5);
}
int Screen::getCharWidth(uint16 c) const {
+ // FIXME: add font support for amiga version
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ return 0;
debugC(9, kDebugLevelScreen, "Screen::getCharWidth('%c'|%d)", c & 0xFF, c);
if (c & 0xFF00)
return SJIS_CHARSIZE >> 1;
@@ -842,6 +855,9 @@ int Screen::getCharWidth(uint16 c) const {
}
int Screen::getTextWidth(const char *str) const {
+ // FIXME: add font support for amiga version
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ return 0;
debugC(9, kDebugLevelScreen, "Screen::getTextWidth('%s')", str);
int curLineLen = 0;
@@ -872,6 +888,9 @@ int Screen::getTextWidth(const char *str) const {
}
void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2) {
+ // FIXME: add font support for amiga version
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ return;
debugC(9, kDebugLevelScreen, "Screen::printText('%s', %d, %d, 0x%X, 0x%X)", str, x, y, color1, color2);
uint8 cmap[2];
cmap[0] = color2;
@@ -1598,15 +1617,26 @@ uint Screen::decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize) {
return dst - dstOrig;
}
-void Screen::decodeFrameDelta(uint8 *dst, const uint8 *src) {
- debugC(9, kDebugLevelScreen, "Screen::decodeFrameDelta(%p, %p)", (const void *)dst, (const void *)src);
+void Screen::decodeFrameDelta(uint8 *dst, const uint8 *src, bool noXor) {
+ debugC(9, kDebugLevelScreen, "Screen::decodeFrameDelta(%p, %p, %d)", (const void *)dst, (const void *)src, noXor);
+ if (noXor)
+ wrapped_decodeFrameDelta<true>(dst, src);
+ else
+ wrapped_decodeFrameDelta<false>(dst, src);
+}
+
+template <bool noXor>
+void Screen::wrapped_decodeFrameDelta(uint8 *dst, const uint8 *src) {
while (1) {
uint8 code = *src++;
if (code == 0) {
uint8 len = *src++;
code = *src++;
while (len--) {
- *dst++ ^= code;
+ if (noXor)
+ *dst++ = code;
+ else
+ *dst++ ^= code;
}
} else if (code & 0x80) {
code -= 0x80;
@@ -1622,11 +1652,17 @@ void Screen::decodeFrameDelta(uint8 *dst, const uint8 *src) {
uint16 len = subcode - 0x4000;
code = *src++;
while (len--) {
- *dst++ ^= code;
+ if (noXor)
+ *dst++ = code;
+ else
+ *dst++ ^= code;
}
} else {
while (subcode--) {
- *dst++ ^= *src++;
+ if (noXor)
+ *dst++ = *src++;
+ else
+ *dst++ ^= *src++;
}
}
} else {
@@ -1635,7 +1671,10 @@ void Screen::decodeFrameDelta(uint8 *dst, const uint8 *src) {
}
} else {
while (code--) {
- *dst++ ^= *src++;
+ if (noXor)
+ *dst++ = *src++;
+ else
+ *dst++ ^= *src++;
}
}
}
@@ -1651,9 +1690,54 @@ void Screen::decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch, bool
}
}
+void Screen::convertAmigaGfx(uint8 *data, int w, int h, bool offscreen) {
+ static uint8 tmp[320*200];
+
+ if (offscreen) {
+ uint8 *curLine = tmp;
+ const uint8 *src = data;
+ int hC = h;
+ while (hC--) {
+ uint8 *dst1 = curLine;
+ uint8 *dst2 = dst1 + 8000;
+ uint8 *dst3 = dst2 + 8000;
+ uint8 *dst4 = dst3 + 8000;
+ uint8 *dst5 = dst4 + 8000;
+
+ int width = w >> 3;
+ while (width--) {
+ *dst1++ = *src++;
+ *dst2++ = *src++;
+ *dst3++ = *src++;
+ *dst4++ = *src++;
+ *dst5++ = *src++;
+ }
+
+ curLine += 40;
+ }
+ } else {
+ memcpy(tmp, data, w*h);
+ }
+
+ int planeOffset = 8000;
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ int bytePos = x/8+y*40;
+ int bitPos = 7-x&7;
+
+ byte colorIndex = 0;
+ colorIndex |= (((tmp[bytePos + planeOffset * 0] & (1 << bitPos)) >> bitPos) & 0x1) << 0;
+ colorIndex |= (((tmp[bytePos + planeOffset * 1] & (1 << bitPos)) >> bitPos) & 0x1) << 1;
+ colorIndex |= (((tmp[bytePos + planeOffset * 2] & (1 << bitPos)) >> bitPos) & 0x1) << 2;
+ colorIndex |= (((tmp[bytePos + planeOffset * 3] & (1 << bitPos)) >> bitPos) & 0x1) << 3;
+ colorIndex |= (((tmp[bytePos + planeOffset * 4] & (1 << bitPos)) >> bitPos) & 0x1) << 4;
+ *data++ = colorIndex;
+ }
+ }
+}
+
template<bool noXor>
void Screen::wrapped_decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch) {
- debugC(9, kDebugLevelScreen, "Screen::wrapped_decodeFrameDeltaPage(%p, %p, %d)", (const void *)dst, (const void *)src, pitch);
int count = 0;
uint8 *dstNext = dst;
while (1) {
@@ -2473,6 +2557,10 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *
break;
}
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ Screen::convertAmigaGfx(dstData, 320, 200, false);
+ }
+
delete [] srcData;
}
@@ -2483,14 +2571,42 @@ void Screen::loadPalette(const char *filename, uint8 *palData) {
if (palData && fileSize) {
debugC(9, kDebugLevelScreen,"Loading a palette of size %i from '%s'", fileSize, filename);
- memcpy(palData, srcData, fileSize);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ assert(fileSize % 2 == 0);
+ assert(fileSize / 2 <= 256);
+ fileSize >>= 1;
+ const uint16 *src = (const uint16 *)srcData;
+ for (uint i = 0; i < fileSize; ++i) {
+ uint16 col = READ_BE_UINT16(src); ++src;
+ palData[2] = (col & 0xF) << 2; col >>= 4;
+ palData[1] = (col & 0xF) << 2; col >>= 4;
+ palData[0] = (col & 0xF) << 2; col >>= 4;
+ palData += 3;
+ }
+ } else {
+ memcpy(palData, srcData, fileSize);
+ }
}
delete [] srcData;
}
void Screen::loadPalette(const byte *data, uint8 *palData, int bytes) {
debugC(9, kDebugLevelScreen, "Screen::loadPalette(%p, %p %d)", (const void *)data, (void *)palData, bytes);
- memcpy(palData, data, bytes);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ assert(bytes % 2 == 0);
+ assert(bytes / 2 <= 256);
+ bytes >>= 1;
+ const uint16 *src = (const uint16 *)data;
+ for (int i = 0; i < bytes; ++i) {
+ uint16 col = READ_BE_UINT16(src); ++src;
+ palData[2] = (col & 0xF) << 2; col >>= 4;
+ palData[1] = (col & 0xF) << 2; col >>= 4;
+ palData[0] = (col & 0xF) << 2; col >>= 4;
+ palData += 3;
+ }
+ } else {
+ memcpy(palData, data, bytes);
+ }
}
// kyra3 specific
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index fbdb517f3c..aaf913c8d2 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -229,8 +229,9 @@ public:
// decoding functions
static void decodeFrame3(const uint8 *src, uint8 *dst, uint32 size);
static uint decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize);
- static void decodeFrameDelta(uint8 *dst, const uint8 *src);
+ static void decodeFrameDelta(uint8 *dst, const uint8 *src, bool noXor = false);
static void decodeFrameDeltaPage(uint8 *dst, const uint8 *src, const int pitch, bool noXor);
+ static void convertAmigaGfx(uint8 *data, int w, int h, bool offscreen = true);
// maybe subclass screen for kyra3
static const ScreenDim _screenDimTableK3[];
@@ -270,6 +271,7 @@ private:
void copyScreenFromRect(int x, int y, int w, int h, const uint8 *ptr);
void copyScreenToRect(int x, int y, int w, int h, uint8 *ptr);
+ template<bool noXor> static void wrapped_decodeFrameDelta(uint8 *dst, const uint8 *src);
template<bool noXor> static void wrapped_decodeFrameDeltaPage(uint8 *dst, const uint8 *src, const int pitch);
uint8 *_pagePtrs[16];
diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp
index 19a1db615a..cf5eb9cb90 100644
--- a/engines/kyra/seqplayer.cpp
+++ b/engines/kyra/seqplayer.cpp
@@ -92,7 +92,7 @@ uint8 *SeqPlayer::setPanPages(int pageNum, int shape) {
void SeqPlayer::makeHandShapes() {
debugC(9, kDebugLevelSequence, "SeqPlayer::makeHandShapes()");
- _screen->loadBitmap("WRITING.CPS", 3, 3, 0);
+ _screen->loadBitmap("WRITING.CPS", 3, 3, _screen->_currentPalette);
if (_vm->gameFlags().platform == Common::kPlatformMacintosh || _vm->gameFlags().platform == Common::kPlatformAmiga) {
freeHandShapes();
@@ -248,16 +248,28 @@ void SeqPlayer::s1_skip() {
void SeqPlayer::s1_loadPalette() {
uint8 colNum = *_seqData++;
- uint32 fileSize;
- uint8 *srcData;
- srcData = _res->fileData(_vm->seqCOLTable()[colNum], &fileSize);
- memcpy(_screen->_currentPalette, srcData, fileSize);
- delete[] srcData;
+
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ if (!colNum) {
+ memcpy(_screen->_currentPalette, _screen->_currentPalette + 576, 3*32);
+ } else if (colNum == 3) {
+ memcpy(_screen->_currentPalette, _screen->_currentPalette + 672, 3*32);
+ } else if (colNum == 4) {
+ memcpy(_screen->_currentPalette, _screen->_currentPalette + 288, 3*32);
+ }
+ _screen->setScreenPalette(_screen->_currentPalette);
+ } else {
+ uint32 fileSize;
+ uint8 *srcData;
+ srcData = _res->fileData(_vm->seqCOLTable()[colNum], &fileSize);
+ memcpy(_screen->_currentPalette, srcData, fileSize);
+ delete [] srcData;
+ }
}
void SeqPlayer::s1_loadBitmap() {
uint8 cpsNum = *_seqData++;
- _screen->loadBitmap(_vm->seqCPSTable()[cpsNum], 3, 3, 0);
+ _screen->loadBitmap(_vm->seqCPSTable()[cpsNum], 3, 3, _screen->_currentPalette);
}
void SeqPlayer::s1_fadeToBlack() {
@@ -267,7 +279,10 @@ void SeqPlayer::s1_fadeToBlack() {
void SeqPlayer::s1_printText() {
static const uint8 colorMap[] = { 0, 0, 0, 0, 12, 12, 12, 0, 0, 0, 0, 0 };
uint8 txt = *_seqData++;
- _screen->fillRect(0, 180, 319, 195, 12);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ _screen->fillRect(0, 180, 319, 195, 0);
+ else
+ _screen->fillRect(0, 180, 319, 195, 12);
_screen->setTextColorMap(colorMap);
if (!_seqDisplayTextFlag) {
const char *str = _vm->seqTextsTable()[txt];
@@ -320,7 +335,10 @@ void SeqPlayer::s1_restoreTalkText() {
}
void SeqPlayer::s1_clearCurrentScreen() {
- _screen->fillRect(10, 180, 319, 196, 0xC);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ _screen->fillRect(10, 180, 319, 195, 0);
+ else
+ _screen->fillRect(10, 180, 319, 196, 0xC);
}
void SeqPlayer::s1_break() {
@@ -349,16 +367,29 @@ void SeqPlayer::s1_copyRegionSpecial() {
uint8 so = *_seqData++;
switch (so) {
case 0:
- _screen->copyRegion(0, 0, 0, 47, 320, 77, 2, 0);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ _screen->copyRegion(0, 0, 0, 47, 312, 76, 2, 0);
+ else
+ _screen->copyRegion(0, 0, 0, 47, 320, 77, 2, 0);
break;
case 1:
- _screen->copyRegion(0, 0, 0, 47, 320, 56, 2, 0);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ _screen->copyRegion(0, 0, 8, 47, 312, 55, 2, 0);
+ else
+ _screen->copyRegion(0, 0, 0, 47, 320, 56, 2, 0);
break;
case 2:
- _screen->copyRegion(107, 72, 107, 72, 43, 87, 2, 0);
- _screen->copyRegion(130, 159, 130, 159, 35, 17, 2, 0);
- _screen->copyRegion(165, 105, 165, 105, 32, 9, 2, 0);
- _screen->copyRegion(206, 83, 206, 83, 94, 93, 2, 0);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ _screen->copyRegion(104, 72, 104, 72, 40, 87, 2, 0);
+ _screen->copyRegion(128, 159, 128, 159, 32, 17, 2, 0);
+ _screen->copyRegion(160, 105, 160, 105, 32, 9, 2, 0);
+ _screen->copyRegion(200, 83, 200, 83, 88, 93, 2, 0);
+ } else {
+ _screen->copyRegion(107, 72, 107, 72, 43, 87, 2, 0);
+ _screen->copyRegion(130, 159, 130, 159, 35, 17, 2, 0);
+ _screen->copyRegion(165, 105, 165, 105, 32, 9, 2, 0);
+ _screen->copyRegion(206, 83, 206, 83, 94, 93, 2, 0);
+ }
break;
case 3:
_screen->copyRegion(152, 56, 152, 56, 48, 48, 2, 0);
@@ -393,6 +424,8 @@ void SeqPlayer::s1_fillRect() {
void SeqPlayer::s1_playEffect() {
uint8 track = *_seqData++;
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ return;
_vm->delay(3 * _vm->tickLength());
_sound->playSoundEffect(track);
}
@@ -400,6 +433,9 @@ void SeqPlayer::s1_playEffect() {
void SeqPlayer::s1_playTrack() {
uint8 msg = *_seqData++;
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ return;
+
if (msg == 1) {
_sound->beginFadeOut();
} else {
diff --git a/engines/kyra/sequences_v1.cpp b/engines/kyra/sequences_v1.cpp
index 30deaf3e68..c243781a75 100644
--- a/engines/kyra/sequences_v1.cpp
+++ b/engines/kyra/sequences_v1.cpp
@@ -140,11 +140,22 @@ void KyraEngine::seq_introLogos() {
}
_screen->clearPage(0);
- _screen->loadBitmap("TOP.CPS", 7, 7, NULL);
- _screen->loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
+
+ if (_flags.platform == Common::kPlatformAmiga) {
+ _screen->loadPalette("INTRO.PAL", _screen->_currentPalette);
+ _screen->loadBitmap("BOTTOM.CPS", 3, 5, 0);
+ _screen->loadBitmap("TOP.CPS", 3, 3, 0);
+ _screen->copyRegion(0, 0, 0, 111, 320, 64, 2, 0);
+ _screen->copyRegion(0, 91, 0, 8, 320, 109, 2, 0);
+ _screen->copyRegion(0, 0, 0, 0, 320, 190, 0, 2);
+ } else {
+ _screen->loadBitmap("TOP.CPS", 7, 7, 0);
+ _screen->loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
+ _screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
+ _screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
+ }
+
_screen->_curPage = 0;
- _screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
- _screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
_screen->updateScreen();
_screen->fadeFromBlack();
@@ -154,6 +165,12 @@ void KyraEngine::seq_introLogos() {
return;
}
delay(60 * _tickLength);
+
+ if (_flags.platform == Common::kPlatformAmiga) {
+ memcpy(_screen->_currentPalette, _screen->_currentPalette + 3*32, 3*32);
+ _screen->setScreenPalette(_screen->_currentPalette);
+ }
+
if (_seq->playSequence(_seq_KyrandiaLogo, _skipFlag) && !seq_skipSequence() || _quitFlag) {
_screen->fadeToBlack();
_screen->clearPage(0);
@@ -164,38 +181,45 @@ void KyraEngine::seq_introLogos() {
if (_quitFlag)
return;
- _screen->copyRegion(0, 91, 0, 8, 320, 104, 6, 2);
- _screen->copyRegion(0, 0, 0, 112, 320, 64, 6, 2);
+ if (_flags.platform == Common::kPlatformAmiga) {
+ memcpy(_screen->_currentPalette, _screen->_currentPalette + 3*64, 3*32);
+ _screen->fadeToBlack();
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, 4, 0);
+ _screen->fadeFromBlack();
+ } else {
+ _screen->copyRegion(0, 91, 0, 8, 320, 104, 6, 2);
+ _screen->copyRegion(0, 0, 0, 112, 320, 64, 6, 2);
- uint32 start = _system->getMillis();
- bool doneFlag = false;
- int oldDistance = 0;
+ uint32 start = _system->getMillis();
+ bool doneFlag = false;
+ int oldDistance = 0;
- do {
- uint32 now = _system->getMillis();
+ do {
+ uint32 now = _system->getMillis();
- // The smallest y2 we ever draw the screen for is 65.
- int distance = (now - start) / _tickLength;
- if (distance > 112) {
- distance = 112;
- doneFlag = true;
- }
+ // The smallest y2 we ever draw the screen for is 65.
+ int distance = (now - start) / _tickLength;
+ if (distance > 112) {
+ distance = 112;
+ doneFlag = true;
+ }
- if (distance > oldDistance) {
- int y1 = 8 + distance;
- int h1 = 168 - distance;
- int y2 = 176 - distance;
- int h2 = distance;
+ if (distance > oldDistance) {
+ int y1 = 8 + distance;
+ int h1 = 168 - distance;
+ int y2 = 176 - distance;
+ int h2 = distance;
- _screen->copyRegion(0, y1, 0, 8, 320, h1, 2, 0);
- if (h2 > 0)
- _screen->copyRegion(0, 64, 0, y2, 320, h2, 4, 0);
- _screen->updateScreen();
- }
+ _screen->copyRegion(0, y1, 0, 8, 320, h1, 2, 0);
+ if (h2 > 0)
+ _screen->copyRegion(0, 64, 0, y2, 320, h2, 4, 0);
+ _screen->updateScreen();
+ }
- oldDistance = distance;
- delay(10);
- } while (!doneFlag && !_quitFlag && !_abortIntroFlag);
+ oldDistance = distance;
+ delay(10);
+ } while (!doneFlag && !_quitFlag && !_abortIntroFlag);
+ }
if (_quitFlag)
return;
@@ -209,21 +233,22 @@ void KyraEngine::seq_introStory() {
_screen->clearPage(0);
if (_flags.isTalkie) {
return;
- } else if (_flags.lang == Common::EN_ANY && _flags.platform == Common::kPlatformPC) {
- _screen->loadBitmap("TEXT.CPS", 3, 3, 0);
+ } else if (_flags.lang == Common::EN_ANY && (_flags.platform == Common::kPlatformPC || _flags.platform == Common::kPlatformAmiga)) {
+ _screen->loadBitmap("TEXT.CPS", 3, 3, _screen->_currentPalette);
} else if (_flags.lang == Common::EN_ANY || _flags.lang == Common::JA_JPN) {
- _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, 0);
+ _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, _screen->_currentPalette);
} else if (_flags.lang == Common::DE_DEU) {
- _screen->loadBitmap("TEXT_GER.CPS", 3, 3, 0);
+ _screen->loadBitmap("TEXT_GER.CPS", 3, 3, _screen->_currentPalette);
} else if (_flags.lang == Common::FR_FRA) {
- _screen->loadBitmap("TEXT_FRE.CPS", 3, 3, 0);
+ _screen->loadBitmap("TEXT_FRE.CPS", 3, 3, _screen->_currentPalette);
} else if (_flags.lang == Common::ES_ESP) {
- _screen->loadBitmap("TEXT_SPA.CPS", 3, 3, 0);
+ _screen->loadBitmap("TEXT_SPA.CPS", 3, 3, _screen->_currentPalette);
} else if (_flags.lang == Common::IT_ITA) {
- _screen->loadBitmap("TEXT_ITA.CPS", 3, 3, 0);
+ _screen->loadBitmap("TEXT_ITA.CPS", 3, 3, _screen->_currentPalette);
} else {
warning("no story graphics file found");
}
+ _screen->setScreenPalette(_screen->_currentPalette);
_screen->copyRegion(0, 0, 0, 0, 320, 200, 3, 0);
if (_flags.lang == Common::JA_JPN) {
diff --git a/engines/kyra/sprites.cpp b/engines/kyra/sprites.cpp
index ba1e08ede1..707f3eec35 100644
--- a/engines/kyra/sprites.cpp
+++ b/engines/kyra/sprites.cpp
@@ -422,7 +422,10 @@ void Sprites::loadDAT(const char *filename, SceneExits &exits) {
}
// XXX
_engine->_paletteChanged = 1;
- _screen->loadPalette(_dat + 0x17, _screen->getPalette(1) + 684, 60);
+ // FIXME: check this...
+ if (_engine->gameFlags().platform != Common::kPlatformAmiga) {
+ _screen->loadPalette(_dat + 0x17, _screen->getPalette(1) + 684, 60);
+ }
uint8 *data = _dat + 0x6B;
uint16 length = READ_LE_UINT16(data);
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 563826ff1c..9851761000 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -31,7 +31,7 @@
namespace Kyra {
-#define RESFILE_VERSION 16
+#define RESFILE_VERSION 17
bool StaticResource::checkKyraDat() {
Common::File kyraDat;
@@ -71,10 +71,10 @@ enum {
GF_JAPANESE = 1 << 9,
// other languages here
GF_LNGUNK = 1 << 16, // also used for multi language in kyra3
- GF_AMIGA = 1 << 17 // this is no special version flag yet!
+ GF_AMIGA = 1 << 17
};
-#define GAME_FLAGS (GF_FLOPPY | GF_TALKIE | GF_DEMO | GF_FMTOWNS)
+#define GAME_FLAGS (GF_FLOPPY | GF_TALKIE | GF_DEMO | GF_FMTOWNS | GF_AMIGA)
#define LANGUAGE_FLAGS (GF_ENGLISH | GF_FRENCH | GF_GERMAN | GF_SPANISH | GF_ITALIAN | GF_JAPANESE | GF_LNGUNK)
uint32 createFeatures(const GameFlags &flags) {
@@ -84,6 +84,8 @@ uint32 createFeatures(const GameFlags &flags) {
return GF_DEMO;
if (flags.platform == Common::kPlatformFMTowns)
return GF_FMTOWNS;
+ if (flags.platform == Common::kPlatformAmiga)
+ return GF_AMIGA;
return GF_FLOPPY;
}
@@ -613,7 +615,9 @@ uint8 *StaticResource::getFile(const char *name, int &size) {
ext = ".DEM";
} else if (_engine->gameFlags().platform == Common::kPlatformFMTowns) {
ext = ".TNS";
- }
+ } else if (_engine->gameFlags().platform == Common::kPlatformAmiga) {
+ ext = ".AMG";
+ }
snprintf(buffer, 64, "%s%s", name, ext);
uint32 tempSize = 0;
uint8 *data = _engine->resource()->fileData(buffer, &tempSize);
diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp
index e1a4863df0..8ba0793f8c 100644
--- a/engines/kyra/wsamovie.cpp
+++ b/engines/kyra/wsamovie.cpp
@@ -72,7 +72,10 @@ int WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) {
}
if (_numFrames & 0x8000) {
- warning("Unhandled wsa flags 0x80");
+ // This is used in the Amiga version, the wsa playing code
+ // doesn't include any handling of it though, so we disable
+ // this warning for now.
+ //warning("Unhandled wsa flags 0x80");
_flags |= 0x80;
_numFrames &= 0x7FFF;
}
@@ -212,6 +215,141 @@ void WSAMovieV1::processFrame(int frameNum, uint8 *dst) {
#pragma mark -
+WSAMovieAmiga::WSAMovieAmiga(KyraEngine *vm) : WSAMovieV1(vm), _buffer(0) {}
+
+int WSAMovieAmiga::open(const char *filename, int offscreenDecode, uint8 *palBuf) {
+ debugC(9, kDebugLevelMovie, "WSAMovieAmiga::open('%s', %d, %p)", filename, offscreenDecode, (const void *)palBuf);
+ int res = WSAMovieV1::open(filename, offscreenDecode, palBuf);
+
+ if (!res)
+ return 0;
+
+ _buffer = new uint8[_width * _height];
+ assert(_buffer);
+ return res;
+}
+
+void WSAMovieAmiga::close() {
+ debugC(9, kDebugLevelMovie, "WSAMovieAmiga::close()");
+ if (_opened) {
+ delete [] _buffer;
+ _buffer = 0;
+ }
+ WSAMovieV1::close();
+}
+
+void WSAMovieAmiga::displayFrame(int frameNum) {
+ debugC(9, kDebugLevelMovie, "WSAMovieAmiga::displayFrame(%d)", frameNum);
+ if (frameNum >= _numFrames || !_opened)
+ return;
+
+ uint8 *dst;
+ dst = _buffer;
+ memset(_buffer, 0, _width*_height);
+
+ if (_currentFrame == _numFrames) {
+ if (!(_flags & WF_NO_FIRST_FRAME)) {
+ Screen::decodeFrameDelta(dst, _deltaBuffer, true);
+ Screen::convertAmigaGfx(dst, _width, _height);
+
+ if (_flags & WF_OFFSCREEN_DECODE) {
+ dst = _offscreenBuffer;
+ const uint8 *src = _buffer;
+ int size = _width * _height;
+
+ for (int i = 0; i < size; ++i) {
+ *dst++ ^= *src++;
+ }
+
+ dst = _buffer;
+ } else {
+ _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _buffer);
+ }
+ }
+ _currentFrame = 0;
+ }
+
+ // try to reduce the number of needed frame operations
+ int diffCount = ABS(_currentFrame - frameNum);
+ int frameStep = 1;
+ int frameCount;
+ if (_currentFrame < frameNum) {
+ frameCount = _numFrames - frameNum + _currentFrame;
+ if (diffCount > frameCount) {
+ frameStep = -1;
+ } else {
+ frameCount = diffCount;
+ }
+ } else {
+ frameCount = _numFrames - _currentFrame + frameNum;
+ if (frameCount >= diffCount) {
+ frameStep = -1;
+ frameCount = diffCount;
+ }
+ }
+
+ // process
+ if (frameStep > 0) {
+ uint16 cf = _currentFrame;
+ while (frameCount--) {
+ cf += frameStep;
+ processFrame(cf, dst);
+ if (cf == _numFrames) {
+ cf = 0;
+ }
+ }
+ } else {
+ uint16 cf = _currentFrame;
+ while (frameCount--) {
+ if (cf == 0) {
+ cf = _numFrames;
+ }
+ processFrame(cf, dst);
+ cf += frameStep;
+ }
+ }
+
+ // display
+ _currentFrame = frameNum;
+ if (_flags & WF_OFFSCREEN_DECODE) {
+ _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer);
+ }
+}
+
+void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) {
+ debugC(9, kDebugLevelMovie, "WSAMovieAmiga::processFrame(%d, %p)", frameNum, (const void *)dst);
+ if (!_opened)
+ return;
+ assert(frameNum <= _numFrames);
+
+ memset(dst, 0, _width*_height);
+
+ const uint8 *src = _frameData + _frameOffsTable[frameNum];
+ Screen::decodeFrame4(src, _deltaBuffer, _deltaBufferSize);
+ Screen::decodeFrameDelta(dst, _deltaBuffer, true);
+ Screen::convertAmigaGfx(dst, _width, _height);
+
+ src = dst;
+ dst = 0;
+ int dstPitch = 0;
+ if (_flags & WF_OFFSCREEN_DECODE) {
+ dst = _offscreenBuffer;
+ dstPitch = _width;
+ } else {
+ dst = _vm->screen()->getPageRect(_drawPage, _x, _y, _width, _height);
+ dstPitch = Screen::SCREEN_W;
+ }
+
+ for (int y = 0; y < _height; ++y) {
+ for (int x = 0; x < _width; ++x) {
+ *dst++ ^= *src++;
+ }
+ dst += dstPitch - _width;
+ }
+}
+
+#pragma mark -
+
WSAMovieV2::WSAMovieV2(KyraEngine *vm) : WSAMovieV1(vm), _xAdd(0), _yAdd(0) {}
int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) {
diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h
index dc50213939..6744ba0715 100644
--- a/engines/kyra/wsamovie.h
+++ b/engines/kyra/wsamovie.h
@@ -92,6 +92,19 @@ protected:
uint8 *_frameData;
};
+class WSAMovieAmiga : public WSAMovieV1 {
+public:
+ WSAMovieAmiga(KyraEngine *vm);
+ int open(const char *filename, int offscreen, uint8 *palette);
+ void close();
+
+ void displayFrame(int frameNum);
+private:
+ void processFrame(int frameNum, uint8 *dst);
+
+ uint8 *_buffer;
+};
+
class WSAMovieV2 : public WSAMovieV1 {
public:
WSAMovieV2(KyraEngine *vm);