diff options
Diffstat (limited to 'engines/kyra')
-rw-r--r-- | engines/kyra/animator_v3.cpp | 270 | ||||
-rw-r--r-- | engines/kyra/kyra.h | 4 | ||||
-rw-r--r-- | engines/kyra/kyra_v3.cpp | 296 | ||||
-rw-r--r-- | engines/kyra/kyra_v3.h | 121 | ||||
-rw-r--r-- | engines/kyra/module.mk | 2 | ||||
-rw-r--r-- | engines/kyra/scene_v3.cpp | 647 | ||||
-rw-r--r-- | engines/kyra/screen.cpp | 10 | ||||
-rw-r--r-- | engines/kyra/screen.h | 2 | ||||
-rw-r--r-- | engines/kyra/staticres.cpp | 12 | ||||
-rw-r--r-- | engines/kyra/text.h | 2 | ||||
-rw-r--r-- | engines/kyra/text_v3.cpp | 48 | ||||
-rw-r--r-- | engines/kyra/text_v3.h | 47 |
12 files changed, 1433 insertions, 28 deletions
diff --git a/engines/kyra/animator_v3.cpp b/engines/kyra/animator_v3.cpp index 5278ec78c3..9d6c42f084 100644 --- a/engines/kyra/animator_v3.cpp +++ b/engines/kyra/animator_v3.cpp @@ -24,6 +24,7 @@ */ #include "kyra/kyra_v3.h" +#include "kyra/wsamovie.h" namespace Kyra { @@ -62,4 +63,273 @@ void KyraEngine_v3::clearAnimObjects() { } } +KyraEngine_v3::AnimObj *KyraEngine_v3::initAnimList(AnimObj *list, AnimObj *entry) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::initAnimList(%p, %p)", (const void*)list, (const void*)entry); + entry->nextObject = list; + return entry; +} + +KyraEngine_v3::AnimObj *KyraEngine_v3::addToAnimListSorted(AnimObj *list, AnimObj *add) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::addToAnimListSorted(%p, %p)", (const void*)list, (const void*)add); + add->nextObject = 0; + + if (!list) + return add; + + if (add->yPos1 <= list->yPos1) { + add->nextObject = list; + return add; + } + + AnimObj *cur = list; + AnimObj *prev = list; + while (add->yPos1 > cur->yPos1) { + AnimObj *temp = cur->nextObject; + if (!temp) + break; + prev = cur; + cur = temp; + } + + if (add->yPos1 <= cur->yPos1) { + prev->nextObject = add; + add->nextObject = cur; + } else { + cur->nextObject = add; + add->nextObject = 0; + } + return list; +} + +KyraEngine_v3::AnimObj *KyraEngine_v3::deleteAnimListEntry(AnimObj *list, AnimObj *entry) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::addToAnimListSorted(%p, %p)", (const void*)list, (const void*)entry); + if (!list) + return 0; + + AnimObj *old = 0; + AnimObj *cur = list; + + while (true) { + if (cur == entry) + break; + if (!cur->nextObject) + break; + old = cur; + cur = cur->nextObject; + } + + if (cur != entry) + return list; + + if (cur == list) { + if (!cur->nextObject) + return 0; + cur = cur->nextObject; + return cur; + } + + if (!cur->nextObject) { + if (!old) + return 0; + old->nextObject = 0; + return list; + } + + if (cur != entry) + return list; + + old->nextObject = entry->nextObject; + return list; +} + +void KyraEngine_v3::animSetupPaletteEntry(AnimObj *anim) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::animSetupPaletteEntry(%p)", (const void*)anim); + int layer = _screen->getLayer(anim->xPos1, anim->yPos1) - 1; + int16 count = 0; + for (int i = 0; i < 3; ++i) + count += _sceneDatPalette[layer*3+i]; + count /= 3; + count *= -1; + count = MAX<int16>(0, MIN<int16>(count, 10)); + anim->palette = count / 3; +} + +void KyraEngine_v3::restorePage3() { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::restorePage3()"); + musicUpdate(0); + _screen->copyBlockToPage(3, 0, 0, 320, 200, _gamePlayBuffer); + musicUpdate(0); +} + +void KyraEngine_v3::drawAnimObjects() { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::drawAnimObjects()"); + for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { + if (!curObject->enabled) + continue; + + int x = curObject->xPos2 - (_screen->getScreenDim(2)->sx << 3); + int y = curObject->yPos2 - _screen->getScreenDim(2)->sy; + int layer = 7; + + if (curObject->flags & 0x800) { + if (!curObject->unk8) + layer = 0; + else + layer = getDrawLayer(curObject->xPos1, curObject->yPos1); + } + + if (curObject->index) + drawSceneAnimObject(curObject, x, y, layer); + else + drawCharacterAnimObject(curObject, x, y, layer); + } +} + +void KyraEngine_v3::drawSceneAnimObject(AnimObj *obj, int x, int y, int layer) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::drawSceneAnimObject(%p, %d, %d, %d)", (const void*)obj, x, y, layer); + if (obj->type == 1) { + if (obj->shapeIndex == 0xFFFF) + return; + int scale = getScale(obj->xPos1, obj->yPos1); + _screen->drawShape(2, getShapePtr(obj->shapeIndex), x, y, 2, obj->flags | 104, _paletteOverlay, obj->palette, layer, scale, scale); + } else { + if (obj->shapePtr) { + _screen->drawShape(2, obj->shapePtr, x, y, 2, obj->flags, 7); + } else { + if (obj->shapeIndex3 == 0xFFFF || obj->animNum == 0xFFFF) + return; + uint16 flags = 0x4000; + if (obj->flags & 0x800) + flags |= 0x8000; + int x = obj->xPos2 - _sceneAnimMovie[obj->animNum]->xAdd(); + int y = obj->yPos1 - _sceneAnimMovie[obj->animNum]->yAdd(); + _sceneAnimMovie[obj->animNum]->setDrawPage(2); + _sceneAnimMovie[obj->animNum]->setX(x); + _sceneAnimMovie[obj->animNum]->setY(y); + _sceneAnimMovie[obj->animNum]->displayFrame(obj->shapeIndex3, flags | layer); + } + } +} + +void KyraEngine_v3::drawCharacterAnimObject(AnimObj *obj, int x, int y, int layer) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::drawCharacterAnimObject(%p, %d, %d, %d)", (const void*)obj, x, y, layer); + if (_drawNoShapeFlag) + return; + + if (_mainCharacter.animFrame < 9) + _mainCharacter.animFrame = 87; + + if (obj->shapeIndex == 0xFFFF || _mainCharacter.animFrame == 87) + return; + + _screen->drawShape(2, getShapePtr(421), _mainCharacter.x3, _mainCharacter.y3, 2, obj->flags | 304, _paletteOverlay, 3, layer, _charScale, _charScale); + uint8 *shape = getShapePtr(_mainCharacter.animFrame); + if (shape) + _screen->drawShape(2, shape, x, y, 2, obj->flags | 2, layer, _charScale, _charScale); +} + +void KyraEngine_v3::refreshAnimObjects(int force) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::refreshAnimObjects(%d)", force); + for (AnimObj *curObject = _animList; curObject; curObject = curObject->nextObject) { + if (!curObject->enabled) + continue; + if (!curObject->needRefresh && !force) + continue; + + const int scale = (curObject->index == 0) ? _charScale : 0; + + int x = curObject->xPos2 - curObject->width2; + if (scale) + x -= (0x100 - scale) >> 4; + + if (x < 0) + x = 0; + if (x >= 320) + x = 319; + + int y = curObject->yPos2 - curObject->height2; + if (scale) + y -= (0x100 - scale) >> 3; + if (y < 0) + y = 0; + if (y >= 187) + y = 186; + + int width = curObject->width + curObject->width2 + 8; + int height = curObject->height + curObject->height2*2; + if (width + x > 320) + width -= width + x - 322; + + const int maxY = _inventoryState ? 143 : 187; + if (height + y > maxY) + height -= height + y - (maxY + 1); + + if (height > 0) { + _screen->hideMouse(); + _screen->copyRegion(x, y, x, y, width, height, 2, 0, Screen::CR_NO_P_CHECK); + _screen->showMouse(); + } + + curObject->needRefresh = false; + } +} + +void KyraEngine_v3::refreshAnimObjectsIfNeed() { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::refreshAnimObjectsIfNeed()"); + for (AnimObj *curEntry = _animList; curEntry; curEntry = curEntry->nextObject) { + if (curEntry->enabled && curEntry->needRefresh) { + restorePage3(); + drawAnimObjects(); + refreshAnimObjects(0); + _screen->updateScreen(); + return; + } + } +} + +void KyraEngine_v3::updateCharacterAnim(int charId) { + debugC(9, kDebugLevelAnimator, "KyraEngine_v3::updateCharacterAnim(%d)", charId); + + AnimObj *obj = &_animObjects[0]; + obj->needRefresh = true; + obj->flags &= ~1; + obj->xPos1 = _mainCharacter.x1; + obj->yPos1 = _mainCharacter.y1; + obj->shapePtr = getShapePtr(_mainCharacter.animFrame); + obj->shapeIndex = obj->shapeIndex2 = _mainCharacter.animFrame; + + int shapeOffsetX = 0, shapeOffsetY = 0; + //XXX if (_mainCharacter.animFrame >= 50 && _mainCharacter.animFrame <= 87) { + shapeOffsetX = _malcolmShapeXOffset; + shapeOffsetY = _malcolmShapeYOffset; + //} else { + //} + + obj->xPos2 = _mainCharacter.x1; + obj->yPos2 = _mainCharacter.y1; + _charScale = getScale(_mainCharacter.x1, _mainCharacter.y1); + obj->xPos2 += (shapeOffsetX * _charScale) >> 8; + obj->yPos2 += (shapeOffsetY * _charScale) >> 8; + _mainCharacter.x3 = _mainCharacter.x1 - (_charScale >> 4) - 1; + _mainCharacter.y3 = _mainCharacter.y1 - (_charScale >> 6) - 1; + //if (_charSpecialWidth2 == -1) { + obj->width2 = 4; + obj->height2 = 10; + //} + + for (int i = 1; i <= 16; ++i) { + if (_animObjects[i].enabled && _animObjects[i].unk8) + _animObjects[i].needRefresh = true; + } + + obj = deleteAnimListEntry(_animList, obj); + if (_animList) + _animList = addToAnimListSorted(_animList, obj); + else + _animList = initAnimList(_animList, obj); + + if (!_loadingState) + updateCharPal(1); +} + } // end of namespace Kyra diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h index 20a7ba7c7f..f88b23ea05 100644 --- a/engines/kyra/kyra.h +++ b/engines/kyra/kyra.h @@ -129,6 +129,7 @@ public: Common::RandomSource _rnd; // input + void setMousePos(int x, int y); Common::Point getMousePos() const; // config specific @@ -225,9 +226,6 @@ protected: const int8 *_trackMap; int _trackMapSize; - // input - void setMousePos(int x, int y); - // pathfinder virtual int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize); int findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end); diff --git a/engines/kyra/kyra_v3.cpp b/engines/kyra/kyra_v3.cpp index 2f42d6ec82..f26584462b 100644 --- a/engines/kyra/kyra_v3.cpp +++ b/engines/kyra/kyra_v3.cpp @@ -28,7 +28,7 @@ #include "kyra/screen_v3.h" #include "kyra/wsamovie.h" #include "kyra/sound.h" -#include "kyra/text.h" +#include "kyra/text_v3.h" #include "kyra/vqa.h" #include "kyra/gui.h" @@ -65,6 +65,33 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi _mainCharacter.facing = 5; _mainCharacter.walkspeed = 5; memset(_mainCharacter.inventory, -1, sizeof(_mainCharacter.inventory)); + _text = 0; + _commandLineY = 189; + _inventoryState = false; + memset(&_sceneScriptState, 0, sizeof(_sceneScriptState)); + memset(&_sceneScriptData, 0, sizeof(_sceneScriptData)); + memset(_wsaSlots, 0, sizeof(_wsaSlots)); + _updateCharPosNextUpdate = 0; + memset(_characterAnimTable, 0, sizeof(_characterAnimTable)); + _overwriteSceneFacing = false; + _maskPageMinY = _maskPageMaxY = 0; + _sceneStrings = 0; + _enterNewSceneLock = 0; + _mainCharX = _mainCharY = -1; + _animList = 0; + _drawNoShapeFlag = false; + _wsaPlayingVQA = false; + _lastCharPalLayer = -1; + _charPalUpdate = false; + _runFlag = false; + _unkInputFlag = false; + _unkSceneScreenFlag1 = false; + _noScriptEnter = true; + _itemInHand = _handItemSet = -1; + _unk3 = -1; + _unk4 = 0; + _loadingState = false; + _noStartupChat = false; } KyraEngine_v3::~KyraEngine_v3() { @@ -100,6 +127,13 @@ KyraEngine_v3::~KyraEngine_v3() { i->_value = 0; } _gameShapes.clear(); + + _scriptInterpreter->unloadScript(&_sceneScriptData); + + for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) + delete _wsaSlots[i]; + + delete [] _sceneStrings; } int KyraEngine_v3::init() { @@ -114,6 +148,8 @@ int KyraEngine_v3::init() { assert(_soundDigital); if (!_soundDigital->init()) error("_soundDigital->init() failed"); + KyraEngine::_text = _text = new TextDisplayer_v3(this, _screen); + assert(_text); _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); @@ -146,9 +182,6 @@ int KyraEngine_v3::go() { // XXX playMenuAudioFile(); - _menuAnim->setX(0); _menuAnim->setY(0); - _menuAnim->setDrawPage(0); - for (int i = 0; i < 64 && !_quitFlag; ++i) { uint32 nextRun = _system->getMillis() + 3 * _tickLength; _menuAnim->displayFrame(i, 0); @@ -173,9 +206,8 @@ int KyraEngine_v3::go() { break; case 1: - _soundDigital->beginFadeOut(_musicSoundChannel, 60); - _screen->fadeToBlack(60); playVQA("K3INTRO"); + _wsaPlayingVQA = false; _screen->hideMouse(); break; @@ -206,8 +238,11 @@ int KyraEngine_v3::go() { } void KyraEngine_v3::initMainMenu() { - _menuAnim = createWSAMovie(); + _menuAnim = new WSAMovieV2(this, _screen); _menuAnim->open("REVENGE.WSA", 1, _screen->getPalette(0)); + _menuAnim->setX(0); + _menuAnim->setY(0); + _menuAnim->setDrawPage(0); memset(_screen->getPalette(0), 0, 3); _menu = new MainMenu(this); @@ -237,8 +272,6 @@ void KyraEngine_v3::uninitMainMenu() { void KyraEngine_v3::playVQA(const char *name) { debugC(9, kDebugLevelMain, "KyraEngine_v3::playVQA('%s')", name); - memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); - VQAMovie vqa(this, _system); char filename[20]; @@ -247,26 +280,28 @@ void KyraEngine_v3::playVQA(const char *name) { snprintf(filename, sizeof(filename), "%s%d.VQA", name, size); if (vqa.open(filename)) { - uint8 pal[768]; - memcpy(pal, _screen->getPalette(0), sizeof(pal)); - if (_screen->_curPage == 0) - _screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 3); + _soundDigital->stopAllSounds(); _screen->hideMouse(); - _soundDigital->beginFadeOut(_musicSoundChannel, 60); - _musicSoundChannel = -1; + memcpy(_screen->getPalette(1), _screen->getPalette(0), 768); + fadeOutMusic(60); _screen->fadeToBlack(); + _screen->clearPage(0); + vqa.setDrawPage(0); vqa.play(); vqa.close(); + + _soundDigital->stopAllSounds(); _screen->showMouse(); - if (_screen->_curPage == 0) - _screen->copyRegion(0, 0, 0, 0, 320, 200, 3, 0); + uint8 pal[768]; + memset(pal, 1, sizeof(pal)); _screen->setScreenPalette(pal); + _screen->clearPage(0); + memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); + _wsaPlayingVQA = true; } - - memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); } #pragma mark - @@ -344,6 +379,15 @@ int KyraEngine_v3::musicUpdate(int forceRestart) { return 1; } +void KyraEngine_v3::fadeOutMusic(int ticks) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::fadeOutMusic(%d)", ticks); + if (_musicSoundChannel >= 0) { + _fadeOutMusicChannel = _musicSoundChannel; + _soundDigital->beginFadeOut(_musicSoundChannel, ticks); + _curMusicTrack = -1; + } +} + #pragma mark - void KyraEngine_v3::preinit() { @@ -369,6 +413,11 @@ void KyraEngine_v3::initMouseShapes() { void KyraEngine_v3::startup() { debugC(9, kDebugLevelMain, "KyraEngine_v3::startup()"); + for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) { + _wsaSlots[i] = new WSAMovieV2(this, _screen); + assert(_wsaSlots[i]); + } + musicUpdate(0); memset(_flagsTable, 0, sizeof(_flagsTable)); @@ -471,7 +520,8 @@ void KyraEngine_v3::startup() { //openMoondomtrWsa(); _soundDigital->beginFadeOut(_musicSoundChannel, 60); delayWithTicks(60); - //XXX enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); + enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); + _screen->updateScreen(); musicUpdate(0); _screen->showMouse(); //XXX @@ -643,6 +693,212 @@ void KyraEngine_v3::updateMalcolmShapes() { #pragma mark - +void KyraEngine_v3::showMessage(const char *string, uint8 c0, uint8 c1) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::showMessage('%s', %d, %d)", string, c0, c1); + _shownMessage = string; + _screen->hideMouse(); + + restoreCommandLine(); + _restoreCommandLine = false; + + if (string) { + int x = _text->getCenterStringX(string, 0, 320); + int pageBackUp = _screen->_curPage; + _screen->_curPage = 0; + _text->printText(string, x, _commandLineY, c0, c1, 0); + _screen->_curPage = pageBackUp; + _screen->updateScreen(); + //setCommandLineRestoreTimer(7); + } + + _screen->showMouse(); +} + +void KyraEngine_v3::restoreCommandLine() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::restoreCommandLine()"); + int y = _inventoryState ? 144 : 188; + _screen->copyBlockToPage(0, 0, y, 320, 12, _interfaceCommandLine); +} + +#pragma mark - + +void KyraEngine_v3::moveCharacter(int facing, int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::moveCharacter(%d, %d, %d)", facing, x, y); + x &= ~3; + y &= ~1; + _mainCharacter.facing = facing; + + _screen->hideMouse(); + switch (facing) { + case 0: + while (_mainCharacter.y1 > y) + updateCharPosWithUpdate(); + break; + + case 2: + while (_mainCharacter.x1 < x) + updateCharPosWithUpdate(); + break; + + case 4: + while (_mainCharacter.y1 < y) + updateCharPosWithUpdate(); + break; + + case 6: + while (_mainCharacter.x1 > x) + updateCharPosWithUpdate(); + break; + + default: + break; + } + _screen->showMouse(); +} + +void KyraEngine_v3::updateCharPosWithUpdate() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPosWithUpdate()"); + updateCharPos(0, 0); + update(); +} + +void KyraEngine_v3::updateCharPos(uint8 *table, int force) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPos(%p, %d)", table, force); + if (!force || (_updateCharPosNextUpdate > _system->getMillis())) + return; + _mainCharacter.x1 += _updateCharPosXTable[_mainCharacter.facing]; + _mainCharacter.y1 += _updateCharPosYTable[_mainCharacter.facing]; + updateCharAnimFrame(0, table); + _updateCharPosNextUpdate = _system->getMillis() + _mainCharacter.walkspeed * _tickLength; +} + +void KyraEngine_v3::updateCharAnimFrame(int character, uint8 *table) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPos(%d, %p)", character, table); + ++_mainCharacter.animFrame; + int facing = _mainCharacter.facing; + + if (table) { + if (table[0] != table[-1] && table[1] == table[-1]) { + facing = getOppositeFacingDirection(table[-1]); + table[0] = table[-1]; + } + } + + if (facing) { + if (facing == 7 || facing == 1) { + if (_characterAnimTable[0] > 2) + facing = 0; + memset(_characterAnimTable, 0, sizeof(_characterAnimTable)); + } else if (facing == 4) { + ++_characterAnimTable[1]; + } else if (facing == 5 || facing == 3) { + if (_characterAnimTable[1] > 2) + facing = 4; + memset(_characterAnimTable, 0, sizeof(_characterAnimTable)); + } + } else { + ++_characterAnimTable[0]; + } + + switch (facing) { + case 0: + if (_mainCharacter.animFrame < 79 || _mainCharacter.animFrame > 86) + _mainCharacter.animFrame = 79; + break; + + case 1: case 2: case 3: + if (_mainCharacter.animFrame < 71 || _mainCharacter.animFrame > 78) + _mainCharacter.animFrame = 71; + break; + + case 4: + if (_mainCharacter.animFrame < 55 || _mainCharacter.animFrame > 62) + _mainCharacter.animFrame = 55; + break; + + case 5: case 6: case 7: + if (_mainCharacter.animFrame < 63 || _mainCharacter.animFrame > 70) + _mainCharacter.animFrame = 63; + break; + + default: + break; + } + + updateCharacterAnim(0); +} + +void KyraEngine_v3::updateCharPal(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::updateCharPal(%d)", unk1); + int layer = _screen->getLayer(_mainCharacter.x1, _mainCharacter.y1) - 1; + const uint8 *src = _costPalBuffer + _malcolmShapes * 72; + uint8 *dst = _screen->getPalette(0) + 432; + const int8 *sceneDatPal = &_sceneDatPalette[layer * 3]; + + if (layer != _lastCharPalLayer && unk1) { + for (int i = 0, j = 0; i < 72; ++i) { + uint8 col = *dst; + int8 addCol = *src + *sceneDatPal; + addCol = MAX<int8>(0, MIN<int8>(addCol, 63)); + addCol = (col - addCol) >> 1; + *dst -= addCol; + ++dst; + ++src; + ++sceneDatPal; + ++j; + if (j > 3) { + sceneDatPal = &_sceneDatPalette[layer * 3]; + j = 0; + } + } + _charPalUpdate = true; + _screen->setScreenPalette(_screen->getPalette(0)); + _lastCharPalLayer = layer; + } else if (_charPalUpdate || !unk1) { + memcpy(dst, src, 72); + + for (int i = 0, j = 0; i < 72; ++i) { + uint8 col = *dst + *sceneDatPal; + *dst = MAX<int8>(0, MIN<int8>(col, 63)); + ++dst; + ++sceneDatPal; + ++j; + if (j > 3) { + sceneDatPal = &_sceneDatPalette[layer * 3]; + j = 0; + } + } + + _screen->setScreenPalette(_screen->getPalette(0)); + _charPalUpdate = false; + } +} + +#pragma mark - + +void KyraEngine_v3::update() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::update()"); + //XXX + + _screen->updateScreen(); +} + +#pragma mark - + +int KyraEngine_v3::getDrawLayer(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::getDrawLayer(%d, %d)", x, y); + int layer = _screen->getLayer(x, y) - 1; + layer = _sceneDatLayerTable[layer]; + return MAX(0, MIN(layer, 6)); +} + +int KyraEngine_v3::getScale(int x, int y) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::getScale(%d, %d)", x, y); + return _scaleTable[_screen->getLayer(x, y) - 1]; +} + +#pragma mark - + int KyraEngine_v3::getMaxFileSize(const char *file) { debugC(9, kDebugLevelMain, "KyraEngine_v3::getMaxFileSize(%s)", file); int size = 0; diff --git a/engines/kyra/kyra_v3.h b/engines/kyra/kyra_v3.h index f9b5ea22b3..75c43bca7a 100644 --- a/engines/kyra/kyra_v3.h +++ b/engines/kyra/kyra_v3.h @@ -28,6 +28,7 @@ #include "kyra/kyra.h" #include "kyra/screen_v3.h" +#include "kyra/script.h" #include "common/hashmap.h" namespace Kyra { @@ -36,6 +37,7 @@ class SoundDigital; class Screen_v3; class MainMenu; class WSAMovieV2; +class TextDisplayer_v3; class KyraEngine_v3 : public KyraEngine { public: @@ -56,10 +58,15 @@ private: void preinit(); void startup(); + void update(); + void runStartupScript(int script, int unk1); void setupOpcodeTable(); + bool _runFlag; + bool _unkInputFlag; + Screen_v3 *_screen; SoundDigital *_soundDigital; @@ -68,6 +75,7 @@ private: void playMenuAudioFile(); int _musicSoundChannel; + int _fadeOutMusicChannel; const char *_menuAudioFile; static const char *_soundList[]; @@ -79,6 +87,7 @@ private: void stopMusicTrack(); int musicUpdate(int forceRestart); + void fadeOutMusic(int ticks); void snd_playVoiceFile(int) {} @@ -86,7 +95,7 @@ private: void initMainMenu(); void uninitMainMenu(); - Movie *_menuAnim; + WSAMovieV2 *_menuAnim; MainMenu *_menu; // game speed @@ -122,6 +131,7 @@ private: int16 xPos3, yPos3; int16 width, height; int16 width2, height2; + uint16 palette; AnimObj *nextObject; }; @@ -130,6 +140,26 @@ private: void clearAnimObjects(); + AnimObj *_animList; + bool _drawNoShapeFlag; + AnimObj *initAnimList(AnimObj *list, AnimObj *entry); + AnimObj *addToAnimListSorted(AnimObj *list, AnimObj *entry); + AnimObj *deleteAnimListEntry(AnimObj *list, AnimObj *entry); + + void animSetupPaletteEntry(AnimObj *anim); + + void restorePage3(); + + void drawAnimObjects(); + void drawSceneAnimObject(AnimObj *obj, int x, int y, int drawLayer); + void drawCharacterAnimObject(AnimObj *obj, int x, int y, int drawLayer); + + void refreshAnimObjects(int force); + void refreshAnimObjectsIfNeed(); + + bool _loadingState; + void updateCharacterAnim(int charId); + // interface uint8 *_interface; uint8 *_interfaceCommandLine; @@ -137,6 +167,14 @@ private: void loadInterfaceShapes(); void loadInterface(); + void showMessage(const char *string, uint8 c0, uint8 c1); + void restoreCommandLine(); + + int _commandLineY; + const char *_shownMessage; + bool _restoreCommandLine; + bool _inventoryState; + // translation stuff uint8 *_scoreFile; uint8 *_cCodeFile; @@ -144,6 +182,7 @@ private: uint8 *_itemFile; uint8 *_actorFile; uint32 _actorFileSize; + uint8 *_sceneStrings; // items uint8 *_itemBuffer1; @@ -151,11 +190,16 @@ private: void initItems(); + // -> hand item + int _itemInHand; + int _handItemSet; + // shapes typedef Common::HashMap<int, uint8*> ShapeMap; ShapeMap _gameShapes; void addShapeToPool(const uint8 *data, int realIndex, int shape); + uint8 *getShapePtr(int shape) const { return _gameShapes[shape]; } void initMouseShapes(); @@ -190,6 +234,9 @@ private: WSAMovieV2 *_sceneAnimMovie[16]; uint8 *_sceneShapes[20]; + void freeSceneShapes(); + void freeSceneAnims(); + // voice int _currentTalkFile; void openTalkFile(int file); @@ -204,6 +251,51 @@ private: SceneDesc *_sceneList; uint16 _sceneExit1, _sceneExit2, _sceneExit3, _sceneExit4; + int _sceneEnterX1, _sceneEnterY1; + int _sceneEnterX2, _sceneEnterY2; + int _sceneEnterX3, _sceneEnterY3; + int _sceneEnterX4, _sceneEnterY4; + int _specialExitCount; + uint16 _specialExitTable[25]; + + bool _noScriptEnter; + void enterNewScene(uint16 scene, int facing, int unk1, int unk2, int unk3); + void enterNewSceneUnk1(int facing, int unk1, int unk2); + void enterNewSceneUnk2(int unk1); + int _enterNewSceneLock; + + void unloadScene(); + + void loadScenePal(); + void loadSceneMsc(); + void initSceneScript(int unk1); + void initSceneAnims(int unk1); + void initSceneScreen(int unk1); + + bool _noStartupChat; + void runSceneScript4(int unk1); + void runSceneScript8(); + + int _sceneMinY, _sceneMaxY; + int _maskPageMinY, _maskPageMaxY; + + ScriptState _sceneScriptState; + ScriptData _sceneScriptData; + WSAMovieV2 *_wsaSlots[10]; + + bool _sceneSpecialScriptState[10]; + ScriptState _sceneSpecialScripts[10]; + uint32 _sceneSpecialScriptsTimer[10]; + + int8 _sceneDatPalette[45]; + int8 _sceneDatLayerTable[15]; + + int getDrawLayer(int x, int y); + + int getScale(int x, int y); + int _scaleTable[15]; + + bool _unkSceneScreenFlag1; // items struct Item { @@ -237,6 +329,27 @@ private: }; Character _mainCharacter; + int _mainCharX, _mainCharY; + int _charScale; + + void moveCharacter(int facing, int x, int y); + + void updateCharPosWithUpdate(); + void updateCharPos(uint8 *table, int force); + + uint32 _updateCharPosNextUpdate; + static const int8 _updateCharPosXTable[]; + static const int8 _updateCharPosYTable[]; + + void updateCharAnimFrame(int character, uint8 *table); + int8 _characterAnimTable[2]; + static const uint8 _characterFrameTable[]; + + bool _overwriteSceneFacing; + + void updateCharPal(int unk1); + int _lastCharPalLayer; + bool _charPalUpdate; // unk uint8 *_unkBuffer1040Bytes; @@ -245,6 +358,8 @@ private: uint8 *_gfxBackUpRect; uint8 *_paletteOverlay; + int _unk3, _unk4; + void loadCostPal(); void loadShadowShape(); void loadExtrasShapes(); @@ -261,6 +376,10 @@ private: int o3_getHiddenItemsEntry(ScriptState *script); int o3_dummy(ScriptState *script); + // misc + TextDisplayer_v3 *_text; + bool _wsaPlayingVQA; + // resource specific private: static const char *_languageExtension[]; diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index e598881ce5..b2e011828c 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -23,6 +23,7 @@ MODULE_OBJS := \ scene.o \ scene_v1.o \ scene_v2.o \ + scene_v3.o \ screen.o \ screen_v1.o \ screen_v2.o \ @@ -45,6 +46,7 @@ MODULE_OBJS := \ text.o \ text_v1.o \ text_v2.o \ + text_v3.o \ timer.o \ timer_v1.o \ timer_v2.o \ diff --git a/engines/kyra/scene_v3.cpp b/engines/kyra/scene_v3.cpp new file mode 100644 index 0000000000..66ad58d3ef --- /dev/null +++ b/engines/kyra/scene_v3.cpp @@ -0,0 +1,647 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_v3.h" +#include "kyra/screen_v3.h" +#include "kyra/wsamovie.h" +#include "kyra/sound.h" + +namespace Kyra { + +void KyraEngine_v3::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2, int unk3) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::enterNewScene('%d, %d, %d, %d, %d)", sceneId, facing, unk1, unk2, unk3); + ++_enterNewSceneLock; + _screen->hideMouse(); + + showMessage(0, 0xF0, 0xF0); + if (_inventoryState) { + //XXX hideInventory(); + musicUpdate(0); + } + + musicUpdate(0); + //XXX + musicUpdate(0); + + if (!unk3) { + //XXX + musicUpdate(0); + } + + if (unk1) { + int x = _mainCharacter.x1; + int y = _mainCharacter.y1; + + switch (facing) { + case 0: + y -= 6; + break; + + case 2: + x = 343; + break; + + case 4: + y = 191; + break; + + case 6: + x = -24; + break; + } + + musicUpdate(0); + moveCharacter(facing, x, y); + } + + musicUpdate(0); + uint32 waitUntilTimer = 0; + bool newSoundFile = false; + if (_curMusicTrack != _sceneList[sceneId].sound) { + fadeOutMusic(60); + waitUntilTimer = _system->getMillis() + 60 * _tickLength; + newSoundFile = true; + } + + //XXX + + if (!unk3) { + _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); + _scriptInterpreter->startScript(&_sceneScriptState, 5); + while (_scriptInterpreter->validScript(&_sceneScriptState)) { + _scriptInterpreter->runScript(&_sceneScriptState); + musicUpdate(0); + } + } + + musicUpdate(0); + + for (int i = 0; i < 10; ++i) + _wsaSlots[i]->close(); + + musicUpdate(0); + + _specialExitCount = 0; + Common::set_to(_specialExitTable, _specialExitTable+ARRAYSIZE(_specialExitTable), 0xFFFF); + + musicUpdate(0); + + _mainCharacter.sceneId = sceneId; + _sceneList[sceneId].flags &= ~1; + musicUpdate(0); + unloadScene(); + musicUpdate(0); + //XXX resetMaskPage(); + + for (int i = 0; i < 4; ++i) { + if (i == _musicSoundChannel || i == _fadeOutMusicChannel) + _soundDigital->stopSound(i); + } + _fadeOutMusicChannel = -1; + musicUpdate(0); + loadScenePal(); + musicUpdate(0); + + if (queryGameFlag(0x1D9)) { + //XXX VQA code here + } + + musicUpdate(0); + loadSceneMsc(); + musicUpdate(0); + _sceneExit1 = _sceneList[sceneId].exit1; + _sceneExit2 = _sceneList[sceneId].exit2; + _sceneExit3 = _sceneList[sceneId].exit3; + _sceneExit4 = _sceneList[sceneId].exit4; + + while (_system->getMillis() > waitUntilTimer) + _system->delayMillis(10); + + musicUpdate(0); + initSceneScript(unk3); + musicUpdate(0); + + if (_overwriteSceneFacing) { + facing = _mainCharacter.facing; + _overwriteSceneFacing = false; + } + + enterNewSceneUnk1(facing, unk2, unk3); + musicUpdate(0); + //XXX setCommandLineRestoreTimer(-1); + _sceneScriptState.regs[3] = 1; + //XXX enterNewSceneUnk1(); + if (queryGameFlag(0)) { + _runFlag = false; + } else { + if (!--_enterNewSceneLock) + _unkInputFlag = false; + //XXX + if (_itemInHand <= 0) { + _itemInHand = -1; + _handItemSet = -1; + _screen->setMouseCursor(0, 0, _gameShapes[0]); + } + + Common::Point pos = getMousePos(); + if (pos.y > 187) + setMousePos(pos.x, 179); + } + _screen->showMouse(); +} + +void KyraEngine_v3::enterNewSceneUnk1(int facing, int unk1, int unk2) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::enterNewSceneUnk1(%d, %d, %d)", facing, unk1, unk2); + int x = 0, y = 0; + int x2 = 0, y2 = 0; + bool needProc = true; + + if (_mainCharX == -1 && _mainCharY == -1) { + switch (facing+1) { + case 1: case 2: case 8: + x2 = _sceneEnterX3; + y2 = _sceneEnterY3; + break; + + case 3: + x2 = _sceneEnterX4; + y2 = _sceneEnterY4; + break; + + case 4: case 5: case 6: + x2 = _sceneEnterX1; + y2 = _sceneEnterY1; + break; + + case 7: + x2 = _sceneEnterX2; + y2 = _sceneEnterY2; + break; + + default: + x2 = y2 = -1; + break; + } + + if (x2 >= 316) + x2 = 312; + if (y2 >= 185) + y2 = 183; + if (x2 <= 4) + x2 = 8; + } + + if (_mainCharX >= 0) { + x = x2 = _mainCharX; + needProc = false; + } + + if (_mainCharY >= 0) { + y = y2 = _mainCharY; + needProc = false; + } + + _mainCharX = _mainCharY = -1; + + if (unk1 && needProc) { + x = x2; + y = y2; + + switch (facing) { + case 0: + y2 = 191; + break; + + case 2: + x2 = -24; + break; + + case 4: + y2 = y - 4; + break; + + case 6: + x2 = 343; + break; + + default: + break; + } + } + + x2 &= ~3; + x &= ~3; + y2 &= ~1; + y &= ~1; + + _mainCharacter.facing = facing; + _mainCharacter.x1 = _mainCharacter.x2 = x2; + _mainCharacter.y1 = _mainCharacter.y2 = y2; + initSceneAnims(unk2); + + if (_mainCharacter.sceneId == 9 && _soundDigital->isPlaying(_musicSoundChannel)) + playMusicTrack(_sceneList[_mainCharacter.sceneId].sound, 0); + if (!unk2) + playMusicTrack(_sceneList[_mainCharacter.sceneId].sound, 0); + + if (unk1 && !unk2 && _mainCharacter.animFrame != 87) + moveCharacter(facing, x, y); +} + +void KyraEngine_v3::enterNewSceneUnk2(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::enterNewSceneUnk2(%d)", unk1); + _unk3 = -1; + if (_mainCharX == -1 && _mainCharY == -1) { + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + updateCharacterAnim(0); + refreshAnimObjectsIfNeed(); + } + + if (!unk1) { + runSceneScript4(0); + //malcolmSceneStartupChat(); + } + + _unk4 = 0; + _unk3 = -1; +} + +void KyraEngine_v3::unloadScene() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::unloadScene()"); + delete [] _sceneStrings; + _sceneStrings = 0; + musicUpdate(0); + _scriptInterpreter->unloadScript(&_sceneScriptData); + musicUpdate(0); + freeSceneShapes(); + musicUpdate(0); + freeSceneAnims(); + musicUpdate(0); +} + +void KyraEngine_v3::freeSceneShapes() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::freeSceneShapes()"); + for (uint i = 0; i < ARRAYSIZE(_sceneShapes); ++i) { + delete [] _sceneShapes[i]; + _sceneShapes[i] = 0; + } +} + +void KyraEngine_v3::freeSceneAnims() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::freeSceneAnims()"); + for (int i = 0; i < 16; ++i) { + _sceneAnims[i].flags = 0; + _sceneAnimMovie[i]->close(); + } +} + +void KyraEngine_v3::loadScenePal() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::loadScenePal()"); + char filename[16]; + memcpy(_screen->getPalette(2), _screen->getPalette(0), 768); + strcpy(filename, _sceneList[_mainCharacter.sceneId].filename1); + strcat(filename, ".COL"); + + _screen->loadBitmap(filename, 3, 3, 0); + memcpy(_screen->getPalette(2), _screen->getCPagePtr(3), 432); + memset(_screen->getPalette(2), 0, 3); + + for (int i = 144; i <= 167; ++i) { + uint8 *palette = _screen->getPalette(2) + i * 3; + palette[0] = palette[2] = 63; + palette[1] = 0; + } + + _screen->generateOverlay(_screen->getPalette(2), _paletteOverlay, 0xF0, 0x19); + + uint8 *palette = _screen->getPalette(2) + 432; + const uint8 *costPal = _costPalBuffer + _malcolmShapes * 72; + memcpy(palette, costPal, 24*3); +} + +void KyraEngine_v3::loadSceneMsc() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::loadSceneMsc()"); + char filename[16]; + strcpy(filename, _sceneList[_mainCharacter.sceneId].filename1); + strcat(filename, ".MSC"); + + Common::SeekableReadStream *stream = _res->getFileStream(filename); + assert(stream); + int16 minY = 0, height = 0; + minY = stream->readSint16LE(); + height = stream->readSint16LE(); + delete stream; + stream = 0; + musicUpdate(0); + _maskPageMinY = minY; + _maskPageMaxY = minY + height - 1; + + _screen->setShapePages(3, 5); + + musicUpdate(0); + _screen->loadBitmap(filename, 5, 5, 0, true); + + // HACK + uint8 data[320*200]; + _screen->copyRegionToBuffer(5, 0, 0, 320, 200, data); + _screen->fillRect(0, 0, 319, _maskPageMinY - 1, 0xFF, 5); + _screen->copyBlockToPage(5, 0, _maskPageMinY, 320, height, data); + _screen->fillRect(0, _maskPageMaxY + 1, 319, 199, 0xFF, 5); + + musicUpdate(0); +} + +void KyraEngine_v3::initSceneScript(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::initSceneScript(%d)", unk1); + const SceneDesc &scene = _sceneList[_mainCharacter.sceneId]; + musicUpdate(0); + + char filename[16]; + strcpy(filename, scene.filename1); + strcat(filename, ".DAT"); + + Common::SeekableReadStream *stream = _res->getFileStream(filename); + assert(stream); + stream->seek(2, SEEK_CUR); + + byte scaleTable[15]; + stream->read(scaleTable, 15); + stream->read(_sceneDatPalette, 45); + stream->read(_sceneDatLayerTable, 15); + int16 shapesCount = stream->readSint16LE(); + + for (int i = 0; i < 15; ++i) + _scaleTable[i] = (uint16(scaleTable[i]) << 8) / 100; + + if (shapesCount > 0) { + strcpy(filename, scene.filename1); + strcat(filename, "9.CPS"); + musicUpdate(0); + _screen->loadBitmap(filename, 3, 3, 0); + int pageBackUp = _screen->_curPage; + _screen->_curPage = 2; + for (int i = 0; i < shapesCount; ++i) { + int16 x = stream->readSint16LE(); + int16 y = stream->readSint16LE(); + int16 w = stream->readSint16LE(); + int16 h = stream->readSint16LE(); + _sceneShapes[i] = _screen->encodeShape(x, y, w, h, 0); + assert(_sceneShapes[i]); + musicUpdate(0); + } + _screen->_curPage = pageBackUp; + musicUpdate(0); + } + musicUpdate(0); + + strcpy(filename, scene.filename1); + strcat(filename, ".CPS"); + _screen->loadBitmap(filename, 3, 3, 0); + musicUpdate(0); + + Common::set_to(_sceneSpecialScriptState, _sceneSpecialScriptState+ARRAYSIZE(_sceneSpecialScriptState), false); + _sceneEnterX1 = 160; + _sceneEnterY1 = 0; + _sceneEnterX2 = 296; + _sceneEnterY2 = 93; + _sceneEnterX3 = 160; + _sceneEnterY3 = 171; + _sceneEnterX4 = 24; + _sceneEnterY4 = 93; + _sceneMinY = 0; + _sceneMaxY = 319; + + _scriptInterpreter->initScript(&_sceneScriptState, &_sceneScriptData); + strcpy(filename, scene.filename2); + strcat(filename, ".EMC"); + musicUpdate(0); + _scriptInterpreter->loadScript(filename, &_sceneScriptData, &_opcodes); + + strcpy(filename, scene.filename1); + strcat(filename, "."); + loadLanguageFile(filename, _sceneStrings); + musicUpdate(0); + + runSceneScript8(); + _scriptInterpreter->startScript(&_sceneScriptState, 0); + _sceneScriptState.regs[0] = _mainCharacter.sceneId; + _sceneScriptState.regs[5] = unk1; + while (_scriptInterpreter->validScript(&_sceneScriptState)) + _scriptInterpreter->runScript(&_sceneScriptState); + + _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _gamePlayBuffer); + musicUpdate(0); + + for (int i = 0; i < 10; ++i) { + _scriptInterpreter->initScript(&_sceneSpecialScripts[i], &_sceneScriptData); + _scriptInterpreter->startScript(&_sceneSpecialScripts[i], i+9); + musicUpdate(0); + _sceneSpecialScriptsTimer[i] = 0; + } + + _sceneEnterX1 &= ~3; + _sceneEnterY1 &= ~1; + _sceneEnterX2 &= ~3; + _sceneEnterY2 &= ~1; + _sceneEnterX3 &= ~3; + _sceneEnterY3 &= ~1; + _sceneEnterX4 &= ~3; + _sceneEnterY4 &= ~1; + musicUpdate(0); +} + +void KyraEngine_v3::initSceneAnims(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::initSceneAnims(%d)", unk1); + for (int i = 0; i < 67; ++i) + _animObjects[i].enabled = false; + + AnimObj *obj = &_animObjects[0]; + + if (_mainCharacter.animFrame != 87 && !unk1) + _mainCharacter.animFrame = _characterFrameTable[_mainCharacter.facing]; + + obj->enabled = true; + obj->xPos1 = _mainCharacter.x1; + obj->yPos1 = _mainCharacter.y1; + obj->shapePtr = getShapePtr(_mainCharacter.animFrame); + obj->shapeIndex2 = obj->shapeIndex = _mainCharacter.animFrame; + obj->xPos2 = _mainCharacter.x1; + obj->yPos2 = _mainCharacter.y1; + _charScale = getScale(_mainCharacter.x1, _mainCharacter.y1); + obj->xPos3 = obj->xPos2 += (_malcolmShapeXOffset * _charScale) >> 8; + obj->yPos3 = obj->yPos2 += (_malcolmShapeYOffset * _charScale) >> 8; + _mainCharacter.x3 = _mainCharacter.x1 - (_charScale >> 4) - 1; + _mainCharacter.y3 = _mainCharacter.y1 - (_charScale >> 6) - 1; + obj->needRefresh = true; + _animList = 0; + + for (int i = 0; i < 16; ++i) { + const SceneAnim &anim = _sceneAnims[i]; + obj = &_animObjects[i+1]; + obj->enabled = false; + obj->needRefresh = false; + + if (anim.flags & 1) { + obj->enabled = true; + obj->needRefresh = true; + } + + obj->unk8 = (anim.flags & 0x20) ? 1 : 0; + obj->flags = (anim.flags & 0x10) ? 0x800 : 0; + if (anim.flags & 2) + obj->flags |= 1; + + obj->xPos1 = anim.x; + obj->yPos1 = anim.y; + + if ((anim.flags & 4) && anim.shapeIndex != 0xFFFF) + obj->shapePtr = _sceneShapes[anim.shapeIndex]; + else + obj->shapePtr = 0; + + if (anim.flags & 8) { + obj->shapeIndex3 = anim.shapeIndex; + obj->animNum = i; + } else { + obj->shapeIndex3 = 0xFFFF; + obj->animNum = 0xFFFF; + } + + obj->xPos3 = obj->xPos2 = anim.x2; + obj->yPos3 = obj->yPos3 = anim.y2; + obj->width = anim.width; + obj->height = anim.height; + obj->width2 = obj->height2 = anim.specialSize; + + if (anim.flags & 1) { + if (_animList) + _animList = addToAnimListSorted(_animList, obj); + else + _animList = initAnimList(_animList, obj); + } + } + + if (_animList) + _animList = addToAnimListSorted(_animList, &_animObjects[0]); + else + _animList = initAnimList(_animList, &_animObjects[0]); + + for (int i = 0; i < 50; ++i) { + obj = &_animObjects[i+17]; + const Item &item = _itemList[i]; + if (item.id != 0xFFFF && item.sceneId == _mainCharacter.sceneId) { + obj->xPos1 = item.x; + obj->yPos1 = item.y; + animSetupPaletteEntry(obj); + obj->shapePtr = 0; + obj->shapeIndex = obj->shapeIndex2 = item.id + 248; + obj->xPos2 = item.x; + obj->yPos2 = item.y; + + int scale = getScale(obj->xPos1, obj->yPos1); + const uint8 *shape = getShapePtr(obj->shapeIndex); + obj->xPos3 = obj->xPos2 -= (_screen->getShapeScaledWidth(shape, scale) >> 1); + obj->yPos3 = obj->yPos2 -= _screen->getShapeScaledHeight(shape, scale) - 1; + obj->enabled = true; + obj->needRefresh = true; + + if (_animList) + _animList = addToAnimListSorted(_animList, obj); + else + _animList = initAnimList(_animList, obj); + } else { + obj->enabled = false; + obj->needRefresh = false; + } + } + + for (int i = 0; i < 67; ++i) + _animObjects[i].needRefresh = _animObjects[i].enabled; + + restorePage3(); + drawAnimObjects(); + _screen->hideMouse(); + initSceneScreen(unk1); + _screen->showMouse(); + refreshAnimObjects(0); +} + +void KyraEngine_v3::initSceneScreen(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::initSceneScreen(%d)", unk1); + _screen->copyBlockToPage(2, 0, 188, 320, 12, _interfaceCommandLine); + + if (_unkSceneScreenFlag1) { + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); + return; + } + + if (_noScriptEnter) { + memset(_screen->getPalette(0), 0, 432); + if (!_wsaPlayingVQA) + _screen->setScreenPalette(_screen->getPalette(0)); + } + + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); + + if (_noScriptEnter) { + if (!_wsaPlayingVQA) + _screen->setScreenPalette(_screen->getPalette(2)); + memcpy(_screen->getPalette(0), _screen->getPalette(2), 432); + if (_wsaPlayingVQA) { + _screen->fadeFromBlack(0x3C); + _wsaPlayingVQA = false; + } + } + + updateCharPal(0); + + //XXX when loading from main menu +} + +void KyraEngine_v3::runSceneScript4(int unk1) { + debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript4(%d)", unk1); + _sceneScriptState.regs[4] = _itemInHand; + _sceneScriptState.regs[5] = unk1; + _sceneScriptState.regs[3] = 0; + _noStartupChat = false; + + _scriptInterpreter->startScript(&_sceneScriptState, 4); + while (_scriptInterpreter->validScript(&_sceneScriptState)) + _scriptInterpreter->runScript(&_sceneScriptState); + + if (_sceneScriptState.regs[3]) + _noStartupChat = true; +} + +void KyraEngine_v3::runSceneScript8() { + debugC(9, kDebugLevelMain, "KyraEngine_v3::runSceneScript8()"); + _scriptInterpreter->startScript(&_sceneScriptState, 8); + while (_scriptInterpreter->validScript(&_sceneScriptState)) { + musicUpdate(0); + _scriptInterpreter->runScript(&_sceneScriptState); + } +} + +} // end of namespace Kyra diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 85a4ff79bc..cf1e068e9e 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -2579,8 +2579,8 @@ void Screen::shakeScreen(int times) { } } -void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData) { - debugC(9, kDebugLevelScreen, "KyraEngine::loadBitmap('%s', %d, %d, %p)", filename, tempPage, dstPage, (void *)palData); +void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData, bool skip) { + debugC(9, kDebugLevelScreen, "KyraEngine::loadBitmap('%s', %d, %d, %p, %d)", filename, tempPage, dstPage, (void *)palData, skip); uint32 fileSize; uint8 *srcData = _vm->resource()->fileData(filename, &fileSize); @@ -2588,6 +2588,9 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 * warning("couldn't load bitmap: '%s'", filename); return; } + + if (skip) + srcData += 4; const char *ext = filename + strlen(filename) - 3; uint8 compType = srcData[2]; @@ -2626,6 +2629,9 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 * Screen::convertAmigaGfx(dstData, 320, 200, false); } + if (skip) + srcData -= 4; + delete [] srcData; } diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index c746c41c5d..a0403e6c68 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -193,7 +193,7 @@ public: void rectClip(int &x, int &y, int w, int h); // misc - void loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData); + void loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData, bool skip=false); bool loadPalette(const char *filename, uint8 *palData); void loadPalette(const byte *data, uint8 *palData, int bytes); diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 1279a23709..eb4466fbc4 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -1987,6 +1987,18 @@ const KyraEngine_v3::ShapeDesc KyraEngine_v3::_shapeDescs[] = { const int KyraEngine_v3::_shapeDescsSize = ARRAYSIZE(KyraEngine_v3::_shapeDescs); +const int8 KyraEngine_v3::_updateCharPosXTable[] = { + 0, 4, 4, 4, 0, -4, -4, -4 +}; + +const int8 KyraEngine_v3::_updateCharPosYTable[] = { + -2, -2, 0, 2, 2, 2, 0, -2 +}; + +const uint8 KyraEngine_v3::_characterFrameTable[] = { + 0x36, 0x35, 0x35, 0x33, 0x32, 0x32, 0x34, 0x34 +}; + } // End of namespace Kyra diff --git a/engines/kyra/text.h b/engines/kyra/text.h index 5d9179b1ee..d7cc5e9f81 100644 --- a/engines/kyra/text.h +++ b/engines/kyra/text.h @@ -52,7 +52,7 @@ public: void printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage); void printIntroTextMessage(const char *text, int x, int y, uint8 col1, uint8 col2, uint8 col3, int dstPage, Screen::FontId font=Screen::FID_8_FNT); - void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font=Screen::FID_8_FNT); + virtual void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font=Screen::FID_8_FNT); void printCharacterText(const char *text, int8 charNum, int charX); uint16 _talkMessageY; diff --git a/engines/kyra/text_v3.cpp b/engines/kyra/text_v3.cpp new file mode 100644 index 0000000000..b02599faa4 --- /dev/null +++ b/engines/kyra/text_v3.cpp @@ -0,0 +1,48 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/text_v3.h" + +#include "kyra/screen_v3.h" + +namespace Kyra { + +TextDisplayer_v3::TextDisplayer_v3(KyraEngine_v3 *vm, Screen_v3 *screen) + : TextDisplayer(vm, screen), _vm(vm), _screen(screen) { +} + +void TextDisplayer_v3::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font) { + debugC(9, kDebugLevelMain, "TextDisplayer_v3::printText('%s', %d, %d, %d, %d, %d)", str, x, y, c0, c1, c2); + uint8 colorMap[] = { 0, 255, 240, 240 }; + colorMap[3] = c1; + _screen->setTextColor(colorMap, 0, 3); + Screen::FontId curFont = _screen->setFont(font); + _screen->_charWidth = -2; + _screen->printText(str, x, y, c0, c2); + _screen->_charWidth = 0; + _screen->setFont(curFont); +} + +} // end of namespace Kyra diff --git a/engines/kyra/text_v3.h b/engines/kyra/text_v3.h new file mode 100644 index 0000000000..c8c9be8e46 --- /dev/null +++ b/engines/kyra/text_v3.h @@ -0,0 +1,47 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_TEXT_V3_H +#define KYRA_TEXT_V3_H + +#include "kyra/text.h" + +#include "kyra/kyra_v3.h" + +namespace Kyra { + +class TextDisplayer_v3 : public TextDisplayer { +public: + TextDisplayer_v3(KyraEngine_v3 *vm, Screen_v3 *screen); + + void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font=Screen::FID_8_FNT); +protected: + KyraEngine_v3 *_vm; + Screen_v3 *_screen; +}; + +} // end of namespace Kyra + +#endif |