aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMatthew Stewart2018-07-19 04:39:57 -0400
committerEugene Sandulenko2018-08-09 08:37:30 +0200
commit565bf0e96750588e8a7f6816e79683e97896f8de (patch)
tree6d8e0c8ba093937227f073999c587945be2646ab /engines
parent2b09f698ed47942d84e6c7f503901941116db328 (diff)
downloadscummvm-rg350-565bf0e96750588e8a7f6816e79683e97896f8de.tar.gz
scummvm-rg350-565bf0e96750588e8a7f6816e79683e97896f8de.tar.bz2
scummvm-rg350-565bf0e96750588e8a7f6816e79683e97896f8de.zip
STARTREK: atan2 function
Diffstat (limited to 'engines')
-rw-r--r--engines/startrek/fixedint.h25
-rw-r--r--engines/startrek/math.cpp129
-rw-r--r--engines/startrek/space.h7
-rw-r--r--engines/startrek/startrek.cpp22
-rw-r--r--engines/startrek/startrek.h1
5 files changed, 181 insertions, 3 deletions
diff --git a/engines/startrek/fixedint.h b/engines/startrek/fixedint.h
index cae9efdb94..2ea6400127 100644
--- a/engines/startrek/fixedint.h
+++ b/engines/startrek/fixedint.h
@@ -122,6 +122,31 @@ public:
bool operator<=(double d) const {
return toDouble() <= d;
}
+ bool operator>(double d) const {
+ return toDouble() > d;
+ }
+ bool operator>=(double d) const {
+ return toDouble() >= d;
+ }
+
+ bool operator==(const TFixedInt &f) const {
+ return val == f.val;
+ }
+ bool operator!=(const TFixedInt &f) const {
+ return val != f.val;
+ }
+ bool operator<(const TFixedInt &f) const {
+ return val < f.val;
+ }
+ bool operator<=(const TFixedInt &f) const {
+ return val <= f.val;
+ }
+ bool operator>(const TFixedInt &f) const {
+ return val > f.val;
+ }
+ bool operator>=(const TFixedInt &f) const {
+ return val >= f.val;
+ }
void saveLoadWithSerializer(Common::Serializer &ser) {
if (totalBits == 16)
diff --git a/engines/startrek/math.cpp b/engines/startrek/math.cpp
new file mode 100644
index 0000000000..80aa39ee6a
--- /dev/null
+++ b/engines/startrek/math.cpp
@@ -0,0 +1,129 @@
+/* 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 "startrek/startrek.h"
+
+namespace StarTrek {
+
+Fixed14 StarTrekEngine::sin(Fixed8 angle) {
+ int16 i = angle.raw();
+ if (angle < 0) {
+ i %= 0x400;
+ i += 0x400;
+ }
+ i &= 0x3ff;
+
+ if (i == 0x100)
+ return 1.0;
+ else if (i == 0x300)
+ return -1.0;
+
+ float f;
+ if (i < 0x100)
+ f = _sineTable.getTable()[i & 0xff];
+ else if (i < 0x200)
+ f = _sineTable.getTable()[256 - (i & 0xff)];
+ else if (i < 0x300)
+ f = -_sineTable.getTable()[i & 0xff];
+ else if (i < 0x400)
+ f = -_sineTable.getTable()[256 - (i & 0xff)];
+ return Fixed16(f);
+}
+
+Fixed14 StarTrekEngine::cos(Fixed8 angle) {
+ return sin(angle + 1.0);
+}
+
+Fixed8 StarTrekEngine::atan2(int32 deltaX, int32 deltaY) {
+ const int16 atanTable[] = {
+ 0x0000, 0x0064, 0x00c9, 0x012d, 0x0192, 0x01f6, 0x025b, 0x02c0,
+ 0x0324, 0x0389, 0x03ee, 0x0453, 0x04b8, 0x051d, 0x0582, 0x05e8,
+ 0x064d, 0x06b3, 0x0718, 0x077e, 0x07e4, 0x084a, 0x08b1, 0x0917,
+ 0x097e, 0x09e5, 0x0a4c, 0x0ab3, 0x0b1a, 0x0b82, 0x0bea, 0x0c52,
+ 0x0cba, 0x0d23, 0x0d8c, 0x0df5, 0x0e5f, 0x0ec8, 0x0f32, 0x0f9d,
+ 0x1007, 0x1072, 0x10de, 0x114a, 0x11b6, 0x1222, 0x128f, 0x12fc,
+ 0x136a, 0x13d8, 0x1446, 0x14b5, 0x1524, 0x1594, 0x1604, 0x1675,
+ 0x16e6, 0x1757, 0x17ca, 0x183c, 0x18b0, 0x1923, 0x1998, 0x1a0c,
+ 0x1a82, 0x1af8, 0x1b6f, 0x1be6, 0x1c5e, 0x1cd7, 0x1d50, 0x1dca,
+ 0x1e45, 0x1ec0, 0x1f3c, 0x1fb9, 0x2037, 0x20b5, 0x2134, 0x21b4,
+ 0x2235, 0x22b7, 0x2339, 0x23bd, 0x2441, 0x24c6, 0x254c, 0x25d4,
+ 0x265c, 0x26e5, 0x276f, 0x27fa, 0x2887, 0x2914, 0x29a2, 0x2a32,
+ 0x2ac3, 0x2b55, 0x2be8, 0x2c7d, 0x2d12, 0x2da9, 0x2e42, 0x2edc,
+ 0x2f77, 0x3013, 0x30b1, 0x3151, 0x31f2, 0x3294, 0x3338, 0x33de,
+ 0x3486, 0x352f, 0x35d9, 0x3686, 0x3734, 0x37e5, 0x3897, 0x394b,
+ 0x3a01, 0x3ab9, 0x3b73, 0x3c30, 0x3cee, 0x3daf, 0x3e72, 0x3f38,
+ 0x4000
+ };
+
+ if (deltaX == 0 && deltaY == 0)
+ return 0.0;
+
+ bool deltaYNegative = deltaY <= 0;
+ bool deltaXNegative = deltaX <= 0;
+
+ deltaY = abs(deltaY);
+ deltaX = abs(deltaX);
+
+ Fixed14 ratio;
+ if (deltaY > deltaX)
+ ratio = Fixed14::fromRaw(((deltaX & 0xffff0000) >> 2) / (deltaY >> 16));
+ else
+ ratio = Fixed14::fromRaw(((deltaY & 0xffff0000) >> 2) / (deltaX >> 16));
+
+ int16 endIndex = 128;
+ int16 index = 0;
+ int16 angle;
+ while (index <= endIndex) {
+ angle = (index + endIndex) / 2;
+ Fixed14 tableValue = Fixed14::fromRaw(atanTable[angle]);
+ if (tableValue > ratio)
+ endIndex = angle - 1;
+ else if (tableValue < ratio)
+ index = angle + 1;
+ else
+ break;
+ }
+
+ if (deltaY > deltaX) {
+ if (!deltaYNegative && !deltaXNegative)
+ angle = angle;
+ else if (!deltaYNegative && deltaXNegative)
+ angle = -angle;
+ else if (deltaYNegative && !deltaXNegative)
+ angle = 512 - angle;
+ else
+ angle = angle - 512;
+ } else {
+ if (!deltaYNegative && !deltaXNegative)
+ angle = 256 - angle;
+ else if (deltaYNegative && !deltaXNegative)
+ angle = 256 + angle;
+ else if (deltaYNegative && deltaXNegative)
+ angle = -256 - angle;
+ else
+ angle = -256 + angle;
+ }
+
+ return Fixed8::fromRaw(angle);
+}
+
+}
diff --git a/engines/startrek/space.h b/engines/startrek/space.h
index a9c6bdea93..f4b53d17ab 100644
--- a/engines/startrek/space.h
+++ b/engines/startrek/space.h
@@ -73,7 +73,8 @@ struct TPoint {
};
typedef TPoint<int32> Point3;
-typedef TPoint<Fixed14> Point3W;
+typedef TPoint<int16> Point3_Short;
+typedef TPoint<Fixed14> Point_Fixed14;
template<typename T>
@@ -106,7 +107,7 @@ public:
}
};
-typedef TMatrix<Point3W> Matrix;
+typedef TMatrix<Point_Fixed14> Matrix;
struct Star {
bool active;
@@ -117,10 +118,12 @@ struct Star {
// TODO: what does this stand for? Maybe rename it.
struct R3 {
Point3 pos; // 0x0
+ Matrix matrix; // 0xc
int16 field1e; // 0x1e
int16 field20; // 0x20
int16 field22; // 0x22
int16 field24; // 0x24
+ Point3_Short speed; // 0x26
SharedPtr<FileStream> shpFile; // 0x68
};
diff --git a/engines/startrek/startrek.cpp b/engines/startrek/startrek.cpp
index c8bad8dae6..22d89db3ad 100644
--- a/engines/startrek/startrek.cpp
+++ b/engines/startrek/startrek.cpp
@@ -371,7 +371,27 @@ void StarTrekEngine::initIntroR3ObjectToMove(R3 *r3, int16 srcAngle, int16 srcDe
Fixed8 a1 = Fixed8::fromRaw((srcAngle << 8) / 90);
Fixed8 a2 = Fixed8::fromRaw((destAngle << 8) / 90);
- //r3->pos.x = sin(a1).multToFixed16(srcDepth) + _starfieldPosition.x;
+ r3->pos.x = (sin(a1).multToInt(srcDepth) << 16) + _starfieldPosition.x;
+ r3->pos.z = (cos(a1).multToInt(srcDepth) << 16) + _starfieldPosition.z;
+ r3->pos.y = 0;
+
+ int32 deltaX = (sin(a2).multToInt(destDepth) << 16) + _starfieldPosition.x - r3->pos.x;
+ int32 deltaZ = (cos(a2).multToInt(destDepth) << 16) + _starfieldPosition.z - r3->pos.z;
+
+ Fixed16 angle = atan2(deltaX, deltaZ);
+ r3->matrix = initMatrix();
+
+ // sub_248cc(angle, r3->matrix);
+
+ if (ticks != 0) {
+ r3->speed.x = deltaX / ticks;
+ r3->speed.z = deltaZ / ticks;
+ r3->speed.y = 0;
+ } else {
+ r3->speed.x = 0;
+ r3->speed.z = 0;
+ r3->speed.y = 0;
+ }
}
void StarTrekEngine::loadSubtitleSprite(int index, Sprite *sprite) {
diff --git a/engines/startrek/startrek.h b/engines/startrek/startrek.h
index 7ebc47d13f..4f5e62dbd4 100644
--- a/engines/startrek/startrek.h
+++ b/engines/startrek/startrek.h
@@ -217,6 +217,7 @@ public:
*/
Fixed14 sin(Fixed8 angle);
Fixed14 cos(Fixed8 angle);
+ Fixed8 atan2(int32 deltaX, int32 deltaZ);
// Game modes
Common::Error runGameMode(int mode);