diff options
author | Matthew Stewart | 2018-07-19 04:39:57 -0400 |
---|---|---|
committer | Eugene Sandulenko | 2018-08-09 08:37:30 +0200 |
commit | 565bf0e96750588e8a7f6816e79683e97896f8de (patch) | |
tree | 6d8e0c8ba093937227f073999c587945be2646ab /engines | |
parent | 2b09f698ed47942d84e6c7f503901941116db328 (diff) | |
download | scummvm-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.h | 25 | ||||
-rw-r--r-- | engines/startrek/math.cpp | 129 | ||||
-rw-r--r-- | engines/startrek/space.h | 7 | ||||
-rw-r--r-- | engines/startrek/startrek.cpp | 22 | ||||
-rw-r--r-- | engines/startrek/startrek.h | 1 |
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); |