aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mohawk')
-rw-r--r--engines/mohawk/graphics.cpp4
-rw-r--r--engines/mohawk/graphics.h1
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp214
-rw-r--r--engines/mohawk/myst_stacks/myst.h8
4 files changed, 218 insertions, 9 deletions
diff --git a/engines/mohawk/graphics.cpp b/engines/mohawk/graphics.cpp
index 30478bf74b..64968723bd 100644
--- a/engines/mohawk/graphics.cpp
+++ b/engines/mohawk/graphics.cpp
@@ -517,6 +517,10 @@ void MystGraphics::drawRect(Common::Rect rect, RectState state) {
_mainScreen->frameRect(rect, _pixelFormat.RGBToColor(255, 0, 0));
}
+void MystGraphics::drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color) {
+ _mainScreen->drawLine(p1.x, p1.y, p2.x, p2.y, color);
+}
+
RivenGraphics::RivenGraphics(MohawkEngine_Riven* vm) : GraphicsManager(), _vm(vm) {
_bitmapDecoder = new MohawkBitmap();
diff --git a/engines/mohawk/graphics.h b/engines/mohawk/graphics.h
index e872291d4d..f027f98d9f 100644
--- a/engines/mohawk/graphics.h
+++ b/engines/mohawk/graphics.h
@@ -115,6 +115,7 @@ public:
void updateScreen();
void runTransition(uint16 type, Common::Rect rect, uint16 steps, uint16 delay);
void drawRect(Common::Rect rect, RectState state);
+ void drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color);
protected:
MohawkSurface *decodeImage(uint16 id);
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index dddfe76fb5..a1dce9e3ed 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -32,6 +32,7 @@
#include "mohawk/video.h"
#include "mohawk/myst_stacks/myst.h"
+#include "graphics/colormasks.h"
#include "gui/message.h"
namespace Mohawk {
@@ -238,6 +239,55 @@ uint16 MystScriptParser_Myst::getVar(uint16 var) {
return myst.rocketshipMarkerSwitch;
case 12: // Clock tower gears bridge
return myst.clockTowerBridgeOpen;
+ case 13: // Tower in right position
+ return myst.towerRotationAngle == 271
+ || myst.towerRotationAngle == 83
+ || myst.towerRotationAngle == 129
+ || myst.towerRotationAngle == 152;
+ case 14: // Tower Solution (Key) Plaque
+ switch (myst.towerRotationAngle) {
+ case 271:
+ return 1;
+ case 83:
+ return 2;
+ case 129:
+ return 3;
+ case 152:
+ return 4;
+ default:
+ return 0;
+ }
+ case 15: // Tower Window (Book) View
+ switch (myst.towerRotationAngle) {
+ case 271:
+ return 1;
+ case 83:
+ if (myst.gearsOpen)
+ return 6;
+ else
+ return 2;
+ case 129:
+ if (myst.shipState)
+ return 5;
+ else
+ return 3;
+ case 152:
+ return 4;
+ default:
+ return 0;
+ }
+ case 16: // Tower Window (Book) View From Ladder Top
+ if (myst.towerRotationAngle != 271
+ && myst.towerRotationAngle != 83
+ && myst.towerRotationAngle != 129) {
+ if (myst.towerRotationAngle == 152)
+ return 2;
+ else
+ return 0;
+ } else {
+ return 1;
+ }
+
case 23: // Fireplace Pattern Correct
return _fireplaceLines[0] == 195
&& _fireplaceLines[1] == 107
@@ -606,11 +656,63 @@ void MystScriptParser_Myst::opcode_105(uint16 op, uint16 var, uint16 argc, uint1
}
void MystScriptParser_Myst::o_towerRotationStart(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ MystVariables::Myst &myst = _vm->_saveLoad->_v->myst;
+
_towerRotationMapClicked = true;
+ _towerRotationSpeed = 0;
+
+ _vm->_cursor->setCursor(700);
+
+ const Common::Point center = Common::Point(383, 124);
+ Common::Point end = towerRotationMapComputeCoords(center, myst.towerRotationAngle);
+ towerRotationMapComputeAngle();
+ towerRotationMapDrawLine(center, end);
+
+ _vm->_sound->playSound(5378, Audio::Mixer::kMaxChannelVolume, true);
}
void MystScriptParser_Myst::o_towerRotationEnd(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ MystVariables::Myst &myst = _vm->_saveLoad->_v->myst;
+
_towerRotationMapClicked = false;
+
+ _vm->_cursor->hideCursor();
+
+ uint16 cnt = 0;
+ _vm->_sound->replaceSound(6378);
+ while (_vm->_sound->isPlaying(6378)) {
+ _vm->_system->delayMillis(100);
+
+ // Blink tower rotation label while sound is playing
+ cnt = (cnt +1) % 14;
+ if (cnt == 7)
+ _towerRotationMapLabel->drawConditionalDataToScreen(0);
+ else if (cnt == 0)
+ _towerRotationMapLabel->drawConditionalDataToScreen(1);
+ }
+
+ _towerRotationMapLabel->drawConditionalDataToScreen(0);
+
+ _vm->_cursor->showCursor();
+
+ // Set angle value to expected value
+ if (myst.towerRotationAngle >= 265
+ && myst.towerRotationAngle <= 277
+ && myst.rocketshipMarkerSwitch) {
+ myst.towerRotationAngle = 271;
+ } else if (myst.towerRotationAngle >= 77
+ && myst.towerRotationAngle <= 89
+ && myst.gearsMarkerSwitch) {
+ myst.towerRotationAngle = 83;
+ } else if (myst.towerRotationAngle >= 123
+ && myst.towerRotationAngle <= 135
+ && myst.dockMarkerSwitch) {
+ myst.towerRotationAngle = 129;
+ } else if (myst.towerRotationAngle >= 146
+ && myst.towerRotationAngle <= 158
+ && myst.cabinMarkerSwitch) {
+ myst.towerRotationAngle = 152;
+ }
}
void MystScriptParser_Myst::opcode_109(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -1710,14 +1812,7 @@ void MystScriptParser_Myst::towerRotationMap_run() {
_towerRotationMapInitialized = true;
_vm->_sound->playSound(4378);
- // Draw library
- _vm->redrawArea(304, false);
-
- // Draw other resources
- for (uint i = 1; i <= 10; i++) {
- MystResourceType8 *resource = static_cast<MystResourceType8 *>(_vm->_resources[i]);
- _vm->redrawResource(resource, false);
- }
+ towerRotationDrawBuildings();
// Draw to screen
_vm->_gfx->updateScreen();
@@ -1726,7 +1821,7 @@ void MystScriptParser_Myst::towerRotationMap_run() {
uint32 time = _vm->_system->getMillis();
if (time > _startTime) {
if (_towerRotationMapClicked) {
- // TODO: handle tower rotation
+ towerRotationMapRotate();
_startTime = time + 100;
} else {
// Blink tower
@@ -1746,6 +1841,107 @@ void MystScriptParser_Myst::o_towerRotationMap_init(uint16 op, uint16 var, uint1
_towerRotationMapClicked = false;
}
+void MystScriptParser_Myst::towerRotationDrawBuildings() {
+ // Draw library
+ _vm->redrawArea(304, false);
+
+ // Draw other resources
+ for (uint i = 1; i <= 10; i++) {
+ MystResourceType8 *resource = static_cast<MystResourceType8 *>(_vm->_resources[i]);
+ _vm->redrawResource(resource, false);
+ }
+}
+
+uint16 MystScriptParser_Myst::towerRotationMapComputeAngle() {
+ MystVariables::Myst &myst = _vm->_saveLoad->_v->myst;
+
+ _towerRotationSpeed++;
+ if (_towerRotationSpeed >= 7)
+ _towerRotationSpeed = 7;
+ else
+ _towerRotationSpeed++;
+
+ myst.towerRotationAngle = (myst.towerRotationAngle + _towerRotationSpeed) % 360;
+ uint16 angle = myst.towerRotationAngle;
+ _towerRotationOverSpot = false;
+
+ if (angle >= 265 && angle <= 277
+ && myst.rocketshipMarkerSwitch) {
+ angle = 271;
+ _towerRotationOverSpot = true;
+ _towerRotationSpeed = 1;
+ } else if (angle >= 77 && angle <= 89
+ && myst.gearsMarkerSwitch) {
+ angle = 83;
+ _towerRotationOverSpot = true;
+ _towerRotationSpeed = 1;
+ } else if (angle >= 123 && angle <= 135
+ && myst.dockMarkerSwitch) {
+ angle = 129;
+ _towerRotationOverSpot = true;
+ _towerRotationSpeed = 1;
+ } else if (angle >= 146 && angle <= 158
+ && myst.cabinMarkerSwitch) {
+ angle = 152;
+ _towerRotationOverSpot = true;
+ _towerRotationSpeed = 1;
+ }
+
+ return angle;
+}
+
+Common::Point MystScriptParser_Myst::towerRotationMapComputeCoords(const Common::Point &center, uint16 angle) {
+ Common::Point end;
+
+ // Polar to rect coords
+ double radians = angle * PI / 180.0;
+ end.x = center.x + cos(radians) * 310.0;
+ end.y = center.y + sin(radians) * 310.0;
+
+ return end;
+}
+
+void MystScriptParser_Myst::towerRotationMapDrawLine(const Common::Point &center, const Common::Point &end) {
+ Graphics::PixelFormat pf = _vm->_system->getScreenFormat();
+ uint32 color = 0;
+
+ if (!_towerRotationOverSpot)
+ color = pf.RGBToColor(0xFF, 0xFF, 0xFF); // White
+ else
+ color = pf.RGBToColor(0xFF, 0, 0); // Red
+
+ const Common::Rect rect = Common::Rect(106, 42, 459, 273);
+
+ Common::Rect src;
+ src.left = rect.left;
+ src.top = 333 - rect.bottom;
+ src.right = rect.right;
+ src.bottom = 333 - rect.top;
+
+ // Redraw background
+ _vm->_gfx->copyImageSectionToScreen(_vm->getCardBackgroundId(), src, rect);
+
+ // Draw buildings
+ towerRotationDrawBuildings();
+
+ // Draw tower
+ _towerRotationMapTower->drawConditionalDataToScreen(0, false);
+
+ // Draw label
+ _towerRotationMapLabel->drawConditionalDataToScreen(1, false);
+
+ // Draw line
+ _vm->_gfx->drawLine(center, end, color);
+ _vm->_gfx->updateScreen();
+}
+
+void MystScriptParser_Myst::towerRotationMapRotate() {
+ const Common::Point center = Common::Point(383, 124);
+ uint16 angle = towerRotationMapComputeAngle();
+ Common::Point end = towerRotationMapComputeCoords(center, angle);
+ towerRotationMapDrawLine(center, end);
+}
+
void MystScriptParser_Myst::o_forechamberDoor_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
// Used for Card 4138 (Dock Forechamber Door)
// Set forechamber door to closed
diff --git a/engines/mohawk/myst_stacks/myst.h b/engines/mohawk/myst_stacks/myst.h
index 2a6e812b8a..b832a8da51 100644
--- a/engines/mohawk/myst_stacks/myst.h
+++ b/engines/mohawk/myst_stacks/myst.h
@@ -203,7 +203,9 @@ private:
uint16 _towerRotationMapInitialized; // 292
MystResourceType11 *_towerRotationMapTower; // 108
MystResourceType8 *_towerRotationMapLabel; // 112
+ uint16 _towerRotationSpeed; // 124
bool _towerRotationMapClicked; // 132
+ bool _towerRotationOverSpot; // 136
void generatorRedrawRocket();
void generatorButtonValue(MystResource *button, uint16 &offset, uint16 &value);
@@ -219,6 +221,12 @@ private:
void clockWheelStartTurn(uint16 wheel);
void clockWheelTurn(uint16 var);
+
+ void towerRotationMapRotate();
+ void towerRotationDrawBuildings();
+ uint16 towerRotationMapComputeAngle();
+ Common::Point towerRotationMapComputeCoords(const Common::Point &center, uint16 angle);
+ void towerRotationMapDrawLine(const Common::Point &center, const Common::Point &end);
};
} // End of namespace Mohawk