From 689ea77c0d8be927d2d5c9874239e444267a4999 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 12 Mar 2007 20:43:56 +0000 Subject: WIP code for Amiga version: - Font displaying is not yet supported. - Intro should be glitch free - all other things are *untested* svn-id: r26113 --- engines/kyra/kyra.cpp | 3 +- engines/kyra/plugin.cpp | 3 +- engines/kyra/scene.cpp | 10 ++- engines/kyra/screen.cpp | 134 +++++++++++++++++++++++++++++++++++++--- engines/kyra/screen.h | 4 +- engines/kyra/seqplayer.cpp | 66 +++++++++++++++----- engines/kyra/sequences_v1.cpp | 99 ++++++++++++++++++----------- engines/kyra/sprites.cpp | 5 +- engines/kyra/staticres.cpp | 12 ++-- engines/kyra/wsamovie.cpp | 140 +++++++++++++++++++++++++++++++++++++++++- engines/kyra/wsamovie.h | 13 ++++ 11 files changed, 418 insertions(+), 71 deletions(-) (limited to 'engines/kyra') 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(dst, src); + else + wrapped_decodeFrameDelta(dst, src); +} + +template +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 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 static void wrapped_decodeFrameDelta(uint8 *dst, const uint8 *src); template 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); -- cgit v1.2.3