aboutsummaryrefslogtreecommitdiff
path: root/engines/titanic/star_control/star_camera.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/titanic/star_control/star_camera.cpp')
-rw-r--r--engines/titanic/star_control/star_camera.cpp606
1 files changed, 606 insertions, 0 deletions
diff --git a/engines/titanic/star_control/star_camera.cpp b/engines/titanic/star_control/star_camera.cpp
new file mode 100644
index 0000000000..2ccf2e3355
--- /dev/null
+++ b/engines/titanic/star_control/star_camera.cpp
@@ -0,0 +1,606 @@
+/* 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.
+ *
+ */
+
+#include "titanic/star_control/star_camera.h"
+#include "titanic/star_control/star_control_sub21.h"
+#include "titanic/star_control/star_control_sub22.h"
+#include "titanic/star_control/dmatrix.h"
+#include "titanic/star_control/fmatrix.h"
+#include "titanic/titanic.h"
+
+namespace Titanic {
+
+FMatrix *CStarCamera::_matrix1;
+FMatrix *CStarCamera::_matrix2;
+
+CStarCamera::CStarCamera(const CStar20Data *data) :
+ _matrixRow(-1), _handlerP(nullptr), _field108(0) {
+ setupHandler(data);
+}
+
+CStarCamera::CStarCamera(CStarControlSub13 *src) :
+ _matrixRow(-1), _handlerP(nullptr), _field108(0), _sub13(src) {
+}
+
+void CStarCamera::init() {
+ _matrix1 = nullptr;
+ _matrix2 = nullptr;
+}
+
+void CStarCamera::deinit() {
+ delete _matrix1;
+ delete _matrix2;
+ _matrix1 = nullptr;
+ _matrix2 = nullptr;
+}
+
+CStarCamera::~CStarCamera() {
+ deleteHandler();
+}
+
+void CStarCamera::proc2(const CStarControlSub13 *src) {
+ _sub13.copyFrom(src);
+}
+
+void CStarCamera::proc3(const CStar20Data *src) {
+ _handlerP->copyFrom(src);
+}
+
+void CStarCamera::setPosition(const FVector &v) {
+ if (!isLocked()) {
+ _sub13.setPosition(v);
+ set108();
+ }
+}
+
+void CStarCamera::proc5(const FVector &v) {
+ if (!isLocked())
+ _sub13.fn11(v);
+}
+
+void CStarCamera::proc6(int v) {
+ if (!isLocked())
+ _sub13.setC(v);
+}
+
+void CStarCamera::proc7(int v) {
+ if (!isLocked())
+ _sub13.set10(v);
+}
+
+void CStarCamera::proc8(int v) {
+ if (!isLocked())
+ _sub13.set14(v);
+}
+
+void CStarCamera::proc9(int v) {
+ if (!isLocked())
+ _sub13.set18(v);
+}
+
+void CStarCamera::proc10(int v) {
+ if (!isLocked())
+ _sub13.set1C(v);
+}
+
+void CStarCamera::proc11() {
+ if (!isLocked())
+ _sub13.fn12();
+}
+
+void CStarCamera::proc12(StarMode mode, double v2) {
+ if (!isLocked())
+ _sub13.fn13(mode, v2);
+}
+
+void CStarCamera::proc13(CStarControlSub13 *dest) {
+ *dest = _sub13;
+}
+
+void CStarCamera::proc14(FVector &v) {
+ FMatrix matrix = _sub13.getMatrix();
+ FVector vector = _sub13._position;
+
+ _handlerP->proc9(vector, v, matrix);
+}
+
+void CStarCamera::proc15(CErrorCode *errorCode) {
+ if (!_matrix1)
+ _matrix1 = new FMatrix();
+ if (!_matrix2)
+ _matrix2 = new FMatrix();
+
+ *_matrix1 = _sub13.getMatrix();
+ *_matrix2 = *_matrix1;
+
+ FVector v1 = _sub13._position;
+ FVector v2 = _sub13._position;
+ _handlerP->proc11(*errorCode, v2, *_matrix2);
+
+ if (v1 != v2) {
+ _sub13.setPosition(v2);
+ set108();
+ }
+
+ if (*_matrix1 != *_matrix2) {
+ _sub13.setMatrix(*_matrix2);
+ }
+}
+
+void CStarCamera::proc16() {
+ _handlerP->proc4();
+}
+
+void CStarCamera::proc17() {
+ _handlerP->proc5();
+}
+
+void CStarCamera::proc18() {
+ _handlerP->proc6();
+}
+
+void CStarCamera::proc19() {
+ _handlerP->proc7();
+}
+
+void CStarCamera::proc20(double factor) {
+ if (!isLocked())
+ _sub13.reposition(factor);
+}
+
+void CStarCamera::proc21(const FPose &pose) {
+ if (!isLocked()) {
+ _sub13.setPosition(pose);
+ set108();
+ }
+}
+
+void CStarCamera::proc22(FMatrix &m) {
+ if (!isLocked())
+ _sub13.fn15(m);
+}
+
+FPose CStarCamera::proc23() {
+ return _sub13.getSub1();
+}
+
+FPose CStarCamera::proc24() {
+ return _sub13.getSub2();
+}
+
+double CStarCamera::proc25() const {
+ return _sub13._field10;
+}
+
+double CStarCamera::proc26() const {
+ return _sub13._field14;
+}
+
+int CStarCamera::proc27() const {
+ return _sub13._field24;
+}
+
+FVector CStarCamera::proc28(int index, const FVector &src) {
+ FVector dest;
+ dest._x = ((_sub13._valArray[index] + src._x) * _sub13._centerVector._x)
+ / (_sub13._centerVector._y * src._z);
+ dest._y = src._y * _sub13._centerVector._x / (_sub13._centerVector._z * src._z);
+ dest._z = src._z;
+ return dest;
+}
+
+FVector CStarCamera::proc29(int index, const FVector &src) {
+ return _sub13.fn16(index, src);
+}
+
+FVector CStarCamera::proc30(int index, const FVector &v) {
+ return _sub13.fn17(index, v);
+}
+
+FVector CStarCamera::proc31(int index, const FVector &v) {
+ return _sub13.fn18(index, v);
+}
+
+void CStarCamera::setViewportPosition(const FPoint &angles) {
+ debug(DEBUG_INTERMEDIATE, "setViewportPosition %f %f", angles._x, angles._y);
+
+ if (isLocked())
+ return;
+
+ if (_matrixRow == -1) {
+ FPose subX(X_AXIS, angles._y);
+ FPose subY(Y_AXIS, angles._x);
+ FPose sub(subX, subY);
+ proc22(sub);
+ } else if (_matrixRow == 0) {
+ FVector row1 = _matrix._row1;
+ FPose subX(X_AXIS, angles._y);
+ FPose subY(Y_AXIS, angles._x);
+ FPose sub(subX, subY);
+
+ FMatrix m1 = _sub13.getMatrix();
+ FVector tempV1 = _sub13._position;
+ FVector tempV2, tempV3, tempV4, tempV5, tempV6;
+ tempV2._y = m1._row1._y * 100000.0;
+ tempV2._z = m1._row1._z * 100000.0;
+ tempV3._x = m1._row1._x * 100000.0 + tempV1._x;
+ tempV4._x = tempV3._x;
+ tempV3._y = tempV2._y + tempV1._y;
+ tempV4._y = tempV3._y;
+ tempV3._z = tempV2._z + tempV1._z;
+ tempV4._z = tempV3._z;
+ tempV2._x = m1._row2._x * 100000.0;
+ tempV2._y = m1._row2._y * 100000.0;
+ tempV2._z = m1._row2._z * 100000.0;
+ tempV2._x = m1._row3._x * 100000.0;
+ tempV2._y = m1._row3._y * 100000.0;
+ tempV2._z = m1._row3._z * 100000.0;
+ tempV2._x = tempV2._x + tempV1._x;
+ tempV2._y = tempV2._y + tempV1._y;
+ tempV2._z = tempV2._z + tempV1._z;
+ tempV3._x = tempV2._x + tempV1._x;
+ tempV3._y = tempV2._y + tempV1._y;
+ tempV5._x = tempV2._x;
+ tempV5._y = tempV2._y;
+ tempV3._z = tempV2._z + tempV1._z;
+ tempV5._z = tempV2._z;
+ tempV6._x = tempV3._x;
+ tempV6._y = tempV3._y;
+ tempV6._z = tempV3._z;
+ tempV1._x = tempV1._x - row1._x;
+ tempV1._y = tempV1._y - row1._y;
+ tempV1._z = tempV1._z - row1._z;
+ tempV4._x = tempV3._x - row1._x;
+ tempV4._y = tempV4._y - row1._y;
+ tempV4._z = tempV4._z - row1._z;
+ tempV5._x = tempV2._x - row1._x;
+
+ tempV5._y = tempV5._y - row1._y;
+ tempV5._z = tempV5._z - row1._z;
+ tempV6._x = tempV3._x - row1._x;
+ tempV6._y = tempV6._y - row1._y;
+ tempV6._z = tempV6._z - row1._z;
+
+ FVector modV1 = tempV1.fn5(sub);
+ FVector modV2 = tempV4.fn5(sub);
+ FVector modV3 = tempV5.fn5(sub);
+ FVector modV4 = tempV6.fn5(sub);
+ tempV1 = modV1;
+ tempV4 = modV2;
+ tempV5 = modV3;
+ tempV4 = modV4;
+
+ tempV2._x = tempV4._x - tempV1._x;
+ tempV2._y = tempV4._y - tempV1._y;
+ tempV2._z = tempV4._z - tempV1._z;
+ tempV4._x = tempV2._x;
+ tempV4._y = tempV2._y;
+ tempV2._x = tempV5._x - tempV1._x;
+ tempV4._z = tempV2._z;
+ tempV5._x = tempV2._x;
+ tempV2._y = tempV5._y - tempV1._y;
+ tempV5._y = tempV2._y;
+ tempV2._z = tempV5._z - tempV1._z;
+ tempV5._z = tempV2._z;
+ tempV2._x = tempV6._x - tempV1._x;
+ tempV2._y = tempV6._y - tempV1._y;
+ tempV2._z = tempV6._z - tempV1._z;
+ tempV6 = tempV2;
+
+ tempV4.normalize();
+ tempV5.normalize();
+ tempV6.normalize();
+ tempV1 += row1;
+
+ m1.set(tempV4, tempV5, tempV6);
+ _sub13.setMatrix(m1);
+ _sub13.setPosition(tempV1);
+ } else if (_matrixRow == 1) {
+ FVector tempV2;
+ DMatrix m1, m2, sub;
+ DVector mrow1, mrow2, mrow3;
+ DVector tempV1, diffV, multV, multV2, tempV3, tempV4, tempV5, tempV6, tempV7;
+ DVector tempV8, tempV9, tempV10, tempV11, tempV12;
+ DVector tempV13, tempV14, tempV15, tempV16;
+
+ DMatrix subX(0, _matrix._row1);
+ DMatrix subY(Y_AXIS, angles._y);
+
+ tempV1 = _matrix._row2 - _matrix._row1;
+ diffV = tempV1;
+ m1 = diffV.fn5();
+ m1 = m1.fn4(subX);
+ subX = m1.fn1();
+ subX = subX.fn4(subY);
+
+ FMatrix m3 = _sub13.getMatrix();
+ tempV2 = _sub13._position;
+ multV._x = m3._row1._x * 1000000.0;
+ multV._y = m3._row1._y * 1000000.0;
+ multV._z = m3._row1._z * 1000000.0;
+ tempV3._x = tempV2._x;
+ tempV3._y = tempV2._y;
+ tempV3._z = tempV2._z;
+ multV2._z = m3._row2._z * 1000000.0;
+
+ tempV1._x = multV._x + tempV3._x;
+ tempV1._y = multV._y + tempV3._y;
+ tempV1._z = multV._z + tempV3._z;
+ mrow3._z = 0.0;
+ mrow3._y = 0.0;
+ mrow3._x = 0.0;
+ multV2._x = m3._row2._x * 1000000.0;
+ multV2._y = m3._row2._y * 1000000.0;
+ mrow1 = tempV1;
+ multV = multV2 + tempV3;
+ mrow2 = multV;
+
+ tempV7._z = m3._row3._z * 1000000.0 + tempV3._z;
+ tempV7._y = m3._row3._y * 1000000.0 + tempV3._y;
+ tempV7._x = m3._row3._x * 1000000.0 + tempV3._x;
+
+ mrow3 = tempV8;
+ DVector *v = tempV3.fn1(tempV9, subX);
+ tempV3 = *v;
+ v = mrow1.fn1(tempV10, subX);
+ mrow1 = *v;
+ v = mrow2.fn1(tempV11, subX);
+ mrow2 = *v;
+ v = mrow3.fn1(tempV12, subX);
+ mrow3 = *v;
+
+ v = tempV3.fn1(tempV13, m1);
+ tempV3 = *v;
+ v = mrow1.fn1(tempV14, m1);
+ mrow1 = *v;
+ v = mrow2.fn1(tempV15, m1);
+ mrow2 = *v;
+ v = mrow3.fn1(tempV16, m1);
+ mrow3 = *v;
+
+ mrow1 -= tempV3;
+ mrow2 -= tempV3;
+ mrow3 -= tempV3;
+ mrow1.normalize();
+ mrow2.normalize();
+ mrow3.normalize();
+ tempV16 = tempV3;
+
+ m3.set(mrow1, mrow2, mrow3);
+ _sub13.setMatrix(m3);
+ _sub13.setPosition(tempV16);
+ }
+}
+
+bool CStarCamera::addMatrixRow(const FVector &v) {
+ if (_matrixRow >= 2)
+ return false;
+
+ CStar20Data data;
+ _handlerP->copyTo(&data);
+ deleteHandler();
+
+ FVector &row = _matrix[++_matrixRow];
+ row = v;
+ setupHandler(&data);
+ return true;
+}
+
+bool CStarCamera::removeMatrixRow() {
+ if (_matrixRow == -1)
+ return false;
+
+ CStar20Data data;
+ _handlerP->copyTo(&data);
+ deleteHandler();
+
+ --_matrixRow;
+ setupHandler(&data);
+ return true;
+}
+
+void CStarCamera::proc36(double *v1, double *v2, double *v3, double *v4) {
+ _sub13.fn19(v1, v2, v3, v4);
+}
+
+void CStarCamera::load(SimpleFile *file, int param) {
+ _sub13.load(file, param);
+}
+
+void CStarCamera::save(SimpleFile *file, int indent) {
+ _sub13.save(file, indent);
+}
+
+bool CStarCamera::setupHandler(const CStar20Data *src) {
+ CStarControlSub20 *handler = nullptr;
+
+ switch (_matrixRow) {
+ case -1:
+ handler = new CStarControlSub21(src);
+ break;
+
+ case 0:
+ case 1:
+ case 2:
+ handler = new CStarControlSub22(src);
+ break;
+
+ default:
+ break;
+ }
+
+ if (handler) {
+ assert(!_handlerP);
+ _handlerP = handler;
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+void CStarCamera::deleteHandler() {
+ if (_handlerP) {
+ delete _handlerP;
+ _handlerP = nullptr;
+ }
+}
+
+void CStarCamera::fn1(CStarControlSub13 *sub13, const FVector &v) {
+ if (_matrixRow == 1) {
+ FMatrix m1 = sub13->getMatrix();
+ FMatrix m2 = _sub13.getMatrix();
+ FVector v1 = sub13->_position;
+ FVector v2 = _sub13._position;
+
+ _handlerP->proc8(v2, v1, m2, m1);
+ CStarVector *sv = new CStarVector(this, v);
+ _handlerP->setVector(sv);
+ }
+}
+
+void CStarCamera::fn2(FVector v1, FVector v2, FVector v3) {
+ if (_matrixRow == -1) {
+ FVector tempV;
+ tempV._z = _sub13._field10;
+ v3._z = v1._z;
+ tempV._x = _sub13._centerVector._z * v1._y * v1._z / _sub13._centerVector._x;
+ v3._y = _sub13._centerVector._y * tempV._z * v3._x / _sub13._centerVector._x;
+ v3._x = _sub13._centerVector._y * v1._x * v1._z / _sub13._centerVector._x - _sub13._valArray[2];
+ tempV._y = _sub13._centerVector._z * tempV._z * v3._y / _sub13._centerVector._x;
+ tempV._x = tempV._x - _sub13._valArray[2];
+
+ v3.normalize();
+ tempV.normalize();
+
+ FMatrix matrix = _sub13.getMatrix();
+ const FVector &pos = _sub13._position;
+ _handlerP->proc10(v3, tempV, pos, matrix);
+
+ CStarVector *sv = new CStarVector(this, v2);
+ _handlerP->setVector(sv);
+ }
+}
+
+void CStarCamera::fn3(CStarControlSub13 *sub13, const FVector &v) {
+ if (_matrixRow != 0)
+ return;
+
+ DMatrix m1;
+ DVector tempV1 = _matrix._row1;
+ DMatrix m2(0, tempV1);
+
+ tempV1 = v - _matrix._row1;
+ m1 = tempV1.fn5();
+
+ m1 = m1.fn4(m2);
+ m2 = m1.fn1();
+
+ DVector tempV2 = _sub13._position;
+ DMatrix m4;
+ m4._row1 = sub13->_position;
+ m4._row2 = DVector(0.0, 0.0, 0.0);
+ m4._row3 = DVector(0.0, 0.0, 0.0);
+ m4._row4 = DVector(0.0, 0.0, 0.0);
+
+ FMatrix m5 = sub13->getMatrix();
+ DVector tempV3, tempV4;
+ tempV4._x = m5._row1._x * 1000000.0 + m4._row1._x;
+ tempV4._y = m5._row1._y * 1000000.0 + m4._row1._y;
+ tempV4._z = m5._row1._z * 1000000.0 + m4._row1._z;
+ tempV3._x = m5._row2._x * 1000000.0 + m4._row1._x;
+ tempV3._y = m5._row2._y * 1000000.0 + m4._row1._y;
+ tempV3._z = m5._row2._z * 1000000.0 + m4._row1._z;
+ m4._row3 = tempV4;
+ m4._row2 = tempV3;
+
+ tempV4._x = m5._row3._x * 1000000.0;
+ tempV4._y = m5._row3._y * 1000000.0;
+ tempV3._x = tempV4._x + m4._row1._x;
+ tempV3._y = tempV4._y + m4._row1._y;
+ tempV3._z = m5._row3._z * 1000000.0 + m4._row1._z;
+ m4._row4 = tempV3;
+
+ DVector *dv = tempV2.fn1(tempV3, m2);
+ tempV3 = *dv;
+ dv = m4._row1.fn1(tempV3, m2);
+ m4._row1 = *dv;
+ dv = m4._row3.fn1(tempV3, m2);
+ m4._row3 = *dv;
+ dv = m4._row2.fn1(tempV3, m2);
+ m4._row2 = *dv;
+ dv = m4._row4.fn1(tempV3, m2);
+ m4._row4 = *dv;
+
+ // Find the angle that gives the minimum distance
+ DVector tempV5;
+ double minDistance = 1.0e20;
+ int minDegree = 0;
+ for (int degree = 0; degree < 360; ++degree) {
+ tempV5 = m4._row1;
+ tempV5.fn2((double)degree);
+ double distance = tempV2.getDistance(tempV5);
+
+ if (distance < minDistance) {
+ minDistance = distance;
+ minDegree = degree;
+ }
+ }
+
+ m4._row1.fn2((double)minDegree);
+ m4._row2.fn2((double)minDegree);
+ m4._row3.fn2((double)minDegree);
+ m4._row4.fn2((double)minDegree);
+ dv = m4._row1.fn1(tempV3, m1);
+ m4._row1 = *dv;
+ dv = m4._row3.fn1(tempV3, m1);
+ m4._row3 = *dv;
+ dv = m4._row2.fn1(tempV3, m1);
+ m4._row2 = *dv;
+ dv = m4._row4.fn1(tempV3, m1);
+ m4._row4 = *dv;
+
+ m4._row3._x -= m4._row1._x;
+ m4._row3._y -= m4._row1._y;
+ m4._row3._z -= m4._row1._z;
+ m4._row2._x -= m4._row1._x;
+ m4._row2._y -= m4._row1._y;
+ m4._row2._z = m4._row2._z - m4._row1._z;
+
+ m4._row4._x = m4._row4._x - m4._row1._x;
+ m4._row4._y = m4._row4._y - m4._row1._y;
+ m4._row4._z = m4._row4._z - m4._row1._z;
+
+ m4._row3.normalize();
+ m4._row2.normalize();
+ m4._row4.normalize();
+ m5.set(m4._row3, m4._row2, m4._row4);
+
+ FVector tempV6 = m4._row1;
+ FMatrix m6 = _sub13.getMatrix();
+ _handlerP->proc8(_sub13._position, tempV6, m6, m5);
+
+ CStarVector *sv = new CStarVector(this, v);
+ _handlerP->setVector(sv);
+}
+
+} // End of namespace Titanic