Initial commit
This commit is contained in:
369
engines/asylum/puzzles/wheel.cpp
Normal file
369
engines/asylum/puzzles/wheel.cpp
Normal file
@@ -0,0 +1,369 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "asylum/puzzles/wheel.h"
|
||||
|
||||
#include "asylum/resources/special.h"
|
||||
#include "asylum/resources/worldstats.h"
|
||||
|
||||
#include "asylum/system/cursor.h"
|
||||
#include "asylum/system/graphics.h"
|
||||
#include "asylum/system/screen.h"
|
||||
|
||||
#include "asylum/views/scene.h"
|
||||
|
||||
#include "asylum/asylum.h"
|
||||
|
||||
namespace Asylum {
|
||||
|
||||
const GameFlag puzzleWheelFlags[32] = {
|
||||
kGameFlag253, kGameFlag257, kGameFlag259, kGameFlag254, kGameFlag258,
|
||||
kGameFlag260, kGameFlag253, kGameFlag255, kGameFlag259, kGameFlag254,
|
||||
kGameFlag256, kGameFlag260, kGameFlag253, kGameFlag255, kGameFlag257,
|
||||
kGameFlag254, kGameFlag256, kGameFlag258, kGameFlag255, kGameFlag257,
|
||||
kGameFlag259, kGameFlag256, kGameFlag258, kGameFlag260, kGameFlag253,
|
||||
kGameFlag254, kGameFlag255, kGameFlag256, kGameFlag257, kGameFlag258,
|
||||
kGameFlag259, kGameFlag260
|
||||
};
|
||||
|
||||
const uint32 puzzleWheelContacts[24] = {
|
||||
1, 5, 7, 2, 6,
|
||||
8, 1, 3, 7, 2,
|
||||
4, 8, 1, 3, 5,
|
||||
2, 4, 6, 3, 5,
|
||||
7, 4, 6, 8
|
||||
};
|
||||
|
||||
const uint32 puzzleWheelSparks[8] = {
|
||||
0, 6, 5, 4, 1, 3, 7, 2
|
||||
};
|
||||
|
||||
const uint32 puzzleWheelClockResourceIndexes[16] = {
|
||||
39, 40, 42, 44, 46,
|
||||
48, 50, 52, 38, 41,
|
||||
43, 45, 47, 49, 51,
|
||||
53
|
||||
};
|
||||
|
||||
const int16 puzzleWheelPoints[56][2] = {
|
||||
{ 0, 0}, { 0, 0}, { 0, 0}, {250, 254}, {122, 24}, {208, 68}, {238, 160},
|
||||
{218, 234}, {162, 228}, { 71, 222}, { 22, 165}, { 35, 70}, {278, 0}, {536, 146},
|
||||
{122, 24}, {208, 68}, {238, 160}, {218, 234}, {162, 228}, { 71, 222}, { 22, 165},
|
||||
{ 35, 70}, {342, 87}, {342, 87}, {342, 87}, {342, 87}, {342, 87}, {342, 87},
|
||||
{342, 87}, {342, 87}, {358, 268}, {342, 87}, {342, 87}, {342, 87}, {342, 87},
|
||||
{342, 87}, {342, 87}, {342, 87}, {342, 87}, {342, 87}, {342, 87}, {342, 87},
|
||||
{342, 87}, {342, 87}, {342, 87}, {342, 87}, {342, 87}, {536, 146}, {406, 106},
|
||||
{402, 217}, {369, 128}, {368, 197}, {452, 184}, {470, 144}, {442, 116}, {347, 166}
|
||||
};
|
||||
|
||||
const int16 puzzleWheelRects[4][4] = {
|
||||
{425, 268, 491, 407}, {358, 268, 424, 407}, {561, 251, 594, 324}, {280, 276, 310, 400}
|
||||
};
|
||||
|
||||
PuzzleWheel::PuzzleWheel(AsylumEngine *engine) : Puzzle(engine) {
|
||||
_currentRect = -1;
|
||||
_resourceIndex = 0;
|
||||
_resourceIndexClock = 0;
|
||||
_resourceIndexLever = 13;
|
||||
|
||||
_frameIndexWheel = 0;
|
||||
memset(&_frameIndexes, 0, sizeof(_frameIndexes));
|
||||
memset(&_frameIndexesSparks, -1, sizeof(_frameIndexesSparks));
|
||||
|
||||
_showTurnedClock = false;
|
||||
_turnWheelRight = false;
|
||||
_moveLever = false;
|
||||
_moveChain = false;
|
||||
}
|
||||
|
||||
PuzzleWheel::~PuzzleWheel() {
|
||||
}
|
||||
|
||||
void PuzzleWheel::saveLoadWithSerializer(Common::Serializer &s) {
|
||||
s.syncAsSint32LE(_resourceIndex);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Event Handling
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool PuzzleWheel::init(const AsylumEvent &) {
|
||||
getSpecial()->reset(false);
|
||||
|
||||
getScreen()->setPalette(getWorld()->graphicResourceIds[1]);
|
||||
getScreen()->setGammaLevel(getWorld()->graphicResourceIds[1]);
|
||||
|
||||
updateCursor();
|
||||
getCursor()->show();
|
||||
|
||||
_currentRect = -2;
|
||||
|
||||
memset(&_frameIndexesSparks, -1, sizeof(_frameIndexesSparks));
|
||||
|
||||
for (uint32 i = 0; i < 8; i++) {
|
||||
if (_vm->isGameFlagSet((GameFlag)(kGameFlag253 + i)))
|
||||
_frameIndexes[i + 1] = GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[i + 14]) - 1;
|
||||
else
|
||||
_frameIndexes[i + 1] = GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[i + 4]) - 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PuzzleWheel::updateScreen() {
|
||||
getScreen()->clearGraphicsInQueue();
|
||||
getScreen()->draw(getWorld()->graphicResourceIds[0]);
|
||||
|
||||
// Blinking red light
|
||||
getScreen()->draw(getWorld()->graphicResourceIds[12], (uint32)_frameIndexes[11], &puzzleWheelPoints[12]);
|
||||
_frameIndexes[11] = (_frameIndexes[11] + 1) % (int32)GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[12]);
|
||||
|
||||
// Clock
|
||||
if (_showTurnedClock)
|
||||
getScreen()->draw(getWorld()->graphicResourceIds[_resourceIndexClock], (uint32)_frameIndexes[9], Common::Point(342, 87));
|
||||
else
|
||||
getScreen()->draw(getWorld()->graphicResourceIds[_resourceIndex + 22], 0, Common::Point(342, 87));
|
||||
|
||||
// Chain
|
||||
getScreen()->draw(getWorld()->graphicResourceIds[3], (uint32)_frameIndexes[0], &puzzleWheelPoints[3]);
|
||||
|
||||
// Update chain frame index
|
||||
if (_moveChain) {
|
||||
if (!_frameIndexes[0]) {
|
||||
getCursor()->hide();
|
||||
getSound()->playSound(getWorld()->graphicResourceIds[65]);
|
||||
}
|
||||
|
||||
_frameIndexes[0] = (_frameIndexes[0] + 1) % (int32)GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[3]);
|
||||
|
||||
if (!_frameIndexes[0]) {
|
||||
closeLocks();
|
||||
_moveChain = false;
|
||||
getCursor()->show();
|
||||
}
|
||||
}
|
||||
|
||||
// Locks
|
||||
uint32 frameIndex = 1;
|
||||
for (uint32 i = 0; i < 8; i++) {
|
||||
ResourceId resourceIndex = 0;
|
||||
uint32 pointIndex = 0;
|
||||
|
||||
if (_vm->isGameFlagSet((GameFlag)(kGameFlag253 + i))) {
|
||||
resourceIndex = 14 + i;
|
||||
pointIndex = 10 + (4 + i);
|
||||
} else {
|
||||
resourceIndex = 4 + i;
|
||||
pointIndex = 4 + i;
|
||||
}
|
||||
|
||||
getScreen()->draw(getWorld()->graphicResourceIds[resourceIndex], (uint32)_frameIndexes[frameIndex], &puzzleWheelPoints[pointIndex]);
|
||||
|
||||
if (_frameIndexes[frameIndex] != (int32)GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[resourceIndex]) - 1)
|
||||
++_frameIndexes[frameIndex];
|
||||
|
||||
++frameIndex;
|
||||
}
|
||||
|
||||
// Sparks
|
||||
for (uint32 i = 0; i < 8; i++) {
|
||||
if (_frameIndexesSparks[i] >= 0) {
|
||||
getScreen()->draw(getWorld()->graphicResourceIds[57 + i], (uint32)_frameIndexesSparks[i], &puzzleWheelPoints[48 + i]);
|
||||
|
||||
if (_frameIndexesSparks[i] == (int32)GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[57 + i]) - 1)
|
||||
_frameIndexesSparks[i] = -1;
|
||||
else
|
||||
++_frameIndexesSparks[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Lever
|
||||
if (_resourceIndexLever == 13)
|
||||
getScreen()->draw(getWorld()->graphicResourceIds[_resourceIndexLever], (uint32)_frameIndexes[10], &puzzleWheelPoints[13]);
|
||||
else if (_resourceIndexLever == 54)
|
||||
getScreen()->draw(getWorld()->graphicResourceIds[_resourceIndexLever], (uint32)_frameIndexes[10], &puzzleWheelPoints[47]);
|
||||
|
||||
// Update lever frame index
|
||||
if (_moveLever) {
|
||||
if (!_frameIndexes[10] && _resourceIndexLever == 13) {
|
||||
getCursor()->hide();
|
||||
getSound()->playSound(getWorld()->graphicResourceIds[67]);
|
||||
}
|
||||
|
||||
_frameIndexes[10] = (_frameIndexes[10] + 1) % (int32)GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[_resourceIndexLever]);
|
||||
|
||||
if (!_frameIndexes[10]) {
|
||||
if (_resourceIndexLever == 54) {
|
||||
_resourceIndexLever = 13;
|
||||
toggleLocks();
|
||||
_moveLever = false;
|
||||
getCursor()->show();
|
||||
} else {
|
||||
_resourceIndexLever = 54;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wheel
|
||||
getScreen()->draw(getWorld()->graphicResourceIds[30], _frameIndexWheel, &puzzleWheelPoints[30]);
|
||||
|
||||
// Update wheel frame index
|
||||
if (_showTurnedClock) {
|
||||
if (!_frameIndexes[9]) {
|
||||
getCursor()->hide();
|
||||
getSound()->playSound(getWorld()->graphicResourceIds[66]);
|
||||
}
|
||||
|
||||
uint32 frameCountWheel = GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[30]);
|
||||
if (_turnWheelRight)
|
||||
_frameIndexWheel = (_frameIndexWheel + 1) % frameCountWheel;
|
||||
else
|
||||
_frameIndexWheel = (_frameIndexWheel + frameCountWheel - 1) % frameCountWheel;
|
||||
|
||||
_frameIndexes[9] = (_frameIndexes[9] + 1) % (int32)GraphicResource::getFrameCount(_vm, getWorld()->graphicResourceIds[_resourceIndexClock]);
|
||||
|
||||
if (!_frameIndexes[9]) {
|
||||
_showTurnedClock = false;
|
||||
getCursor()->show();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Show elements on screen
|
||||
getScene()->drawRain();
|
||||
|
||||
// Check for completion
|
||||
checkFlags();
|
||||
}
|
||||
|
||||
bool PuzzleWheel::mouseLeftDown(const AsylumEvent &) {
|
||||
switch (findRect()) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0: // Wheel right
|
||||
_frameIndexes[9] = 0;
|
||||
_turnWheelRight = true;
|
||||
_showTurnedClock = true;
|
||||
|
||||
updateIndex();
|
||||
break;
|
||||
|
||||
case 1: // Wheel left
|
||||
_frameIndexes[9] = 0;
|
||||
_turnWheelRight = false;
|
||||
_showTurnedClock = true;
|
||||
|
||||
updateIndex();
|
||||
break;
|
||||
|
||||
case 2: // Lever
|
||||
_moveLever = true;
|
||||
break;
|
||||
|
||||
case 3: // Chain
|
||||
_moveChain = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PuzzleWheel::exitPuzzle() {
|
||||
getScreen()->clear();
|
||||
_vm->switchEventHandler(getScene());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void PuzzleWheel::updateCursor() {
|
||||
int32 index = findRect();
|
||||
|
||||
if (_currentRect != index) {
|
||||
_currentRect = index;
|
||||
|
||||
getCursor()->set(getWorld()->graphicResourceIds[2], -1, (index == -1) ? kCursorAnimationNone : kCursorAnimationMirror);
|
||||
}
|
||||
}
|
||||
|
||||
int32 PuzzleWheel::findRect() {
|
||||
for (uint32 i = 0; i < ARRAYSIZE(puzzleWheelRects); i++) {
|
||||
if (_vm->rectContains(&puzzleWheelRects[i], getCursor()->position()))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void PuzzleWheel::updateIndex() {
|
||||
if (_turnWheelRight) {
|
||||
_resourceIndexClock = puzzleWheelClockResourceIndexes[_resourceIndex];
|
||||
_resourceIndex = (_resourceIndex + 7) % ~7;
|
||||
} else {
|
||||
_resourceIndexClock = puzzleWheelClockResourceIndexes[_resourceIndex + 8];
|
||||
_resourceIndex = (_resourceIndex + 1) % ~7;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PuzzleWheel::checkFlags() {
|
||||
for (uint32 i = 0; i < 8; i++)
|
||||
if (!_vm->isGameFlagSet(puzzleWheelFlags[i]))
|
||||
return;
|
||||
|
||||
_vm->setGameFlag(kGameFlag261);
|
||||
getScreen()->clear();
|
||||
_vm->switchEventHandler(getScene());
|
||||
}
|
||||
|
||||
void PuzzleWheel::closeLocks() {
|
||||
for (uint32 i = 0; i < 8; i++) {
|
||||
if (!_vm->isGameFlagSet(puzzleWheelFlags[24 + i]))
|
||||
continue;
|
||||
|
||||
getSound()->playSound(getWorld()->graphicResourceIds[69]);
|
||||
_vm->clearGameFlag(puzzleWheelFlags[24 + i]);
|
||||
_frameIndexes[i + 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PuzzleWheel::toggleLocks() {
|
||||
memset(&_frameIndexesSparks, -1, sizeof(_frameIndexesSparks));
|
||||
|
||||
for (int32 i = 0; i < 3; i++) {
|
||||
_vm->toggleGameFlag(puzzleWheelFlags[i + 3 * _resourceIndex]);
|
||||
|
||||
// Update lock frame indexes
|
||||
_frameIndexes[puzzleWheelContacts[i + 3 * _resourceIndex]] = 0;
|
||||
|
||||
// Update sparks frame indexes
|
||||
_frameIndexesSparks[puzzleWheelSparks[puzzleWheelContacts[i + 3 * _resourceIndex] - 1]] = 0;
|
||||
|
||||
if (_vm->isGameFlagSet(puzzleWheelFlags[i]))
|
||||
getSound()->playSound(getWorld()->graphicResourceIds[68]);
|
||||
else
|
||||
getSound()->playSound(getWorld()->graphicResourceIds[69]);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Asylum
|
||||
Reference in New Issue
Block a user