diff options
Diffstat (limited to 'engines/igor/parts/part_23.cpp')
-rw-r--r-- | engines/igor/parts/part_23.cpp | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/engines/igor/parts/part_23.cpp b/engines/igor/parts/part_23.cpp new file mode 100644 index 0000000000..e165ad5b1d --- /dev/null +++ b/engines/igor/parts/part_23.cpp @@ -0,0 +1,304 @@ +/* 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 "igor/igor.h" + +namespace Igor { + +static const uint8 PART_23_ANIM_DATA_1[4] = { 0, 4, 1, 11 }; + +void IgorEngine::PART_23_EXEC_ACTION(int action) { + switch (action) { + case 101: + _currentPart = 280; + break; + case 102: + ADD_DIALOGUE_TEXT(201, 2); + SET_DIALOGUE_TEXT(1, 1); + startIgorDialogue(); + break; + case 105: + PART_23_ACTION_105(); + break; + case 106: + ADD_DIALOGUE_TEXT(205, 1); + SET_DIALOGUE_TEXT(1, 1); + startIgorDialogue(); + break; + case 107: + PART_23_ACTION_107(); + break; + case 108: + PART_23_ACTION_108(); + break; + case 109: + _currentPart = 300; + break; + case 110: + ADD_DIALOGUE_TEXT(203, 1); + ADD_DIALOGUE_TEXT(204, 1); + SET_DIALOGUE_TEXT(1, 2); + startIgorDialogue(); + break; + case 111: + ADD_DIALOGUE_TEXT(208, 2); + SET_DIALOGUE_TEXT(1, 1); + startIgorDialogue(); + break; + case 112: + ADD_DIALOGUE_TEXT(210, 1); + ADD_DIALOGUE_TEXT(211, 1); + SET_DIALOGUE_TEXT(1, 2); + startIgorDialogue(); + break; + case 113: + ADD_DIALOGUE_TEXT(212, 1); + SET_DIALOGUE_TEXT(1, 1); + startIgorDialogue(); + break; + default: + error("PART_23_EXEC_ACTION unhandled action %d", action); + break; + } +} + +void IgorEngine::PART_23_ACTION_105() { + if (_objectsState[66] != 0) { + _roomObjectAreasTable[_screenLayer2[38633]].area = 1; + --_walkDataLastIndex; + buildWalkPathSimple(233, 132, 233, 120); + _walkDataCurrentIndex = 1; + _gameState.igorMoving = true; + waitForIgorMove(); + _currentPart = 190; + } +} + +void IgorEngine::PART_23_ACTION_107() { + if (_objectsState[66] == 1) { + EXEC_MAIN_ACTION(11); + } else { + const int offset = 23901; + for (int i = 2; i <= 3; ++i) { + for (int j = 0; j <= 53; ++j) { + memcpy(_screenVGA + j * 320 + offset, _animFramesBuffer + i * 1620 + j * 30 + 0x895, 30); + } + } + playSound(13, 1); + waitForTimer(100); + _objectsState[66] = 1; + PART_23_HELPER_1(1); + } +} + +void IgorEngine::PART_23_ACTION_108() { + if (_objectsState[66] == 0) { + EXEC_MAIN_ACTION(14); + } else { + const int offset = 23901; + for (int i = 2; i <= 3; ++i) { + for (int j = 0; j <= 53; ++j) { + memcpy(_screenVGA + j * 320 + offset, _animFramesBuffer + PART_23_ANIM_DATA_1[i] * 1620 + j * 30 + 0x895, 30); + } + } + playSound(14, 1); + waitForTimer(100); + _objectsState[66] = 0; + PART_23_HELPER_1(1); + } +} + +void IgorEngine::PART_23_UPDATE_ROOM_BACKGROUND() { + if (compareGameTick(29) || compareGameTick(61)) { + int rnd = getRandomNumber(11); + if (rnd <= 4) { + _gameState.unk10 = 1; + } else if (rnd <= 9) { + _gameState.unk10 = 2; + } else if (rnd == 10) { + if (_gameState.unk10 < 3) { + _gameState.unk10 = getRandomNumber(2) + 3; + } else { + _gameState.unk10 = getRandomNumber(2) + 1; + } + } + PART_23_HELPER_7(_gameState.unk10); + } +} + +void IgorEngine::PART_23_HELPER_1(int num) { + if (num == 1 || num == 255) { + if (_objectsState[66] == 0) { + PART_23_HELPER_2(1); + _roomActionsTable[4] = 6; + } else { + PART_23_HELPER_2(2); + _roomActionsTable[4] = 7; + } + } + PART_23_HELPER_3(); +} + +void IgorEngine::PART_23_HELPER_2(int frame) { + const int offset = 23907; + for (int i = 0; i <= 53; ++i) { + memcpy(_screenLayer1 + i * 320 + offset, _animFramesBuffer + (frame - 1) * 1296 + i * 24, 24); + } +} + +void IgorEngine::PART_23_HELPER_3() { + const int offset = 25763; + for (int i = 0; i <= 48; ++i) { + memcpy(_screenLayer1 + i * 320 + offset, _animFramesBuffer + i * 25 + 0xA20, 25); + } +} + +void IgorEngine::PART_23_HELPER_4() { + _walkData[0].setPos(233, 120, 3, 0); + _walkData[0].setDefaultScale(); + _walkDataLastIndex = 0; + _roomObjectAreasTable[_screenLayer2[38633]].area = 1; + buildWalkPathSimple(233, 120, 233, 137); + _roomObjectAreasTable[_screenLayer2[38633]].area = 0; + _walkData[_walkDataLastIndex].frameNum = 0; + _walkDataCurrentIndex = 1; + _gameState.igorMoving = true; + waitForIgorMove(); + if (_objectsState[59] == 0) { + for (int i = 0; i <= 53; ++i) { + for (int j = 0; j <= 23; ++j) { + uint8 color = _screenVGA[(i + 74) * 320 + j + 227]; + if (color >= 0xC0 && color <= 0xCF) { + _screenTempLayer[i * 100 + j] = color; + } else { + _screenTempLayer[i * 100 + j] = _animFramesBuffer[i * 24 + j]; + } + } + } + for (int i = 0; i <= 53; ++i) { + memcpy(_screenVGA + i * 320 + 23907, _screenTempLayer + i * 100, 24); + } + playSound(14, 1); + _objectsState[66] = 0; + PART_23_HELPER_1(1); + ADD_DIALOGUE_TEXT(206, 2); + SET_DIALOGUE_TEXT(1, 1); + startIgorDialogue(); + } +} + +void IgorEngine::PART_23_HELPER_5() { + _walkData[0].setPos(0, 134, 2, 0); + _walkData[0].setDefaultScale(); + _walkData[0].clipSkipX = 15; + _walkData[0].clipWidth = 15; + _walkDataLastIndex = 0; + _walkDataCurrentIndex = 1; + buildWalkPathSimple(0, 134, 100, 140); + _walkData[_walkDataLastIndex].frameNum = 0; + _gameState.igorMoving = true; + waitForIgorMove(); +} + +void IgorEngine::PART_23_HELPER_6() { + _walkData[0].setPos(319, 134, 4, 0); + _walkData[0].setDefaultScale(); + _walkData[0].clipWidth = 15; + _walkDataLastIndex = 0; + _walkDataCurrentIndex = 1; + buildWalkPathSimple(319, 134, 289, 134); + _walkData[_walkDataLastIndex].frameNum = 0; + _gameState.igorMoving = true; + waitForIgorMove(); +} + +void IgorEngine::PART_23_HELPER_7(int frame) { + _roomCursorOn = false; + for (int i = 0; i <= 18; ++i) { + for (int j = 0; j <= 14; ++j) { + int offset = (i + 80) * 320 + j + 162; + uint8 color = _screenVGA[offset]; + if ((color >= 192 && color <= 207) || color == 240 || color == 241) { + _screenTempLayer[i * 100 + j] = color; + } else { + _screenTempLayer[i * 100 + j] = _animFramesBuffer[frame * 285 + i * 15 + j + 0x271C]; + } + } + } + int offset = 25762; + for (int i = 0; i <= 18; ++i) { + memcpy(_screenVGA + i * 320 + offset, _screenTempLayer + i * 100, 15); + memcpy(_screenLayer1 + i * 320 + offset, _animFramesBuffer + frame * 285 + i * 15 + 0x271C, 15); + } + if (_dialogueCursorOn) { + _roomCursorOn = true; + } +} + +void IgorEngine::PART_23() { + _gameState.enableLight = 2; + loadRoomData(PAL_CollegeCorridorLucas, IMG_CollegeCorridorLucas, BOX_CollegeCorridorLucas, MSK_CollegeCorridorLucas, TXT_CollegeCorridorLucas); + static const int anm[] = { FRM_CollegeCorridorLucas1, FRM_CollegeCorridorLucas2, FRM_CollegeCorridorLucas3, FRM_CollegeCorridorLucas4, 0 }; + loadAnimData(anm); + loadActionData(DAT_CollegeCorridorLucas); + _roomDataOffsets = PART_23_ROOM_DATA_OFFSETS; + setRoomWalkBounds(15, 0, 319, 143); + SET_EXEC_ACTION_FUNC(1, &IgorEngine::PART_23_EXEC_ACTION); + _updateRoomBackground = &IgorEngine::PART_23_UPDATE_ROOM_BACKGROUND; + PART_23_HELPER_1(255); + memcpy(_screenVGA, _screenLayer1, 46080); + _currentAction.verb = kVerbWalk; + fadeInPalette(768); + if (_currentPart == 230) { + PART_23_HELPER_5(); + } else if (_currentPart == 231) { + PART_23_HELPER_6(); + } else if (_currentPart == 232) { + PART_23_HELPER_4(); + } + showCursor(); + _gameState.igorMoving = false; + while (_currentPart >= 230 && _currentPart <= 232) { + handleRoomInput(); + if (compareGameTick(1, 16)) { + handleRoomIgorWalk(); + } + if (compareGameTick(19, 32)) { + handleRoomDialogue(); + } + if (compareGameTick(4, 8)) { + handleRoomInventoryScroll(); + } + if (compareGameTick(1)) { + handleRoomLight(); + } + PART_23_UPDATE_ROOM_BACKGROUND(); + waitForTimer(); + } + fadeOutPalette(624); + _updateRoomBackground = 0; +} + +} // namespace Igor |