From f065524949ff2919a692dbc1ae42ea56fe3f61ac Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Sat, 14 Feb 2009 00:51:07 +0000 Subject: LOL: - implemented some input code - you can walk around now (not very far though, since doors don't work yet). Keyboard control is still missing - processButtonList isn't really implemented yet for LOL. I'll still have to check which features are needed here. svn-id: r36320 --- engines/kyra/gui_lol.cpp | 286 ++++++++++++++++++++++++---- engines/kyra/kyra_v1.cpp | 9 +- engines/kyra/lol.cpp | 91 +++++---- engines/kyra/lol.h | 115 ++++++++--- engines/kyra/resource.h | 24 ++- engines/kyra/scene_lol.cpp | 450 ++++++++++++++++++++++++++++++++++++++++---- engines/kyra/screen_lol.cpp | 276 +++++++++++++++++++++++++-- engines/kyra/screen_lol.h | 15 +- engines/kyra/script_lol.cpp | 41 ++-- engines/kyra/staticres.cpp | 201 ++++++++++++++++++-- engines/kyra/text_lol.cpp | 66 ++++++- engines/kyra/text_lol.h | 4 +- 12 files changed, 1386 insertions(+), 192 deletions(-) (limited to 'engines') diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp index 112bc6396f..2963d330d0 100644 --- a/engines/kyra/gui_lol.cpp +++ b/engines/kyra/gui_lol.cpp @@ -124,6 +124,10 @@ void LoLEngine::gui_drawScroll() { } } +void LoLEngine::gui_highlightSelectedSpell(int unk) { + +} + void LoLEngine::gui_drawAllCharPortraitsWithStats() { int numChars = countActiveCharacters(); if (!numChars) @@ -364,7 +368,7 @@ int LoLEngine::gui_enableControls() { if (!_hideControls) { for (int i = 76; i < 85; i++) - gui_disableArrowButton(i, 2); + gui_toggleButtonDisplayMode(i, 2); } gui_toggleFightButtons(false); @@ -380,14 +384,14 @@ int LoLEngine::gui_disableControls(int controlMode) { gui_toggleFightButtons(true); for (int i = 76; i < 85; i++) - gui_disableArrowButton(i, ((controlMode & 2) && (i > 78)) ? 2 : 3); + gui_toggleButtonDisplayMode(i, ((controlMode & 2) && (i > 78)) ? 2 : 3); return 1; } -void LoLEngine::gui_disableArrowButton(int shapeIndex, int mode) { - static const int16 arrowButtonX[] = { 0x000C, 0x0021, 0x0122, 0x000C, 0x0021, 0x0036, 0x000C, 0x0021, 0x0036 }; - static const int16 arrowButtonY[] = { 0x00B4, 0x00B4, 0x0020, 0x0084, 0x0084, 0x0084, 0x0096, 0x0096, 0x0096 }; +void LoLEngine::gui_toggleButtonDisplayMode(int shapeIndex, int mode) { + static const int16 buttonX[] = { 0x0056, 0x0128, 0x000C, 0x0021, 0x0122, 0x000C, 0x0021, 0x0036, 0x000C, 0x0021, 0x0036 }; + static const int16 buttonY[] = { 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x0020, 0x0084, 0x0084, 0x0084, 0x0096, 0x0096, 0x0096 }; if (shapeIndex == 78 && !(_screen->_drawGuiFlag & 0x1000)) return; @@ -396,12 +400,12 @@ void LoLEngine::gui_disableArrowButton(int shapeIndex, int mode) { return; if (mode == 0) - shapeIndex = _lastArrowButtonShape; + shapeIndex = _lastButtonShape; int pageNum = 0; - int16 x1 = arrowButtonX[shapeIndex - 76]; - int16 y1 = arrowButtonY[shapeIndex - 76]; + int16 x1 = buttonX[shapeIndex - 74]; + int16 y1 = buttonY[shapeIndex - 74]; int16 x2 = 0; int16 y2 = 0; uint32 t = 0; @@ -409,25 +413,25 @@ void LoLEngine::gui_disableArrowButton(int shapeIndex, int mode) { switch (mode) { case 1: mode = 0x100; - _lastArrowButtonShape = shapeIndex; + _lastButtonShape = shapeIndex; break; case 0: - if (!_lastArrowButtonShape) + if (!_lastButtonShape) return; t = _system->getMillis(); - if (_arrowButtonTimer > t) - delay(_arrowButtonTimer - t); + if (_buttonPressTimer > t) + delay(_buttonPressTimer - t); case 2: mode = 0; - _lastArrowButtonShape = 0; + _lastButtonShape = 0; break; case 3: mode = 0; - _lastArrowButtonShape = 0; + _lastButtonShape = 0; pageNum = 6; x2 = x1; @@ -442,17 +446,20 @@ void LoLEngine::gui_disableArrowButton(int shapeIndex, int mode) { _screen->drawShape(pageNum, _gameShapes[shapeIndex], x1, y1, 0, mode, _screen->_paletteOverlay1, 1); - if (pageNum != 6) - return; - - int cp = _screen->setCurPage(6); + if (!pageNum) + _screen->updateScreen(); + + if (pageNum == 6) { + int cp = _screen->setCurPage(6); - _screen->drawGridBox(x1, y1, _gameShapes[shapeIndex][3], _gameShapes[shapeIndex][2], 1); - _screen->copyRegion(x1, y1, x2, y2, _gameShapes[shapeIndex][3], _gameShapes[shapeIndex][2], pageNum, 0, Screen::CR_NO_P_CHECK); + _screen->drawGridBox(x1, y1, _gameShapes[shapeIndex][3], _gameShapes[shapeIndex][2], 1); + _screen->copyRegion(x1, y1, x2, y2, _gameShapes[shapeIndex][3], _gameShapes[shapeIndex][2], pageNum, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); - _screen->setCurPage(cp); + _screen->setCurPage(cp); + } - _arrowButtonTimer = _system->getMillis() + 6 * _tickLength; + _buttonPressTimer = _system->getMillis() + 6 * _tickLength; } void LoLEngine::gui_toggleFightButtons(bool disable) { @@ -481,27 +488,222 @@ void LoLEngine::gui_toggleFightButtons(bool disable) { } } +void LoLEngine::gui_updateInput() { + int inputFlag = checkInput(_activeButtons, true); + removeInputTop(); + + if (inputFlag && _unkCharNum != -1 && !(inputFlag & 0x8800)) { + gui_enableDefaultPlayfieldButtons(); + _characters[_unkCharNum].flags &= 0xffef; + gui_drawCharPortraitWithStats(_unkCharNum); + //processMouseButtonEvent(inputFlag); + _unkCharNum = -1; + inputFlag = 0; + } + + if (inputFlag == 1) { + if (_weaponsDisabled || _availableSpells[1] == -1) + return; + + gui_highlightSelectedSpell(0); + if (_availableSpells[++_selectedSpell] == -1) + _selectedSpell = 0; + gui_highlightSelectedSpell(1); + + gui_drawAllCharPortraitsWithStats(); + } else if (inputFlag == 3) { + // TODO + //processPortraitGuiText + } else { + snd_dialogueSpeechUpdate(1); + } +} + +void LoLEngine::gui_enableDefaultPlayfieldButtons() { + gui_resetButtonList(); + gui_initButtonsFromList(_buttonList1); + gui_initCharacterControlButtons(7, 44); + gui_initCharacterControlButtons(11, 44); + gui_initCharacterControlButtons(17, 0); + gui_initCharacterControlButtons(29, 0); + gui_initCharacterControlButtons(25, 33); + + if (_screen->_drawGuiFlag & 0x2000) + gui_initMagicScrollButtons(); +} + +void LoLEngine::gui_enableSequenceButtons(int x, int y, int w, int h, int enableFlags) { + gui_resetButtonList(); + + _sceneWindowButton.x = x; + _sceneWindowButton.y = y; + _sceneWindowButton.w = w; + _sceneWindowButton.h = h; + + gui_initButtonsFromList(_buttonList3); + + if (enableFlags & 1) + gui_initButtonsFromList(_buttonList4); + + if (enableFlags & 2) + gui_initButtonsFromList(_buttonList5); +} + +void LoLEngine::gui_resetButtonList() { + while (_activeButtons) { + Button *n = _activeButtons->nextButton; + delete _activeButtons; + _activeButtons = n; + } + + _activeButtons = 0; +} + +void LoLEngine::gui_initButtonsFromList(const int16 *list) { + while (*list != -1) + gui_initButton(*list++); +} + +void LoLEngine::gui_initCharacterControlButtons(int index, int xOffs) { + int c = countActiveCharacters(); + for (int i = 0; i < c; i++) + gui_initButton(index + i, _activeCharsXpos[i] + xOffs); +} + +void LoLEngine::gui_initMagicScrollButtons() { + +} + +void LoLEngine::gui_initButton(int index, int x) { + Button *b = new Button; + memset (b, 0, sizeof(Button)); + + int cnt = 1; + + if (_activeButtons) { + cnt++; + Button *n = _activeButtons; + + while (n->nextButton) { + n = n->nextButton; + cnt++; + } + + n->nextButton = b; + + } else { + _activeButtons = b; + } + + b->data0Val2 = 0xfe; + b->data0Val3 = 0x01; + b->data1Val2 = 0xfe; + b->data1Val3 = 0x01; + b->data2Val2 = 0xfe; + b->data2Val3 = 0x01; + + b->index = cnt; + b->unk6 = _buttonData[index].clickedShapeId; + b->unk8 = _buttonData[index].unk2; + b->dimTableIndex = _buttonData[index].screenDim; + b->flags = _buttonData[index].buttonflags; + + b->data2Val2 = _buttonData[index].index; + + if (index == 64) { + // scene window button + b->x = _sceneWindowButton.x; + b->y = _sceneWindowButton.y; + b->width = _sceneWindowButton.w - 1; + b->height = _sceneWindowButton.h - 1; + } else { + b->x = x != -1 ? x : _buttonData[index].x; + b->y = _buttonData[index].y; + b->width = _buttonData[index].w - 1; + b->height = _buttonData[index].h - 1; + } + + assignButtonCallback(b, index); +} + int LoLEngine::clickedUpArrow(Button *button) { + if (button->data2Val2 && !(_unkGameFlag & 4)) + return 0; + + moveParty(_currentDirection, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 0, 80); + return 1; } int LoLEngine::clickedDownArrow(Button *button) { + if (button->data2Val2 && !(_unkGameFlag & 4)) + return 0; + + moveParty(_currentDirection ^ 2, 0, 1, 83); + return 1; } int LoLEngine::clickedLeftArrow(Button *button) { + if (button->data2Val2 && !(_unkGameFlag & 4)) + return 0; + + moveParty((_currentDirection - 1) & 3, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 2, 82); + return 1; } int LoLEngine::clickedRightArrow(Button *button) { + if (button->data2Val2 && !(_unkGameFlag & 4)) + return 0; + + moveParty((_currentDirection + 1) & 3, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 3, 84); + return 1; } int LoLEngine::clickedTurnLeftArrow(Button *button) { + if (button->data2Val2 && !(_unkGameFlag & 4)) + return 0; + + gui_toggleButtonDisplayMode(79, 1); + _currentDirection = (--_currentDirection) & 3; + + _sceneDefaultUpdate = 1; + + runSceneScript(_currentBlock, 0x4000); + updatePortraitUnkTimeSub(2, 0); + + if (!_sceneDefaultUpdate) + gui_drawScene(0); + else + movePartySmoothScrollTurnLeft(1); + + gui_toggleButtonDisplayMode(79, 0); + runSceneScript(_currentBlock, 0x10); return 1; } int LoLEngine::clickedTurnRightArrow(Button *button) { + if (button->data2Val2 && !(_unkGameFlag & 4)) + return 0; + + gui_toggleButtonDisplayMode(81, 1); + _currentDirection = (++_currentDirection) & 3; + + _sceneDefaultUpdate = 1; + + runSceneScript(_currentBlock, 0x4000); + updatePortraitUnkTimeSub(2, 0); + + if (!_sceneDefaultUpdate) + gui_drawScene(0); + else + movePartySmoothScrollTurnRight(1); + + gui_toggleButtonDisplayMode(81, 0); + runSceneScript(_currentBlock, 0x10); + return 1; } @@ -554,6 +756,12 @@ int LoLEngine::clickedInventorySlot(Button *button) { } int LoLEngine::clickedInventoryScroll(Button *button) { + int8 dir = (int8) button->data2Val2; + int shp = (dir == 1) ? 75 : 74; + + gui_toggleButtonDisplayMode(shp, 1); + + gui_toggleButtonDisplayMode(shp, 0); return 1; } @@ -561,7 +769,7 @@ int LoLEngine::clickedUnk20(Button *button) { return 1; } -int LoLEngine::clickedUnk21(Button *button) { +int LoLEngine::clickedScene(Button *button) { return 1; } @@ -582,26 +790,34 @@ int LoLEngine::clickedUnk25(Button *button) { } int LoLEngine::clickedOptions(Button *button) { + gui_toggleButtonDisplayMode(76, 1); + + gui_toggleButtonDisplayMode(76, 0); + return 1; } int LoLEngine::clickedRestParty(Button *button) { + gui_toggleButtonDisplayMode(77, 1); + + gui_toggleButtonDisplayMode(77, 0); + return 1; } -int LoLEngine::clickedUnk28(Button *button) { +int LoLEngine::clickedMoneyBox(Button *button) { return 1; } -int LoLEngine::clickedUnk29(Button *button) { +int LoLEngine::clickedCompass(Button *button) { return 1; } -int LoLEngine::clickedUnk30(Button *button) { +int LoLEngine::clickedAutomap(Button *button) { return 1; } -int LoLEngine::clickedUnk31(Button *button) { +int LoLEngine::clickedLamp(Button *button) { return 1; } @@ -615,13 +831,13 @@ GUI_LoL::GUI_LoL(LoLEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) { } int GUI_LoL::processButtonList(Button *list, uint16 inputFlag, int8 mouseWheel) { - if ((inputFlag & 0xFF) == 199) - _pressFlag = true; - else if ((inputFlag & 0xFF) == 200) - _pressFlag = false; + inputFlag &= 0x7fff; int returnValue = 0; while (list) { + bool processMouseClick = (inputFlag == 199 && list->flags & 0x100) || (inputFlag == 299 && list->flags & 0x1000); + bool target = _vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, list->x, list->y, list->x + list->width, list->y + list->height); + /*if (list->flags & 8) { list = list->nextButton; continue; @@ -682,9 +898,15 @@ int GUI_LoL::processButtonList(Button *list, uint16 inputFlag, int8 mouseWheel) processButton(list); _screen->updateScreen(); } + }*/ + if (processMouseClick && target) { + if (list->buttonCallback) { + if ((*list->buttonCallback.get())(list)) + break; + } } - list = list->nextButton;*/ + list = list->nextButton; } if (!returnValue) diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index a5e1e432d0..4278669f33 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -341,8 +341,11 @@ void KyraEngine_v1::updateInput() { while (_eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_KEYDOWN: - if (event.kbd.keycode == '.' || event.kbd.keycode == Common::KEYCODE_ESCAPE) - _eventList.push_back(Event(event, true)); + if (event.kbd.keycode == '.' || event.kbd.keycode == Common::KEYCODE_ESCAPE || + event.kbd.keycode == Common::KEYCODE_SPACE || event.kbd.keycode == Common::KEYCODE_RETURN || + event.kbd.keycode == Common::KEYCODE_UP || event.kbd.keycode == Common::KEYCODE_RIGHT || + event.kbd.keycode == Common::KEYCODE_DOWN || event.kbd.keycode == Common::KEYCODE_LEFT) + _eventList.push_back(Event(event, true)); else if (event.kbd.keycode == 'q' && event.kbd.flags == Common::KBD_CTRL) quitGame(); else @@ -350,6 +353,7 @@ void KyraEngine_v1::updateInput() { break; case Common::EVENT_LBUTTONDOWN: + case Common::EVENT_RBUTTONDOWN: _eventList.push_back(Event(event, true)); break; @@ -358,6 +362,7 @@ void KyraEngine_v1::updateInput() { // fall through case Common::EVENT_LBUTTONUP: + case Common::EVENT_RBUTTONUP: case Common::EVENT_WHEELUP: case Common::EVENT_WHEELDOWN: _eventList.push_back(event); diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 1d3519483a..62c34e0c76 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -40,7 +40,7 @@ namespace Kyra { LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags) { _screen = 0; _gui = 0; - _dlg = 0; + _txt = 0; _tim = 0; switch (_flags.lang) { @@ -91,26 +91,31 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _gameShapeMap = 0; memset(_monsterUnk, 0, 3); + _ingameMT32SoundIndex = _ingameGMSoundIndex = /*_ingameADLSoundIndex =*/ 0; + _charSelection = -1; _characters = 0; _spellProperties = 0; _updateFlags = 0; _selectedSpell = 0; - _updateCharNum = _updateCharV1 = _updateCharV2 = _updateCharV3 = _updateCharV4 = _restorePalette = _hideInventory = 0; + _updateCharNum = _updateCharV1 = _updateCharV2 = _updateCharV3 = _textColourFlag = _hideInventory = 0; + _fadeText = false; _palUpdateTimer = _updatePortraitNext = 0; _lampStatusTimer = 0xffffffff; _weaponsDisabled = false; - _lastArrowButtonShape = 0; - _arrowButtonTimer = 0; + _lastButtonShape = 0; + _buttonPressTimer = 0; _selectedCharacter = 0; _unkFlag = 0; _scriptBoolSkipExec = _sceneUpdateRequired = false; - _unkScriptByte = 0; + _scriptDirection = 0; _currentDirection = 0; _currentBlock = 0; - memset(_scriptExecutedFuncs, 0, 18 * sizeof(uint16)); + memset(_currentBlockPropertyIndex, 0, 18 * sizeof(uint16)); + _scrollSceneBuffer = 0; + _smoothScrollModeNormal = 1; _wllVmpMap = _wllBuffer3 = _wllBuffer4 = _wllWallFlags = 0; _wllShapeMap = 0; _lvlShapeTop = _lvlShapeBottom = _lvlShapeLeftRight = 0; @@ -127,6 +132,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _trueLightTable1 = 0; _levelShapeProperties = 0; _levelShapes = 0; + _scriptAssignedLevelShape = 0; _blockDrawingBuffer = 0; _sceneWindowBuffer = 0; memset (_doorShapes, 0, 2 * sizeof(uint8*)); @@ -137,7 +143,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _cLevelItems = 0; _unkGameFlag = 0; _lastMouseRegion = 0; - _preSeq_X1 = _preSeq_Y1 = _preSeq_X2 = _preSeq_Y2 = 0; + //_preSeq_X1 = _preSeq_Y1 = _preSeq_X2 = _preSeq_Y2 = 0; _dscUnk1 = 0; _dscShapeIndex = 0; @@ -175,7 +181,9 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy memset(_activeTim, 0, 10 * sizeof(TIM*)); memset(_activeVoiceFile, 0, sizeof(_activeVoiceFile)); - //_dlgAnimCallback = &TextDisplayer_LoL::portraitAnimation1; + _buttonData = 0; + _activeButtons = 0; + _buttonList1 = _buttonList2 = _buttonList3 = _buttonList4 = _buttonList5 = _buttonList6 = _buttonList7 = _buttonList8 = 0; } LoLEngine::~LoLEngine() { @@ -187,7 +195,7 @@ LoLEngine::~LoLEngine() { delete _screen; delete _gui; delete _tim; - delete _dlg; + delete _txt; delete[] _itemsInPlay; delete[] _itemProperties; @@ -263,6 +271,8 @@ LoLEngine::~LoLEngine() { delete[] _cLevelItems; delete[] _levelBlockProperties; delete[] _monsterProperties; + delete[] _scrollSceneBuffer; + delete[] _scriptAssignedLevelShape; delete[] _levelFileData; delete[] _vcnExpTable; @@ -291,6 +301,8 @@ LoLEngine::~LoLEngine() { delete[] _ingameSoundList[i]; delete[] _ingameSoundList; } + + gui_resetButtonList(); } Screen *LoLEngine::screen() { @@ -312,12 +324,11 @@ Common::Error LoLEngine::init() { _gui = new GUI_LoL(this); assert(_gui); _gui->initStaticData(); - initButtonList(); _tim = new TIMInterpreter_LoL(this, _screen, _system); assert(_tim); - _dlg = new TextDisplayer_LoL(this, _screen); + _txt = new TextDisplayer_LoL(this, _screen); _screen->setAnimBlockPtr(10000); _screen->setScreenDim(0); @@ -365,6 +376,8 @@ Common::Error LoLEngine::init() { _monsterProperties = new MonsterProperty[5]; memset(_monsterProperties, 0, 5 * sizeof(MonsterProperty)); + _scrollSceneBuffer = new uint8[21120]; + _vcnExpTable = new uint8[128]; for (int i = 0; i < 128; i++) _vcnExpTable[i] = i & 0x0f; @@ -394,6 +407,7 @@ Common::Error LoLEngine::init() { memset(&_scriptData, 0, sizeof(EMCData)); _levelFlagUnk = 0; + _unkCharNum = -1; return Common::kNoError; } @@ -614,8 +628,8 @@ void LoLEngine::startup() { memset(_screen->_currentPalette, 0x3f, 0x180); memcpy(_screen->_currentPalette + 3, tmpPal + 3, 3); memset(_screen->_currentPalette + 0x240, 0x3f, 12); - _screen->generateOverlay(_screen->_currentPalette, _screen->_paletteOverlay1, 1, 6); - _screen->generateOverlay(_screen->_currentPalette, _screen->_paletteOverlay2, 0x90, 0x41); + _screen->generateOverlay(_screen->_currentPalette, _screen->_paletteOverlay1, 1, 96); + _screen->generateOverlay(_screen->_currentPalette, _screen->_paletteOverlay2, 144, 65); memcpy(_screen->_currentPalette, tmpPal, 0x300); delete[] tmpPal; @@ -672,11 +686,13 @@ void LoLEngine::startup() { _loadSuppFilesFlag = 1; - _dlg->setAnimParameters("", 10, 31, 0); - _dlg->setAnimFlag(true); + _txt->setAnimParameters("", 10, 31, 0); + _txt->setAnimFlag(true); _screen->_dimLineCount = 0; + _sound->loadSfxFile("LORESFX"); + setMouseCursorToItemInHand(); } @@ -708,7 +724,7 @@ void LoLEngine::startupNew() { static int selectIds[] = { -9, -1, -8, -5 }; addCharacter(selectIds[_charSelection]); - // TODO + gui_enableDefaultPlayfieldButtons(); loadLevel(1); @@ -743,14 +759,13 @@ void LoLEngine::runLoop() { while (!shouldQuit() && _runFlag) { if (_nextScriptFunc) { - runResidentScript(_nextScriptFunc, 2); + runSceneScript(_nextScriptFunc, 2); _nextScriptFunc = 0; } //processUnkAnimStructs(); //checkFloatingPointerRegions(); - //processCharacters(); - checkInput(0, true); + gui_updateInput(); update(); @@ -781,7 +796,7 @@ void LoLEngine::update() { updateCompass(); snd_characterSpeaking(); - restorePaletteEntry(); + fadeText(); _screen->updateScreen(); } @@ -974,8 +989,8 @@ void LoLEngine::updatePortraits() { } void LoLEngine::updatePortraitUnkTimeSub(int unk1, int unk2) { - if (_updateCharV4 == unk1 || !unk1) { - _restorePalette = 1; + if (_textColourFlag == unk1 || !unk1) { + _fadeText = true; _palUpdateTimer = _system->getMillis(); } @@ -989,7 +1004,7 @@ void LoLEngine::updatePortraitUnkTimeSub(int unk1, int unk2) { _screen->showMouse(); } - _restorePalette = 0; + _fadeText = false; //initGuiUnk(11); } @@ -1045,8 +1060,8 @@ void LoLEngine::initDialogueSequence(int controlMode) { _updateFlags |= 3; - _dlg->setupField(true); - _dlg->expandField(); + _txt->setupField(true); + _txt->expandField(); setupScreenDims(); gui_disableControls(controlMode); } @@ -1073,13 +1088,13 @@ void LoLEngine::unkHideInventory() { removeUnkFlags(2); } -void LoLEngine::gui_prepareForSequence(int x, int y, int w, int h, int unk) { - //resetGuiUnk(x, y, w, h, unk); +void LoLEngine::gui_prepareForSequence(int x, int y, int w, int h, int buttonFlags) { + setSequenceGui(x, y, w, h, buttonFlags); - _preSeq_X1 = x; + /*_preSeq_X1 = x; _preSeq_Y1 = y; _preSeq_X2 = x + w; - _preSeq_Y2 = y + h; + _preSeq_Y2 = y + h;*/ int mouseOffs = _itemInHand ? 10 : 0; _screen->setMouseCursor(mouseOffs, mouseOffs, getItemIconShapePtr(_itemInHand)); @@ -1094,10 +1109,10 @@ void LoLEngine::gui_prepareForSequence(int x, int y, int w, int h, int unk) { void LoLEngine::restoreSceneAfterDialogueSequence(int redraw) { gui_enableControls(); - _dlg->setupField(false); + _txt->setupField(false); _updateFlags &= 0xffdf; - //loadLevel_initGui() + restoreDefaultGui(); for (int i = 0; i < 6; i++) _tim->freeAnimStruct(i); @@ -1115,11 +1130,12 @@ void LoLEngine::restoreSceneAfterDialogueSequence(int redraw) { _hideInventory = 0; } -void LoLEngine::restorePaletteEntry() { - if (!_restorePalette) +void LoLEngine::fadeText() { + if (!_fadeText) return; - _screen->copyColour(192, 252, _system->getMillis() - _palUpdateTimer, 60 * _tickLength); + if (_screen->fadeColour(192, 252, _system->getMillis() - _palUpdateTimer, 60 * _tickLength)) + return; if (_hideInventory) return; @@ -1128,7 +1144,7 @@ void LoLEngine::restorePaletteEntry() { ///initGuiUnk(11); - _restorePalette = 0; + _fadeText = false; } void LoLEngine::updateWsaAnimations() { @@ -1274,6 +1290,11 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) { track = track < _ingameMT32SoundIndexSize ? _ingameMT32SoundIndex[track] - 1 : -1; else if (_sound->getSfxType() == Sound::kMidiGM) track = track < _ingameGMSoundIndexSize ? _ingameGMSoundIndex[track] - 1: -1; + //else if (_sound->getSfxType() == Sound::kAdlib) + // track = track < _ingameADLSoundIndexSize ? _ingameADLSoundIndex[track] - 1: -1; + + if (track == 168) + track = 167; if (track != -1) KyraEngine_v1::snd_playSoundEffect(track); diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 74d3dd96cb..41121a2d93 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -210,14 +210,13 @@ struct CompassDef { struct ButtonDef { uint16 buttonflags; uint8 clickedShapeId; - uint8 unk1; uint16 unk2; int16 x; int16 y; uint16 w; uint16 h; uint16 index; - uint16 flag; + uint16 screenDim; }; class LoLEngine : public KyraEngine_v1 { @@ -351,6 +350,8 @@ private: int _ingameGMSoundIndexSize; const uint8 *_ingameMT32SoundIndex; int _ingameMT32SoundIndexSize; + /*const uint8 *_ingameADLSoundIndex; + int _ingameADLSoundIndexSize;*/ // gui void gui_drawPlayField(); @@ -365,16 +366,17 @@ private: void gui_drawInventoryItem(int index); void gui_drawCompass(); void gui_drawScroll(); + void gui_highlightSelectedSpell(int unk); int gui_enableControls(); int gui_disableControls(int controlMode); - void gui_disableArrowButton(int shapeIndex, int mode); + void gui_toggleButtonDisplayMode(int shapeIndex, int mode); void gui_toggleFightButtons(bool disable); - void gui_prepareForSequence(int x, int y, int w, int h, int unk); + void gui_prepareForSequence(int x, int y, int w, int h, int buttonFlags); bool _weaponsDisabled; - int _lastArrowButtonShape; - uint32 _arrowButtonTimer; + int _lastButtonShape; + uint32 _buttonPressTimer; int _selectedCharacter; int _compassDirection; int _compassUnk; @@ -383,9 +385,19 @@ private: const CompassDef *_compassDefs; int _compassDefsSize; - void initButtonList(); - ButtonDef *_buttonData; - Button *_buttonList; + void gui_updateInput(); + void gui_enableDefaultPlayfieldButtons(); + void gui_enableSequenceButtons(int x, int y, int w, int h, int enableFlags); + + void gui_resetButtonList(); + void gui_initButtonsFromList(const int16 *list); + void gui_initCharacterControlButtons(int index, int xOffs); + void gui_initMagicScrollButtons(); + void gui_initButton(int index, int x = -1); + void assignButtonCallback(Button *button, int index); + + Button *_activeButtons; + ButtonDef _sceneWindowButton; int clickedUpArrow(Button *button); int clickedDownArrow(Button *button); @@ -407,36 +419,55 @@ private: int clickedInventorySlot(Button *button); int clickedInventoryScroll(Button *button); int clickedUnk20(Button *button); - int clickedUnk21(Button *button); + int clickedScene(Button *button); int clickedScroll(Button *button); int clickedUnk23(Button *button); int clickedUnk24(Button *button); int clickedUnk25(Button *button); int clickedOptions(Button *button); int clickedRestParty(Button *button); - int clickedUnk28(Button *button); - int clickedUnk29(Button *button); - int clickedUnk30(Button *button); - int clickedUnk31(Button *button); + int clickedMoneyBox(Button *button); + int clickedCompass(Button *button); + int clickedAutomap(Button *button); + int clickedLamp(Button *button); int clickedUnk32(Button *button); + const ButtonDef *_buttonData; + int _buttonDataSize; + const int16 *_buttonList1; + int _buttonList1Size; + const int16 *_buttonList2; + int _buttonList2Size; + const int16 *_buttonList3; + int _buttonList3Size; + const int16 *_buttonList4; + int _buttonList4Size; + const int16 *_buttonList5; + int _buttonList5Size; + const int16 *_buttonList6; + int _buttonList6Size; + const int16 *_buttonList7; + int _buttonList7Size; + const int16 *_buttonList8; + int _buttonList8Size; + // text - TextDisplayer_LoL *_dlg; + TextDisplayer_LoL *_txt; // emc scripts void runInitScript(const char *filename, int func); void runInfScript(const char *filename); - void runResidentScript(int func, int reg0); - void runResidentScriptCustom(int func, int reg0, int reg1, int reg2, int reg3, int reg4); + void runSceneScript(int block, int sub); + void runSceneScriptCustom(int block, int sub, int charNum, int item, int reg3, int reg4); bool checkScriptUnk(int func); EMCData _scriptData; bool _scriptBoolSkipExec; - uint8 _unkScriptByte; + uint16 _scriptDirection; uint16 _currentDirection; uint16 _currentBlock; bool _sceneUpdateRequired; - int16 _scriptExecutedFuncs[18]; + int16 _currentBlockPropertyIndex[18]; uint16 _gameFlags[15]; uint16 _unkEMC46[16]; @@ -512,7 +543,7 @@ private: void unkHideInventory(); void restoreSceneAfterDialogueSequence(int redraw); void toggleSelectedCharacterFrame(bool mode); - void restorePaletteEntry(); + void fadeText(); void updateWsaAnimations(); uint8 **_itemIconShapes; @@ -555,14 +586,15 @@ private: int _updateCharV1; int _updateCharV2; int _updateCharV3; - int _updateCharV4; - int _restorePalette; + int _textColourFlag; + bool _fadeText; int _hideInventory; uint32 _palUpdateTimer; uint32 _updatePortraitNext; int _loadLevelFlag; int _levelFlagUnk; + int _unkCharNum; uint8 **_monsterShapes; uint8 **_monsterPalettes; @@ -611,10 +643,11 @@ private: void resetItems(int flag); void resetLvlBuffer(); void resetBlockProperties(); + bool testWallFlag(int block, int direction, int flag); bool testWallInvisibility(int block, int direction); void drawScene(int pageNum); - + void generateBlockDrawingBuffer(int block, int direction); void generateBlockDrawingBufferF0(int16 wllOffset, uint8 wllIndex, uint8 wllVmpIndex, int16 vmpOffset, uint8 len, uint8 numEntries); void generateBlockDrawingBufferF1(int16 wllOffset, uint8 wllIndex, uint8 wllVmpIndex, int16 vmpOffset, uint8 len, uint8 numEntries); @@ -634,17 +667,44 @@ private: void drawScriptShapes(int pageNum); void updateSceneWindow(); + void setSequenceGui(int x, int y, int w, int h, int enableFlags); + void restoreDefaultGui(); + void updateCompass(); - void moveParty(uint16 direction, int unk1, int unk2, int unk3); + void moveParty(uint16 direction, int unk1, int unk2, int buttonShape); uint16 calcNewBlockPostion(uint16 curBlock, uint16 direction); - + bool checkBlockPassability(uint16 block, uint16 direction); + void notifyBlockNotPassable(int scrollFlag); + + void movePartySmoothScrollBlocked(int speed); + void movePartySmoothScrollUp(int speed); + void movePartySmoothScrollDown(int speed); + void movePartySmoothScrollLeft(int speed); + void movePartySmoothScrollRight(int speed); + void movePartySmoothScrollTurnLeft(int speed); + void movePartySmoothScrollTurnRight(int speed); + + int smoothScrollDrawSpecialShape(int pageNum); void setLF2(int block); + + uint8 *_scrollSceneBuffer; + uint32 _smoothScrollTimer; + int _smoothScrollModeNormal; + + const uint8 *_scrollXTop; + int _scrollXTopSize; + const uint8 *_scrollYTop; + int _scrollYTopSize; + const uint8 *_scrollXBottom; + int _scrollXBottomSize; + const uint8 *_scrollYBottom; + int _scrollYBottomSize; int _unkFlag; int _nextScriptFunc; uint8 _currentLevel; - bool _loadLevelFlag2; + int _sceneDefaultUpdate; int _lvlBlockIndex; int _lvlShapeIndex; bool _unkDrawLevelBool; @@ -656,6 +716,7 @@ private: uint8 *_sceneWindowBuffer; LevelShapeProperty *_levelShapeProperties; uint8 **_levelShapes; + uint8 *_scriptAssignedLevelShape; char _lastSuppFile[12]; char _lastOverridePalFile[12]; @@ -703,7 +764,7 @@ private: int16 _dmScaleH; int _lastMouseRegion; - int _preSeq_X1, _preSeq_Y1, _preSeq_X2, _preSeq_Y2; + //int _preSeq_X1, _preSeq_Y1, _preSeq_X2, _preSeq_Y2; uint8 _unkGameFlag; uint8 *_tempBuffer5120; diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index 1724a1b26a..85be020ebc 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -217,6 +217,7 @@ enum kKyraResources { lolMusicTrackMap, lolIngameGMSfxIndex, lolIngameMT32SfxIndex, + //lolIngameADLSfxIndex, lolSpellProperties, lolGameShapeMap, lolLevelShpList, @@ -245,6 +246,21 @@ enum kKyraResources { lolDscOvlIndex, lolDscBlockIndex, + lolScrollXTop, + lolScrollYTop, + lolScrollXBottom, + lolScrollYBottom, + + lolButtonDefs, + lolButtonList1, + lolButtonList2, + lolButtonList3, + lolButtonList4, + lolButtonList5, + lolButtonList6, + lolButtonList7, + lolButtonList8, + kMaxResIDs }; @@ -275,6 +291,7 @@ public: const SpellProperty *loadSpellData(int id, int &entries); const CompassDef *loadCompassData(int id, int &entries); const uint16 *loadRawDataBe16(int id, int &entries); + const ButtonDef *loadButtonDefs(int id, int &entries); // use '-1' to prefetch/unload all ids // prefetchId retruns false if only on of the resources @@ -309,7 +326,8 @@ private: bool loadCharData(const char *filename, void *&ptr, int &size); bool loadSpellData(const char *filename, void *&ptr, int &size); bool loadCompassData(const char *filename, void *&ptr, int &size); - bool loadRawDataBe16(const char *filename, void *&ptr, int &size); + bool loadRawDataBe16(const char *filename, void *&ptr, int &size); + bool loadButtonDefs(const char *filename, void *&ptr, int &size); void freeRawData(void *&ptr, int &size); void freeStringTable(void *&ptr, int &size); @@ -323,6 +341,7 @@ private: void freeSpellData(void *&ptr, int &size); void freeCompassData(void *&ptr, int &size); void freeRawDataBe16(void *&ptr, int &size); + void freeButtonDefs(void *&ptr, int &size); const char *getFilename(const char *name); Common::SeekableReadStream *getFile(const char *name); @@ -342,7 +361,8 @@ private: lolCharData, lolSpellData, lolCompassData, - lolRawDataBe16 + lolRawDataBe16, + lolButtonData }; struct BuiltinRes { diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp index 698330e275..44f8f1d334 100644 --- a/engines/kyra/scene_lol.cpp +++ b/engines/kyra/scene_lol.cpp @@ -59,7 +59,7 @@ void LoLEngine::loadLevel(int index) { _currentLevel = index; _updateFlags = 0; - // TODO + restoreDefaultGui(); loadTalkFile(index); @@ -84,7 +84,7 @@ void LoLEngine::loadLevel(int index) { _screen->generateGrayOverlay(_screen->_currentPalette, _screen->_grayOverlay,32, 16, 0, 0, 128, true); - _loadLevelFlag2 = false; + _sceneDefaultUpdate = 0; if (_screen->_fadeFlag == 3) _screen->fadeToBlack(10); @@ -160,7 +160,7 @@ void LoLEngine::initCMZ1(CLevelItem *l, int a) { cmzS3(l); if (_currentLevel != 29) initCMZ1(l, 14); - runResidentScriptCustom(0x404, -1, l->field_16, l->field_16, 0, 0); + runSceneScriptCustom(0x404, -1, l->field_16, l->field_16, 0, 0); checkScriptUnk(l->blockPropertyIndex); if (l->field_14 == 14) initCMZ2(l, 0, 0); @@ -202,7 +202,7 @@ void LoLEngine::initCMZ2(CLevelItem *l, uint16 a, uint16 b) { return; if (l->blockPropertyIndex != t) - runResidentScriptCustom(l->blockPropertyIndex, 0x800, -1, l->field_16, 0, 0); + runSceneScriptCustom(l->blockPropertyIndex, 0x800, -1, l->field_16, 0, 0); if (_updateFlags & 1) return; @@ -767,6 +767,21 @@ void LoLEngine::resetBlockProperties() { } } +bool LoLEngine::testWallFlag(int block, int direction, int flag) { + if (_levelBlockProperties[block].flags & 0x10) + return true; + + if (direction != -1) + return (_wllWallFlags[_levelBlockProperties[block].walls[direction ^ 2]] & flag) ? true : false; + + for (int i = 0; i < 4; i++) { + if (_wllWallFlags[_levelBlockProperties[block].walls[i]] & flag) + return true; + } + + return false; +} + bool LoLEngine::testWallInvisibility(int block, int direction) { uint8 w = _levelBlockProperties[block].walls[direction]; if (_wllVmpMap[w] || _wllShapeMap[w] || _levelBlockProperties[block].flags & 0x80) @@ -838,10 +853,63 @@ void LoLEngine::updateCompass() { } -void LoLEngine::moveParty(uint16 direction, int unk1, int unk2, int unk3) { - // TODO - _currentBlock = calcNewBlockPostion(_currentBlock, direction); - // XXXX +void LoLEngine::moveParty(uint16 direction, int unk1, int unk2, int buttonShape) { + if (buttonShape) + gui_toggleButtonDisplayMode(buttonShape, 1); + + uint16 opos = _currentBlock; + uint16 npos = calcNewBlockPostion(_currentBlock, direction); + + if (!checkBlockPassability(npos, direction)) { + notifyBlockNotPassable(unk2 ? 0 : 1); + gui_toggleButtonDisplayMode(buttonShape, 0); + return; + } + + _scriptDirection = direction; + _currentBlock = npos; + _sceneDefaultUpdate = 1; + + calcCoordinates(_partyPosX, _partyPosY, opos, 0x80, 0x80); + _unkFlag &= 0xfdff; + + runSceneScript(opos, 4); + runSceneScript(npos, 1); + + if (!(_unkFlag & 0x200)) { + updatePortraitUnkTimeSub(2, 0); + + if (_sceneDefaultUpdate) { + switch (unk2) { + case 0: + movePartySmoothScrollUp(2); + break; + case 1: + movePartySmoothScrollDown(2); + break; + case 2: + movePartySmoothScrollLeft(1); + break; + case 3: + movePartySmoothScrollRight(1); + break; + default: + break; + } + } else { + gui_drawScene(0); + } + + gui_toggleButtonDisplayMode(buttonShape, 0); + + runSceneScript(opos, 8); + runSceneScript(npos, 2); + + if (_levelBlockProperties[npos].walls[0] == 0x1a) + memset(_levelBlockProperties[npos].walls, 0, 4); + } + + setLF2(_currentBlock); } uint16 LoLEngine::calcNewBlockPostion(uint16 curBlock, uint16 direction) { @@ -849,6 +917,308 @@ uint16 LoLEngine::calcNewBlockPostion(uint16 curBlock, uint16 direction) { return (curBlock + blockPosTable[direction]) & 0x3ff; } +bool LoLEngine::checkBlockPassability(uint16 block, uint16 direction) { + if (testWallFlag(block, direction, 1)) + return false; + + uint16 d = _levelBlockProperties[block].itemIndex; + + while (d) { + if (d & 0x8000) + return false; + d = findItem(d)->itemIndexUnk; + } + + return true; +} + +void LoLEngine::notifyBlockNotPassable(int scrollFlag) { + if (scrollFlag) + movePartySmoothScrollBlocked(2); + + snd_dialogueSpeechUpdate(1); + _txt->printMessage(0x8002, getLangString(0x403f)); + snd_playSoundEffect(19, 255); +} + +void LoLEngine::movePartySmoothScrollBlocked(int speed) { + if (!(_unkGameFlag & 8) || ((_unkGameFlag & 8) && _hideInventory)) + return; + + _screen->backupSceneWindow(_sceneDrawPage2 == 2 ? 2 : 6, 6); + + for (int i = 0; i < 2; i++) { + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollZoomStepTop(6, 2, _scrollXTop[i], _scrollYTop[i]); + _screen->smoothScrollZoomStepBottom(6, 2, _scrollXBottom[i], _scrollYBottom[i]); + _screen->restoreSceneWindow(2, 0); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + if (!_smoothScrollModeNormal) + i++; + } + + for (int i = 2; i; i--) { + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollZoomStepTop(6, 2, _scrollXTop[i], _scrollYTop[i]); + _screen->smoothScrollZoomStepBottom(6, 2, _scrollXBottom[i], _scrollYBottom[i]); + _screen->restoreSceneWindow(2, 0); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + if (!_smoothScrollModeNormal) + i++; + } + + if (_sceneDefaultUpdate != 2) { + _screen->restoreSceneWindow(6, 0); + _screen->updateScreen(); + } + + updateSceneWindow(); +} + +void LoLEngine::movePartySmoothScrollUp(int speed) { + if (!(_unkGameFlag & 8) || ((_unkGameFlag & 8) && _hideInventory)) + return; + + int d = 0; + + if (_sceneDrawPage2 == 2) { + d = smoothScrollDrawSpecialShape(6); + gui_drawScene(6); + _screen->copyRegionToBuffer(6, 112, 0, 176, 120, _scrollSceneBuffer); + _screen->backupSceneWindow(2, 6); + } else { + d = smoothScrollDrawSpecialShape(2); + gui_drawScene(2); + _screen->copyRegionToBuffer(2, 112, 0, 176, 120, _scrollSceneBuffer); + _screen->backupSceneWindow(6, 6); + } + + for (int i = 0; i < 5; i++) { + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollZoomStepTop(6, 2, _scrollXTop[i], _scrollYTop[i]); + _screen->smoothScrollZoomStepBottom(6, 2, _scrollXBottom[i], _scrollYBottom[i]); + + //if (d) + // unk(_tempBuffer5120, page2); + + _screen->restoreSceneWindow(2, 0); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + if (!_smoothScrollModeNormal) + i++; + } + + //if (d) + // unk(_tempBuffer5120, _scrollSceneBuffer); + + if (_sceneDefaultUpdate != 2) { + _screen->copyBlockToPage(0, 112, 0, 176, 120, _scrollSceneBuffer); + _screen->updateScreen(); + } + + updateSceneWindow(); +} + +void LoLEngine::movePartySmoothScrollDown(int speed) { + if (!(_unkGameFlag & 8)) + return; + + //int d = smoothScrollDrawSpecialShape(2); + gui_drawScene(2); + _screen->backupSceneWindow(2, 6); + + for (int i = 4; i >= 0; i--) { + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollZoomStepTop(6, 2, _scrollXTop[i], _scrollYTop[i]); + _screen->smoothScrollZoomStepBottom(6, 2, _scrollXBottom[i], _scrollYBottom[i]); + + //if (d) + // unk(_tempBuffer5120, page2); + + _screen->restoreSceneWindow(2, 0); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + if (!_smoothScrollModeNormal) + i++; + } + + //if (d) + // unk(_tempBuffer5120, _scrollSceneBuffer); + + if (_sceneDefaultUpdate != 2) { + _screen->restoreSceneWindow(6, 0); + _screen->updateScreen(); + } + + updateSceneWindow(); +} + +void LoLEngine::movePartySmoothScrollLeft(int speed) { + if (!(_unkGameFlag & 8)) + return; + + speed <<= 1; + + gui_drawScene(_sceneDrawPage1); + + for (int i = 88, d = 88; i > 22; i -= 22, d += 22) { + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollHorizontalStep(_sceneDrawPage2, 66, d, i); + _screen->copyRegion(112 + i, 0, 112, 0, d, 120, _sceneDrawPage1, _sceneDrawPage2, Screen::CR_NO_P_CHECK); + _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + } + + if (_sceneDefaultUpdate != 2) { + _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + } + + SWAP(_sceneDrawPage1, _sceneDrawPage2); +} + +void LoLEngine::movePartySmoothScrollRight(int speed) { + if (!(_unkGameFlag & 8)) + return; + + speed <<= 1; + + gui_drawScene(_sceneDrawPage1); + + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->copyRegion(112, 0, 222, 0, 66, 120, _sceneDrawPage1, _sceneDrawPage2, Screen::CR_NO_P_CHECK); + _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollHorizontalStep(_sceneDrawPage2, 22, 0, 66); + _screen->copyRegion(112, 0, 200, 0, 88, 120, _sceneDrawPage1, _sceneDrawPage2, Screen::CR_NO_P_CHECK); + _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollHorizontalStep(_sceneDrawPage2, 44, 0, 22); + _screen->copyRegion(112, 0, 178, 0, 110, 120, _sceneDrawPage1, _sceneDrawPage2, Screen::CR_NO_P_CHECK); + _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + + if (_sceneDefaultUpdate != 2) { + _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + } + + SWAP(_sceneDrawPage1, _sceneDrawPage2); +} + +void LoLEngine::movePartySmoothScrollTurnLeft(int speed) { + if (!(_unkGameFlag & 8)) + return; + + speed <<= 1; + + //int d = smoothScrollDrawSpecialShape(_sceneDrawPage1); + gui_drawScene(_sceneDrawPage1); + int dp = _sceneDrawPage2 == 2 ? _sceneDrawPage2 : _sceneDrawPage1; + + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollTurnStep1(_sceneDrawPage1, _sceneDrawPage2, dp); + //if (d) + // unk(_tempBuffer5120, _scrollSceneBuffer); + _screen->restoreSceneWindow(dp, 0); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollTurnStep2(_sceneDrawPage1, _sceneDrawPage2, dp); + //if (d) + // unk(_tempBuffer5120, _scrollSceneBuffer); + _screen->restoreSceneWindow(dp, 0); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollTurnStep3(_sceneDrawPage1, _sceneDrawPage2, dp); + //if (d) + // unk(_tempBuffer5120, _scrollSceneBuffer); + _screen->restoreSceneWindow(dp, 0); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + + if (_sceneDefaultUpdate != 2) { + drawScriptShapes(_sceneDrawPage1); + _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + } +} + +void LoLEngine::movePartySmoothScrollTurnRight(int speed) { + if (!(_unkGameFlag & 8)) + return; + + speed <<= 1; + + //int d = smoothScrollDrawSpecialShape(_sceneDrawPage1); + gui_drawScene(_sceneDrawPage1); + int dp = _sceneDrawPage2 == 2 ? _sceneDrawPage2 : _sceneDrawPage1; + + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollTurnStep3(_sceneDrawPage2, _sceneDrawPage1, dp); + //if (d) + // unk(_tempBuffer5120, _scrollSceneBuffer); + _screen->restoreSceneWindow(dp, 0); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollTurnStep2(_sceneDrawPage2, _sceneDrawPage1, dp); + //if (d) + // unk(_tempBuffer5120, _scrollSceneBuffer); + _screen->restoreSceneWindow(dp, 0); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + + _smoothScrollTimer = _system->getMillis() + speed * _tickLength; + _screen->smoothScrollTurnStep1(_sceneDrawPage2, _sceneDrawPage1, dp); + //if (d) + // unk(_tempBuffer5120, _scrollSceneBuffer); + _screen->restoreSceneWindow(dp, 0); + _screen->updateScreen(); + fadeText(); + delayUntil(_smoothScrollTimer); + + if (_sceneDefaultUpdate != 2) { + drawScriptShapes(_sceneDrawPage1); + _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + } +} + +int LoLEngine::smoothScrollDrawSpecialShape(int pageNum) { + // TODO + if(!_scriptAssignedLevelShape) + return 0; + return 0; +} + void LoLEngine::setLF2(int block) { if (!(_screen->_drawGuiFlag & 0x1000)) return; @@ -858,16 +1228,12 @@ void LoLEngine::setLF2(int block) { void LoLEngine::drawScene(int pageNum) { if (pageNum && pageNum != _sceneDrawPage1) { - _sceneDrawPage1 ^= _sceneDrawPage2; - _sceneDrawPage2 ^= _sceneDrawPage1; - _sceneDrawPage1 ^= _sceneDrawPage2; + SWAP(_sceneDrawPage1, _sceneDrawPage2); updateSceneWindow(); } if (pageNum && pageNum != _sceneDrawPage1) { - _sceneDrawPage1 ^= _sceneDrawPage2; - _sceneDrawPage2 ^= _sceneDrawPage1; - _sceneDrawPage1 ^= _sceneDrawPage2; + SWAP(_sceneDrawPage1, _sceneDrawPage2); updateSceneWindow(); } @@ -879,9 +1245,7 @@ void LoLEngine::drawScene(int pageNum) { drawScriptShapes(_sceneDrawPage1); _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, _sceneDrawPage2, Screen::CR_NO_P_CHECK); _screen->copyRegion(112, 0, 112, 0, 176, 120, _sceneDrawPage1, 0, Screen::CR_NO_P_CHECK); - _sceneDrawPage1 ^= _sceneDrawPage2; - _sceneDrawPage2 ^= _sceneDrawPage1; - _sceneDrawPage1 ^= _sceneDrawPage2; + SWAP(_sceneDrawPage1, _sceneDrawPage2); } runLoopSub4(0); @@ -896,6 +1260,21 @@ void LoLEngine::updateSceneWindow() { _screen->showMouse(); } +void LoLEngine::setSequenceGui(int x, int y, int w, int h, int enableFlags) { + gui_enableSequenceButtons(x, y, w, h, enableFlags); + int offs = _itemInHand ? 10 : 0; + _screen->setMouseCursor(offs, offs, getItemIconShapePtr(_itemInHand)); + setLampMode(0); + _lampStatusSuspended = true; +} + +void LoLEngine::restoreDefaultGui() { + gui_enableDefaultPlayfieldButtons(); + if (_lampStatusSuspended) + resetLampStatus(); + _lampStatusSuspended = false; +} + void LoLEngine::generateBlockDrawingBuffer(int block, int direction) { _sceneDrawVar1 = _dscBlockMap[_currentDirection]; _sceneDrawVar2 = _dscBlockMap[_currentDirection + 4]; @@ -905,7 +1284,7 @@ void LoLEngine::generateBlockDrawingBuffer(int block, int direction) { _wllProcessFlag = ((block >> 5) + (block & 0x1f) + _currentDirection) & 1; - if (_wllProcessFlag) + if (_wllProcessFlag) // floor and ceiling generateBlockDrawingBufferF1(0, 15, 1, -330, 22, 15); else generateBlockDrawingBufferF0(0, 15, 1, -330, 22, 15); @@ -1014,10 +1393,10 @@ void LoLEngine::generateBlockDrawingBuffer(int block, int direction) { t = _curBlockCaps[15]->walls[_sceneDrawVar2]; t2 = _curBlockCaps[17]->walls[_sceneDrawVar3]; - if (t) + if (t) // wall to the immediate left generateBlockDrawingBufferF0(0, 0, t, 0, 3, 15); - if (t2) - generateBlockDrawingBufferF1(19, 0, t, 0, 3, 15); + if (t2) // wall to the immediate right + generateBlockDrawingBufferF1(19, 0, t2, 0, 3, 15); } void LoLEngine::generateBlockDrawingBufferF0(int16 wllOffset, uint8 wllIndex, uint8 wllVmpIndex, int16 vmpOffset, uint8 len, uint8 numEntries) { @@ -1045,17 +1424,19 @@ void LoLEngine::generateBlockDrawingBufferF1(int16 wllOffset, uint8 wllIndex, ui for (int i = 0; i < numEntries; i++) { for (int ii = 0; ii < len; ii++) { - if ((wllOffset + ii >= 0) && (wllOffset + ii < 22)) { - uint16 t = vmp[len * i + len - 1 - ii]; - if (t) { - if (t & 04000) - t -= 0x4000; - else - t |= 0x4000; - - _blockDrawingBuffer[(wllIndex + i) * 22 + wllOffset + ii] = t; - } - } + if ((wllOffset + ii) < 0 || (wllOffset + ii) > 21) + continue; + + uint16 v = vmp[i * len + (len - 1 - ii)]; + if (!v) + continue; + + if (v & 0x4000) + v -= 0x4000; + else + v |= 0x4000; + + _blockDrawingBuffer[(wllIndex + i) * 22 + wllOffset + ii] = v; } } } @@ -1069,7 +1450,7 @@ bool LoLEngine::hasWall(int index) { void LoLEngine::assignBlockCaps(int block, int direction) { for (int i = 0; i < 18; i++) { uint16 t = (block + _dscBlockIndex[direction * 18 + i]) & 0x3ff; - _scriptExecutedFuncs[i] = t; + _currentBlockPropertyIndex[i] = t; _curBlockCaps[i] = &_levelBlockProperties[t]; _lvlShapeLeftRight[i] = _lvlShapeLeftRight[18 + i] = -1; @@ -1482,7 +1863,8 @@ void LoLEngine::drawDoorOrMonsterShape(uint8 *shape, uint8 *table, int x, int y, } void LoLEngine::drawScriptShapes(int pageNum) { - // TODO + if (!_scriptAssignedLevelShape) + return; } } // end of namespace Kyra diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp index 78ac2c3a89..4eee909ff2 100644 --- a/engines/kyra/screen_lol.cpp +++ b/engines/kyra/screen_lol.cpp @@ -298,6 +298,236 @@ void Screen_LoL::fadeClearSceneWindow(int delay) { _fadeFlag = 1; } +void Screen_LoL::backupSceneWindow(int srcPageNum, int dstPageNum) { + uint8 *src = getPagePtr(srcPageNum) + 112; + uint8 *dst = getPagePtr(dstPageNum) + 0xa500; + + for (int h = 0; h < 120; h++) { + for (int w = 0; w < 176; w++) + *dst++ = *src++; + src += 144; + } +} + +void Screen_LoL::restoreSceneWindow(int srcPageNum, int dstPageNum) { + uint8 *src = getPagePtr(srcPageNum) + 0xa500; + uint8 *dst = getPagePtr(dstPageNum) + 112; + + for (int h = 0; h < 120; h++) { + memcpy(dst, src, 176); + src += 176; + dst += 320; + } + + if (!dstPageNum) + addDirtyRect(112, 0, 176, 120); +} + +void Screen_LoL::smoothScrollZoomStepTop(int srcPageNum, int dstPageNum, int x, int y) { + uint8 *src = getPagePtr(srcPageNum) + 0xa500 + y * 176 + x; + uint8 *dst = getPagePtr(dstPageNum) + 0xa500; + + x <<= 1; + uint16 width = 176 - x; + uint16 scaleX = (((x + 1) << 8) / width + 0x100); + uint16 cntW = scaleX >> 8; + scaleX <<= 8; + width--; + uint16 widthCnt = width; + + uint16 height = 46 - y; + uint16 scaleY = (((y + 1) << 8) / height + 0x100); + scaleY <<= 8; + + uint32 scaleYc = 0; + while (height) { + uint32 scaleXc = 0; + do { + scaleXc += scaleX; + int numbytes = cntW + (scaleXc >> 16); + scaleXc &= 0xffff; + memset(dst, *src++, numbytes); + dst += numbytes; + } while (--widthCnt); + + *dst++ = *src++; + widthCnt = width; + + src += x; + scaleYc += scaleY; + + if (scaleYc >> 16) { + scaleYc = 0; + src -= 176; + continue; + } + + height--; + } +} + +void Screen_LoL::smoothScrollZoomStepBottom(int srcPageNum, int dstPageNum, int x, int y) { + uint8 *src = getPagePtr(srcPageNum) + 0xc4a0 + x; + uint8 *dst = getPagePtr(dstPageNum) + 0xc4a0; + + x <<= 1; + uint16 width = 176 - x; + uint16 scaleX = (((x + 1) << 8) / width + 0x100); + uint16 cntW = scaleX >> 8; + scaleX <<= 8; + width--; + uint16 widthCnt = width; + + uint16 height = 74 - y; + uint16 scaleY = (((y + 1) << 8) / height + 0x100); + scaleY <<= 8; + + uint32 scaleYc = 0; + while (height) { + uint32 scaleXc = 0; + do { + scaleXc += scaleX; + int numbytes = cntW + (scaleXc >> 16); + scaleXc &= 0xffff; + memset(dst, *src++, numbytes); + dst += numbytes; + } while (--widthCnt); + + *dst++ = *src++; + widthCnt = width; + + src += x; + scaleYc += scaleY; + + if (scaleYc >> 16) { + scaleYc = 0; + src -= 176; + continue; + } + + height--; + } +} + +void Screen_LoL::smoothScrollHorizontalStep(int pageNum, int srcX, int dstX, int w) { + uint8 *d = getPagePtr(pageNum); + uint8 *s = d + 112 + srcX; + + int w2 = srcX + w - dstX; + int pitchS = 320 + w2 - (w << 1); + + int pitchD = 320 - w; + int h = 120; + + while (h--) { + for (int i = 0; i < w; i++) + *d++ = *s++; + d -= w; + s -= w2; + + for (int i = 0; i < w; i++) + *s++ = *d++; + + s += pitchS; + d += pitchD; + } +} + +void Screen_LoL::smoothScrollTurnStep1(int srcPage1Num, int srcPage2Num, int dstPageNum) { + uint8 *s = getPagePtr(srcPage1Num) + 273; + uint8 *d = getPagePtr(dstPageNum) + 0xa500; + + for (int i = 0; i < 120; i++) { + uint8 a = *s++; + *d++ = a; + *d++ = a; + + for (int ii = 0; ii < 14; ii++) { + a = *s++; + *d++ = a; + *d++ = a; + *d++ = a; + } + + s += 305; + d += 132; + } + + s = getPagePtr(srcPage2Num) + 112; + d = getPagePtr(dstPageNum) + 0xa52c; + + for (int i = 0; i < 120; i++) { + for (int ii = 0; ii < 33; ii++) { + *d++ = *s++; + *d++ = *s++; + uint8 a = *s++; + *d++ = a; + *d++ = a; + } + + s += 221; + d += 44; + } +} + +void Screen_LoL::smoothScrollTurnStep2(int srcPage1Num, int srcPage2Num, int dstPageNum) { + uint8 *s = getPagePtr(srcPage1Num) + 244; + uint8 *d = getPagePtr(dstPageNum) + 0xa500; + + for (int k = 0; k < 2; k++) { + for (int i = 0; i < 120; i++) { + for (int ii = 0; ii < 44; ii++) { + uint8 a = *s++; + *d++ = a; + *d++ = a; + } + + s += 276; + d += 88; + } + + s = getPagePtr(srcPage2Num) + 112; + d = getPagePtr(dstPageNum) + 0xa558; + } +} + +void Screen_LoL::smoothScrollTurnStep3(int srcPage1Num, int srcPage2Num, int dstPageNum) { + uint8 *s = getPagePtr(srcPage1Num) + 189; + uint8 *d = getPagePtr(dstPageNum) + 0xa500; + + for (int i = 0; i < 120; i++) { + for (int ii = 0; ii < 33; ii++) { + *d++ = *s++; + *d++ = *s++; + uint8 a = *s++; + *d++ = a; + *d++ = a; + } + + s += 221; + d += 44; + } + + s = getPagePtr(srcPage2Num) + 112; + d = getPagePtr(dstPageNum) + 0xa584; + + for (int i = 0; i < 120; i++) { + for (int ii = 0; ii < 14; ii++) { + uint8 a = *s++; + *d++ = a; + *d++ = a; + *d++ = a; + } + + uint8 a = *s++; + *d++ = a; + *d++ = a; + + s += 305; + d += 132; + } +} + void Screen_LoL::fadeToBlack(int delay, const UpdateFunctor *upFunc) { Screen::fadeToBlack(delay, upFunc); _fadeFlag = 2; @@ -329,49 +559,61 @@ void Screen_LoL::loadSpecialColours(uint8 *destPalette) { memcpy(destPalette + 0x240, _screenPalette + 0x240, 12); } -void Screen_LoL::loadColour254(uint8 *destPalEntry) { - memcpy(destPalEntry, _screenPalette + 0x2fa, 3); +void Screen_LoL::copyColour(int dstColourIndex, int srcColourIndex) { + uint8 *s = _screenPalette + srcColourIndex * 3; + uint8 *d = _screenPalette + dstColourIndex * 3; + memcpy(d, s, 3); + + uint8 ci[4]; + ci[0] = (d[0] << 2) | (d[0] & 3); + ci[1] = (d[1] << 2) | (d[1] & 3); + ci[2] = (d[2] << 2) | (d[2] & 3); + ci[3] = 0; + + _system->setPalette(ci, dstColourIndex, 1); } -bool Screen_LoL::copyColour(int dstColorIndex, int srcColorIndex, uint32 time1, uint32 time2) { - uint8 *s = _screenPalette + 3 * dstColorIndex; - uint8 *e = _screenPalette + 3 * srcColorIndex; - uint8 *p = getPalette(1) + 3 * dstColorIndex; +bool Screen_LoL::fadeColour(int dstColourIndex, int srcColourIndex, uint32 elapsedTime, uint32 targetTime) { + uint8 *dst = _screenPalette + 3 * dstColourIndex; + uint8 *src = _screenPalette + 3 * srcColourIndex; + uint8 *p = getPalette(1) + 3 * dstColourIndex; bool res = false; - uint16 t1 = 0; - uint16 t2 = 0; + int16 t1 = 0; + int16 t2 = 0; int32 t3 = 0; uint8 tmpPalEntry[3]; for (int i = 0; i < 3; i++) { - if (time1 < time2) { - t1 = *e & 0x3f; - t2 = *s & 0x3f; + if (elapsedTime < targetTime) { + t1 = *src & 0x3f; + t2 = *dst & 0x3f; t3 = t1 - t2; - if (!t3) + if (t3) res = true; - t3 = (((((t3 << 8) / time2) * time1) >> 8) & 0xffff) + t2; + t3 = (((t3 << 8) / (int)targetTime) * (int)elapsedTime) >> 8; + t3 = t2 + t3; } else { - t1 = *e & 0x3f; + t1 = *dst & 0x3f; *p = t3 = t1; res = false; } tmpPalEntry[i] = t3 & 0xff; - s++; - e++; + src++; + dst++; p++; } uint8 tpal[768]; memcpy(tpal, _screenPalette, 768); - memcpy(tpal + dstColorIndex * 3, tmpPalEntry, 3); + memcpy(tpal + dstColourIndex * 3, tmpPalEntry, 3); setScreenPalette(tpal); + updateScreen(); return res; } diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h index 0f8746ef00..3dcce8a486 100644 --- a/engines/kyra/screen_lol.h +++ b/engines/kyra/screen_lol.h @@ -50,12 +50,23 @@ public: void drawGridBox(int x, int y, int w, int h, int col); void fadeClearSceneWindow(int delay); + // smooth scrolling + void backupSceneWindow(int srcPageNum, int dstPageNum); + void restoreSceneWindow(int srcPageNum, int dstPageNum); + void smoothScrollZoomStepTop(int srcPageNum, int dstPageNum, int x, int y); + void smoothScrollZoomStepBottom(int srcPageNum, int dstPageNum, int x, int y); + void smoothScrollHorizontalStep(int pageNum, int x, int u2, int w); + void smoothScrollTurnStep1(int srcPage1Num, int srcPage2Num, int dstPageNum); + void smoothScrollTurnStep2(int srcPage1Num, int srcPage2Num, int dstPageNum); + void smoothScrollTurnStep3(int srcPage1Num, int srcPage2Num, int dstPageNum); + + // palette stuff void fadeToBlack(int delay=0x54, const UpdateFunctor *upFunc = 0); void setPaletteBrightness(uint8 *palDst, int brightness, int modifier); void generateBrightnessPalette(uint8 *palSrc, uint8 *palDst, int brightness, int modifier); void loadSpecialColours(uint8 *destPalette); - void loadColour254(uint8 *destPalEntry); - bool copyColour(int dstColorIndex, int srcColorIndex, uint32 time1, uint32 time2); + void copyColour(int dstColourIndex, int srcColourIndex); + bool fadeColour(int dstColourIndex, int srcColourIndex, uint32 elapsedTime, uint32 targetTime); void generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool skipSpecialColours); uint8 *generateLevelOverlay(const uint8 *srcPal, uint8 *ovl, int opColor, int weight); diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index 6486233cd8..571dd2d00d 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -54,34 +54,34 @@ void LoLEngine::runInitScript(const char *filename, int func) { void LoLEngine::runInfScript(const char *filename) { _emc->load(filename, &_scriptData, &_opcodes); - runResidentScript(0x400, -1); + runSceneScript(0x400, -1); } -void LoLEngine::runResidentScript(int func, int reg0) { - runResidentScriptCustom(func, reg0, -1, 0, 0, 0); +void LoLEngine::runSceneScript(int block, int sub) { + runSceneScriptCustom(block, sub, -1, 0, 0, 0); } -void LoLEngine::runResidentScriptCustom(int func, int reg0, int reg1, int reg2, int reg3, int reg4) { +void LoLEngine::runSceneScriptCustom(int block, int sub, int charNum, int item, int reg3, int reg4) { EMCState scriptState; memset(&scriptState, 0, sizeof(EMCState)); if (!_scriptBoolSkipExec) { _emc->init(&scriptState, &_scriptData); - _emc->start(&scriptState, func); + _emc->start(&scriptState, block); - scriptState.regs[0] = reg0; - scriptState.regs[1] = reg1; - scriptState.regs[2] = reg2; + scriptState.regs[0] = sub; + scriptState.regs[1] = charNum; + scriptState.regs[2] = item; scriptState.regs[3] = reg3; scriptState.regs[4] = reg4; - scriptState.regs[5] = func; - scriptState.regs[6] = _unkScriptByte; + scriptState.regs[5] = block; + scriptState.regs[6] = _scriptDirection; while (_emc->isValid(&scriptState)) _emc->run(&scriptState); } - checkScriptUnk(func); + checkScriptUnk(block); } bool LoLEngine::checkScriptUnk(int func) { @@ -89,7 +89,7 @@ bool LoLEngine::checkScriptUnk(int func) { return true; for (int i = 0; i < 15; i++) { - if (_scriptExecutedFuncs[i] == func) { + if (_currentBlockPropertyIndex[i] == func) { _sceneUpdateRequired = true; return true; } @@ -420,25 +420,33 @@ int LoLEngine::olol_setGlobalVar(EMCState *script) { calcCoordinates(_partyPosX, _partyPosY, _currentBlock, 0x80, 0x80); setLF2(_currentBlock); break; + case 1: _currentDirection = b; break; + case 2: _currentLevel = b & 0xff; break; + case 3: break; + case 4: _brightness = b & 0xff; break; + case 5: _credits = b; break; + case 6: //TODO break; + case 7: break; + case 8: _updateFlags = b; if (b == 1) { @@ -449,19 +457,24 @@ int LoLEngine::olol_setGlobalVar(EMCState *script) { setUnkFlags(2); } break; + case 9: _lampStatusUnk = b & 0xff; break; + case 10: - _loadLevelFlag2 = b & 0xff; + _sceneDefaultUpdate = b & 0xff; //TODO break; + case 11: //TODO break; + case 12: //TODO break; + default: break; } @@ -606,7 +619,7 @@ int LoLEngine::olol_playDialogueTalkText(EMCState *script) { if (!snd_playCharacterSpeech(track, 0, 0) || textEnabled()) { char *s = getLangString(track); - _dlg->play(4, s, script, 0, 1); + _txt->playDialogue(4, s, script, 0, 1); } return 1; diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 961f188c98..e69d3ed8d8 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -44,7 +44,7 @@ namespace Kyra { -#define RESFILE_VERSION 35 +#define RESFILE_VERSION 36 namespace { bool checkKyraDat(Common::SeekableReadStream *file) { @@ -226,6 +226,7 @@ bool StaticResource::init() { { lolSpellData, proc(loadSpellData), proc(freeSpellData) }, { lolCompassData, proc(loadCompassData), proc(freeCompassData) }, { lolRawDataBe16, proc(loadRawDataBe16), proc(freeRawDataBe16) }, + { lolButtonData, proc(loadButtonDefs), proc(freeButtonDefs) }, { 0, 0, 0 } }; @@ -375,6 +376,7 @@ bool StaticResource::init() { { lolMusicTrackMap, kRawData, "MUSIC.MAP" }, { lolIngameGMSfxIndex, kRawData, "SFX_GM.MAP" }, { lolIngameMT32SfxIndex, kRawData, "SFX_MT32.MAP" }, + //{ lolIngameADLSfxIndex, kRawData, "SFX_ADL.MAP" }, { lolSpellProperties, lolSpellData, "SPELLS.DEF" }, { lolGameShapeMap, kRawData, "GAMESHP.MAP" }, { lolLevelShpList, kStringList, "SHPFILES.TXT" }, @@ -403,6 +405,21 @@ bool StaticResource::init() { { lolDscDoorX, lolRawDataBe16, "DSCDOORX.DEF" }, { lolDscDoorY, lolRawDataBe16, "DSCDOORY.DEF" }, + { lolScrollXTop, kRawData, "SCROLLXT.DEF" }, + { lolScrollYTop, kRawData, "SCROLLYT.DEF" }, + { lolScrollXBottom, kRawData, "SCROLLXB.DEF" }, + { lolScrollYBottom, kRawData, "SCROLLYB.DEF" }, + + { lolButtonDefs, lolButtonData, "BUTTONS.DEF" }, + { lolButtonList1, lolRawDataBe16, "BUTTON1.LST" }, + { lolButtonList2, lolRawDataBe16, "BUTTON2.LST" }, + { lolButtonList3, lolRawDataBe16, "BUTTON3.LST" }, + { lolButtonList4, lolRawDataBe16, "BUTTON4.LST" }, + { lolButtonList5, lolRawDataBe16, "BUTTON5.LST" }, + { lolButtonList6, lolRawDataBe16, "BUTTON6.LST" }, + { lolButtonList7, lolRawDataBe16, "BUTTON7.LST" }, + { lolButtonList8, lolRawDataBe16, "BUTTON84.LST" }, + { 0, 0, 0 } }; @@ -482,6 +499,10 @@ const uint16 *StaticResource::loadRawDataBe16(int id, int &entries) { return (const uint16*)getData(id, lolRawDataBe16, entries); } +const ButtonDef *StaticResource::loadButtonDefs(int id, int &entries) { + return (const ButtonDef*)getData(id, lolButtonData, entries); +} + bool StaticResource::prefetchId(int id) { if (id == -1) { for (int i = 0; _filenameTable[i].filename; ++i) @@ -1048,6 +1069,31 @@ bool StaticResource::loadRawDataBe16(const char *filename, void *&ptr, int &size return true; } +bool StaticResource::loadButtonDefs(const char *filename, void *&ptr, int &size) { + Common::SeekableReadStream *file = getFile(filename); + + size = file->size() / 18; + + ButtonDef *r = new ButtonDef[size]; + + for (int i = 0; i < size; i++) { + r[i].buttonflags = file->readUint16BE(); + r[i].clickedShapeId = file->readByte(); + file->readByte(); + r[i].unk2 = file->readUint16BE(); + r[i].x = file->readSint16BE(); + r[i].y = file->readSint16BE(); + r[i].w = file->readUint16BE(); + r[i].h = file->readUint16BE(); + r[i].index = file->readUint16BE(); + r[i].screenDim = file->readUint16BE(); + } + + ptr = r; + + return true; +} + void StaticResource::freeRawData(void *&ptr, int &size) { uint8 *data = (uint8*)ptr; delete[] data; @@ -1144,6 +1190,13 @@ void StaticResource::freeRawDataBe16(void *&ptr, int &size) { size = 0; } +void StaticResource::freeButtonDefs(void *&ptr, int &size) { + ButtonDef *d = (ButtonDef*)ptr; + delete[] d; + ptr = 0; + size = 0; +} + void StaticResource::freePaletteTable(void *&ptr, int &size) { uint8 **data = (uint8**)ptr; while (size--) @@ -1633,6 +1686,7 @@ void LoLEngine::initStaticResource() { _musicTrackMap = _staticres->loadRawData(lolMusicTrackMap, _musicTrackMapSize); _ingameGMSoundIndex = _staticres->loadRawData(lolIngameGMSfxIndex, _ingameGMSoundIndexSize); _ingameMT32SoundIndex = _staticres->loadRawData(lolIngameMT32SfxIndex, _ingameMT32SoundIndexSize); + //_ingameADLSoundIndex = _staticres->loadRawData(lolIngameADLSfxIndex, _ingameADLSoundIndexSize); _spellProperties = _staticres->loadSpellData(lolSpellProperties, _spellPropertiesSize); _gameShapeMap = (const int8*)_staticres->loadRawData(lolGameShapeMap, _gameShapeMapSize); _levelShpList = _staticres->loadStrings(lolLevelShpList, _levelShpListSize); @@ -1642,24 +1696,29 @@ void LoLEngine::initStaticResource() { _dscUnk1 = (const int8*)_staticres->loadRawData(lolDscUnk1, _dscUnk1Size); _dscShapeIndex = (const int8*)_staticres->loadRawData(lolDscShapeIndex, _dscShapeIndexSize); _dscOvlMap = _staticres->loadRawData(lolDscOvlMap, _dscOvlMapSize); - _dscShapeScaleW = (const uint16 *)_staticres->loadRawDataBe16(lolDscScaleWidthData, _dscShapeScaleWSize); - _dscShapeScaleH = (const uint16 *)_staticres->loadRawDataBe16(lolDscScaleHeightData, _dscShapeScaleHSize); - _dscShapeX = (const int16 *)_staticres->loadRawDataBe16(lolDscX, _dscShapeXSize); - _dscShapeY = (const int8 *)_staticres->loadRawData(lolDscY, _dscShapeYSize); + _dscShapeScaleW = _staticres->loadRawDataBe16(lolDscScaleWidthData, _dscShapeScaleWSize); + _dscShapeScaleH = _staticres->loadRawDataBe16(lolDscScaleHeightData, _dscShapeScaleHSize); + _dscShapeX = (const int16*)_staticres->loadRawDataBe16(lolDscX, _dscShapeXSize); + _dscShapeY = (const int8*)_staticres->loadRawData(lolDscY, _dscShapeYSize); _dscTileIndex = _staticres->loadRawData(lolDscTileIndex, _dscTileIndexSize); _dscUnk2 = _staticres->loadRawData(lolDscUnk2, _dscUnk2Size); _dscDoorShpIndex = _staticres->loadRawData(lolDscDoorShapeIndex, _dscDoorShpIndexSize); - _dscDim1 = (const int8 *)_staticres->loadRawData(lolDscDimData1, _dscDim1Size); - _dscDim2 = (const int8 *)_staticres->loadRawData(lolDscDimData2, _dscDim2Size); + _dscDim1 = (const int8*)_staticres->loadRawData(lolDscDimData1, _dscDim1Size); + _dscDim2 = (const int8*)_staticres->loadRawData(lolDscDimData2, _dscDim2Size); _dscBlockMap = _staticres->loadRawData(lolDscBlockMap, _dscBlockMapSize); _dscDimMap = _staticres->loadRawData(lolDscDimMap, _dscDimMapSize); - _dscDoorMonsterScaleTable = (const uint16 *)_staticres->loadRawDataBe16(lolDscDoorScale, _dscDoorMonsterScaleTableSize); + _dscDoorMonsterScaleTable = _staticres->loadRawDataBe16(lolDscDoorScale, _dscDoorMonsterScaleTableSize); _dscShapeOvlIndex = _staticres->loadRawData(lolDscOvlIndex, _dscShapeOvlIndexSize); - _dscDoor4 = (const uint16 *)_staticres->loadRawDataBe16(lolDscDoor4, _dscDoor4Size); - _dscBlockIndex = (const int8 *)_staticres->loadRawData(lolDscBlockIndex, _dscBlockIndexSize); + _dscDoor4 = _staticres->loadRawDataBe16(lolDscDoor4, _dscDoor4Size); + _dscBlockIndex = (const int8*)_staticres->loadRawData(lolDscBlockIndex, _dscBlockIndexSize); _dscDoor1 = _staticres->loadRawData(lolDscDoor1, _dscDoor1Size); - _dscDoorMonsterX = (const int16 *)_staticres->loadRawDataBe16(lolDscDoorX, _dscDoorMonsterXSize); - _dscDoorMonsterY = (const int16 *)_staticres->loadRawDataBe16(lolDscDoorY, _dscDoorMonsterYSize); + _dscDoorMonsterX = (const int16*)_staticres->loadRawDataBe16(lolDscDoorX, _dscDoorMonsterXSize); + _dscDoorMonsterY = (const int16*)_staticres->loadRawDataBe16(lolDscDoorY, _dscDoorMonsterYSize); + + _scrollXTop = _staticres->loadRawData(lolScrollXTop, _scrollXTopSize); + _scrollYTop = _staticres->loadRawData(lolScrollYTop, _scrollYTopSize); + _scrollXBottom = _staticres->loadRawData(lolScrollXBottom, _scrollXBottomSize); + _scrollYBottom = _staticres->loadRawData(lolScrollYBottom, _scrollYBottomSize); const char *const *tmpSndList = _staticres->loadStrings(lolIngameSfxFiles, _ingameSoundListSize); _ingameSoundList = new char*[_ingameSoundListSize]; @@ -1668,6 +1727,120 @@ void LoLEngine::initStaticResource() { strcpy(_ingameSoundList[i], tmpSndList[i]); } _staticres->unloadId(lolIngameSfxFiles); + + _buttonData = _staticres->loadButtonDefs(lolButtonDefs, _buttonDataSize); + _buttonList1 = (const int16*)_staticres->loadRawDataBe16(lolButtonList1, _buttonList1Size); + _buttonList2 = (const int16*)_staticres->loadRawDataBe16(lolButtonList2, _buttonList2Size); + _buttonList3 = (const int16*)_staticres->loadRawDataBe16(lolButtonList3, _buttonList3Size); + _buttonList4 = (const int16*)_staticres->loadRawDataBe16(lolButtonList4, _buttonList4Size); + _buttonList5 = (const int16*)_staticres->loadRawDataBe16(lolButtonList5, _buttonList5Size); + _buttonList6 = (const int16*)_staticres->loadRawDataBe16(lolButtonList6, _buttonList6Size); + _buttonList7 = (const int16*)_staticres->loadRawDataBe16(lolButtonList7, _buttonList7Size); + _buttonList8 = (const int16*)_staticres->loadRawDataBe16(lolButtonList8, _buttonList8Size); +} + +void LoLEngine::assignButtonCallback(Button *button, int index) { +#define cb(x) BUTTON_FUNCTOR(LoLEngine, this, &LoLEngine::x) + static Button::Callback buttonCallbacks[] = { + cb(clickedUpArrow), + cb(clickedDownArrow), + cb(clickedDownArrow), + cb(clickedLeftArrow), + cb(clickedRightArrow), + cb(clickedTurnLeftArrow), + cb(clickedTurnRightArrow), + cb(clickedAttackButton), + cb(clickedAttackButton), + cb(clickedAttackButton), + cb(clickedAttackButton), + cb(clickedMagicButton), + cb(clickedMagicButton), + cb(clickedMagicButton), + cb(clickedMagicButton), + cb(clickedUnk9), + cb(clickedScreen), + cb(clickedPortraitLeft), + cb(clickedPortraitLeft), + cb(clickedPortraitLeft), + cb(clickedPortraitLeft), + cb(clickedPortraitLeft), + cb(clickedPortraitLeft), + cb(clickedPortraitLeft), + cb(clickedPortraitLeft), + cb(clickedLiveMagicBarsLeft), + cb(clickedLiveMagicBarsLeft), + cb(clickedLiveMagicBarsLeft), + cb(clickedLiveMagicBarsLeft), + cb(clickedPortraitEtcRight), + cb(clickedPortraitEtcRight), + cb(clickedPortraitEtcRight), + cb(clickedPortraitEtcRight), + cb(clickedUnk14), + cb(clickedUnk14), + cb(clickedUnk14), + cb(clickedUnk14), + cb(clickedUnk14), + cb(clickedUnk14), + cb(clickedUnk14), + cb(clickedUnk14), + cb(clickedUnk14), + cb(clickedUnk14), + cb(clickedUnk14), + cb(clickedUnk15), + cb(clickedUnk16), + cb(clickedUnk16), + cb(clickedUnk16), + cb(clickedUnk16), + cb(clickedUnk17), + cb(clickedInventorySlot), + cb(clickedInventorySlot), + cb(clickedInventorySlot), + cb(clickedInventorySlot), + cb(clickedInventorySlot), + cb(clickedInventorySlot), + cb(clickedInventorySlot), + cb(clickedInventorySlot), + cb(clickedInventorySlot), + cb(clickedInventorySlot), + cb(clickedInventoryScroll), + cb(clickedInventoryScroll), + cb(clickedUnk20), + cb(clickedUnk20), + cb(clickedScene), + cb(clickedUpArrow), + cb(clickedDownArrow), + cb(clickedLeftArrow), + cb(clickedRightArrow), + cb(clickedTurnLeftArrow), + cb(clickedTurnRightArrow), + cb(clickedScroll), + cb(clickedScroll), + cb(clickedScroll), + cb(clickedScroll), + cb(clickedScroll), + cb(clickedScroll), + cb(clickedScroll), + cb(clickedScroll), + cb(clickedScroll), + cb(clickedScroll), + cb(clickedUnk23), + cb(clickedUnk23), + cb(clickedUnk23), + cb(clickedUnk23), + cb(clickedUnk24), + cb(clickedUnk25), + cb(clickedUnk25), + cb(clickedOptions), + cb(clickedRestParty), + cb(clickedMoneyBox), + cb(clickedCompass), + cb(clickedAutomap), + cb(clickedLamp), + cb(clickedUnk32), + }; +#undef cb + + button->buttonCallback = buttonCallbacks[index]; } const ScreenDim Screen_LoK::_screenDimTable[] = { @@ -2627,10 +2800,6 @@ void GUI_LoL::initStaticData() { } -void LoLEngine::initButtonList() { - -} - const ScreenDim Screen_LoL::_screenDimTable[] = { { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, // Taken from Intro { 0x08, 0x48, 0x18, 0x38, 0xFE, 0x01, 0x00, 0x00 }, diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp index d5d287a661..b85d12710a 100644 --- a/engines/kyra/text_lol.cpp +++ b/engines/kyra/text_lol.cpp @@ -97,8 +97,8 @@ void TextDisplayer_LoL::setupField(bool mode) { void TextDisplayer_LoL::expandField() { if (_vm->textEnabled()) { - _vm->_restorePalette = 0; - _vm->_updateCharV4 = 0; + _vm->_fadeText = false; + _vm->_textColourFlag = 0; //_vm->toggleGuiUnk(11, 0); _screen->clearDim(3); _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _pageBuffer1); @@ -137,30 +137,32 @@ void TextDisplayer_LoL::setAnimParameters(const char *str, int x, uint8 col1, ui } } -void TextDisplayer_LoL::play(int dim, char *str, EMCState *script, int16 *paramList, int16 paramIndex) { +void TextDisplayer_LoL::playDialogue(int dim, char *str, EMCState *script, int16 *paramList, int16 paramIndex) { memcpy(_curPara, _stringParameters, 15 * sizeof(char*)); //char *cmds = _curPara[0]; + _colour1prot = false; if (dim == 3) { if (_vm->_updateFlags & 2) { _screen->clearDim(4); dim = _screen->curDimIndex(); _colour1 = 254; + _colour1prot = true; } else { _screen->clearDim(3); dim = _screen->curDimIndex(); _colour1 = 192; - uint8 col[3]; - _screen->loadColour254(col); - _screen->setPaletteIndex(192, col[0], col[1], col[2]); + _colour1prot = true; + _screen->copyColour(192, 254); //toggleGuiUnk(11, 1); - _vm->_updateCharV4 = 0; - _vm->_restorePalette = 0; + _vm->_textColourFlag = 0; + _vm->_fadeText = false; } } else { _screen->setScreenDim(dim); _colour1 = 254; + _colour1prot = true; } int cp = _screen->setCurPage(0); @@ -188,7 +190,50 @@ void TextDisplayer_LoL::play(int dim, char *str, EMCState *script, int16 *paramL _screen->setCurPage(cp); _screen->setFont(of); - _vm->_restorePalette = 0; + _vm->_fadeText = false; +} + +void TextDisplayer_LoL::printMessage(uint16 flags, char *str, ...) { + static uint8 textColours[] = { 0xfe, 0xa2, 0x84, 0x97, 0x9F }; + static uint8 soundEffect[] = { 0x0B, 0x00, 0x2B, 0x1B, 0x00 }; + if (flags & 4) + flags ^= 4; + else + _vm->updatePortraits(); + + uint16 col = textColours[flags & 0x7fff]; + + int od = _screen->curDimIndex(); + + if (_vm->_updateFlags & 2) { + _screen->setScreenDim(4); + _screen->clearCurDim(); + } else { + _screen->setScreenDim(3); + _screen->clearCurDim(); + _screen->copyColour(192, col); + //toggleGuiUnk(11, 1); + } + + _colour1 = 192; + _colour1prot = true; + + va_list args; + va_start(args, str); + + vsnprintf((char*) _buffer, 240, str, args); + + va_end(args); + + displayText(str); + + _screen->setScreenDim(od); + + if (!(flags & 0x8000) && soundEffect[flags]) + _vm->sound()->playSoundEffect(soundEffect[flags]); + + _vm->_textColourFlag = flags & 0x7fff; + _vm->_fadeText = false; } bool TextDisplayer_LoL::preprocessString(char *str, EMCState *script, int16 *paramList, int16 paramIndex) { @@ -322,7 +367,8 @@ void TextDisplayer_LoL::displayText(char *str, ...) { memset(_ctrl, 0, 3); - _colour1 = _screen->_curDim->unk8; + if (!_colour1prot) + _colour1 = _screen->_curDim->unk8; _colour2 = _screen->_curDim->unkA; _posX = _screen->_curDim->unkC; _posY = _screen->_curDim->unkE; diff --git a/engines/kyra/text_lol.h b/engines/kyra/text_lol.h index e88242a973..d921dacb0b 100644 --- a/engines/kyra/text_lol.h +++ b/engines/kyra/text_lol.h @@ -44,7 +44,8 @@ public: void setupField(bool mode); void expandField(); - void play(int dim, char *str, EMCState *script, int16 *paramList, int16 paramIndex); + void playDialogue(int dim, char *str, EMCState *script, int16 *paramList, int16 paramIndex); + void printMessage(uint16 colSnd, char *str, ...); int16 _scriptParameter; @@ -90,6 +91,7 @@ private: uint8 _posY; uint8 _colour1; uint8 _colour2; + bool _colour1prot; uint8 *_pageBuffer1; uint8 *_pageBuffer2; -- cgit v1.2.3