aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Stewart2018-07-18 23:53:21 -0400
committerEugene Sandulenko2018-08-09 08:37:30 +0200
commitac9cd1f00a28b09dd0202c90a2fe023bc8cba525 (patch)
treebb3666dcdc40ab72f6e6917c8de1881d40b65ab2
parenta024a3fd4501a0ab41ffdd62f65914f2307bdf22 (diff)
downloadscummvm-rg350-ac9cd1f00a28b09dd0202c90a2fe023bc8cba525.tar.gz
scummvm-rg350-ac9cd1f00a28b09dd0202c90a2fe023bc8cba525.tar.bz2
scummvm-rg350-ac9cd1f00a28b09dd0202c90a2fe023bc8cba525.zip
STARTREK: Implement fixed-point decimal class
-rw-r--r--engines/startrek/awaymission.cpp26
-rw-r--r--engines/startrek/common.h7
-rw-r--r--engines/startrek/fixedint.h152
-rw-r--r--engines/startrek/object.h1
-rw-r--r--engines/startrek/room.cpp4
-rw-r--r--engines/startrek/room.h13
-rw-r--r--engines/startrek/saveload.cpp10
-rw-r--r--engines/startrek/space.cpp64
-rw-r--r--engines/startrek/space.h115
-rw-r--r--engines/startrek/startrek.cpp112
-rw-r--r--engines/startrek/startrek.h24
11 files changed, 417 insertions, 111 deletions
diff --git a/engines/startrek/awaymission.cpp b/engines/startrek/awaymission.cpp
index e086bca045..94ee86993c 100644
--- a/engines/startrek/awaymission.cpp
+++ b/engines/startrek/awaymission.cpp
@@ -105,9 +105,9 @@ void StarTrekEngine::loadRoom(const Common::String &missionName, int roomIndex)
actorFunc1();
initActors();
- double num = _room->getVar0c() - _room->getVar0a();
- double den = _room->getVar06() - _room->getVar08() + 1;
- _playerActorScale = (int32)(num * 256 / den);
+ Fixed16 num = _room->getMaxScale() - _room->getMinScale();
+ int16 den = _room->getMaxY() - _room->getMinY() + 1;
+ _playerActorScale = Fixed32(num) / den;
// TODO: RDF vars 1e/1f and 20/21; relates to BAN files?
@@ -446,21 +446,21 @@ void StarTrekEngine::unloadRoom() {
* further up (away) the object is, the smaller it is.
*/
int StarTrekEngine::loadActorAnimWithRoomScaling(int actorIndex, const Common::String &animName, int16 x, int16 y) {
- uint16 scale = getActorScaleAtPosition(y);
+ Fixed16 scale = getActorScaleAtPosition(y);
return loadActorAnim(actorIndex, animName, x, y, scale);
}
-uint16 StarTrekEngine::getActorScaleAtPosition(int16 y) {
- int16 var06 = _room->getVar06();
- int16 var08 = _room->getVar08();
- int16 var0a = _room->getVar0a();
+Fixed16 StarTrekEngine::getActorScaleAtPosition(int16 y) {
+ int16 maxY = _room->getMaxY();
+ int16 minY = _room->getMinY();
+ Fixed16 minScale = _room->getMinScale();
- if (var06 < y)
- y = var06;
- if (var08 > y)
- y = var08;
+ if (y > maxY)
+ y = maxY;
+ if (y < minY)
+ y = minY;
- return ((_playerActorScale * (y - var08)) >> 8) + var0a;
+ return Fixed16(_playerActorScale * (y - minY)) + minScale;
}
SharedPtr<Room> StarTrekEngine::getRoom() {
diff --git a/engines/startrek/common.h b/engines/startrek/common.h
index d76ef66c28..290772f4a1 100644
--- a/engines/startrek/common.h
+++ b/engines/startrek/common.h
@@ -23,6 +23,7 @@
#define STARTREK_COMMON_H
#include "common/scummsys.h"
+#include "common/textconsole.h"
namespace Common {
struct Rect;
@@ -41,12 +42,6 @@ Common::Rect getRectEncompassing(Common::Rect r1, Common::Rect r2);
void serializeRect(Common::Rect rect, Common::Serializer &ser);
-// Fixed-point (16.16) number
-typedef int32 Fixed32;
-
-// Fixed-point (8.8) number
-typedef int16 Fixed16;
-
}
#endif
diff --git a/engines/startrek/fixedint.h b/engines/startrek/fixedint.h
new file mode 100644
index 0000000000..a91e6b33d9
--- /dev/null
+++ b/engines/startrek/fixedint.h
@@ -0,0 +1,152 @@
+/* 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.
+ *
+ */
+
+#ifndef STARTREK_FIXEDINT_H
+#define STARTREK_FIXEDINT_H
+
+#include "common/serializer.h"
+
+#include "startrek/common.h"
+
+namespace StarTrek {
+
+/**
+ * Signed fixed-point number.
+ */
+template<typename T, uint totalBits, uint decimalBits>
+class TFixedInt : Common::Serializable {
+ const static int max = (1 << (totalBits - decimalBits - 1)) - 1;
+ const static int min = -max - 1;
+
+ T val;
+
+public:
+ static TFixedInt fromRaw(T raw) {
+ TFixedInt ret;
+ ret.val = raw;
+ return ret;
+ }
+
+ TFixedInt() : val(0) {}
+ TFixedInt(double d) {
+ assert(d >= min && d <= max); // FIXME: downgrade this to a warning?
+ val = (T)(d * (1 << decimalBits));
+ }
+
+ /**
+ * Constructor from other fixed-point formats.
+ */
+ template<typename T2, uint otherTB, uint otherDB>
+ TFixedInt<T, totalBits, decimalBits>(const TFixedInt<T2, otherTB, otherDB> &fi) {
+ int diff = otherDB - decimalBits;
+ if (otherDB >= decimalBits)
+ val = fi.raw() >> diff;
+ else
+ val = fi.raw() << (-diff);
+ }
+
+ T raw() const {
+ return val;
+ }
+
+ int16 toInt() const {
+ return val >> decimalBits;
+ }
+
+ double toDouble() const {
+ return ((double)val) / (1 << decimalBits);
+ }
+
+ /**
+ * Multiplication with an int, with the result being an int.
+ */
+ int32 multToInt(int32 i) {
+ return ((val * i) << (totalBits - decimalBits)) >> totalBits;
+ }
+
+ /**
+ * Multiplication with an int, with the result being the same type.
+ */
+ TFixedInt operator*(int32 i) const {
+ return fromRaw(val * i);
+ }
+ /**
+ * Division with an int, with the result being the same type.
+ */
+ TFixedInt operator/(int32 i) const {
+ return fromRaw(val / i);
+ }
+ TFixedInt operator+(const TFixedInt &f) const {
+ return fromRaw(val + f.val);
+ }
+ TFixedInt operator-(const TFixedInt &f) const {
+ return fromRaw(val - f.val);
+ }
+
+ void operator+=(const TFixedInt &f) {
+ val += f.val;
+ }
+ void operator-=(const TFixedInt &f) {
+ val -= f.val;
+ }
+
+ 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<=(double d) const {
+ return toDouble() <= d;
+ }
+
+ void saveLoadWithSerializer(Common::Serializer &ser) {
+ if (totalBits == 16)
+ ser.syncAsSint16LE(val);
+ else if (totalBits == 32)
+ ser.syncAsSint32LE(val);
+ else
+ error("Unsupported bit size for TFixedInt");
+ }
+};
+
+template<typename T, uint totalBits, uint decimalBits>
+int32 operator*(const int16 lhs, const TFixedInt<T, totalBits, decimalBits> &rhs) {
+ return rhs * lhs;
+}
+
+
+// Fixed-point (2.14) number (between -1 and 1)
+typedef TFixedInt<int16, 16, 14> Fixed14;
+
+// Fixed-point (8.8) number
+typedef TFixedInt<int16, 16, 8> Fixed16;
+
+// Fixed-point (16.16) number
+typedef TFixedInt<int32, 32, 16> Fixed32;
+
+}
+
+#endif
diff --git a/engines/startrek/object.h b/engines/startrek/object.h
index 3a2dc335ef..e10a0f637f 100644
--- a/engines/startrek/object.h
+++ b/engines/startrek/object.h
@@ -24,6 +24,7 @@
#define STARTREK_OBJECT_H
#include "startrek/common.h"
+#include "startrek/fixedint.h"
#include "startrek/items.h"
#include "startrek/sprite.h"
diff --git a/engines/startrek/room.cpp b/engines/startrek/room.cpp
index 4ec703f69d..a9f83118b6 100644
--- a/engines/startrek/room.cpp
+++ b/engines/startrek/room.cpp
@@ -210,7 +210,7 @@ void Room::loadActorAnim(int actorIndex, Common::String anim, int16 x, int16 y,
if (actorIndex >= 0 && actorIndex < SCALED_ACTORS_END)
_vm->loadActorAnimWithRoomScaling(actorIndex, anim, x, y);
else
- _vm->loadActorAnim(actorIndex, anim, x, y, 256);
+ _vm->loadActorAnim(actorIndex, anim, x, y, 1.0);
if (finishedAnimActionParam != 0) {
actor->triggerActionWhenAnimFinished = true;
@@ -231,7 +231,7 @@ void Room::loadActorAnimC(int actorIndex, Common::String anim, int16 x, int16 y,
if (actorIndex >= 0 && actorIndex < SCALED_ACTORS_END)
_vm->loadActorAnimWithRoomScaling(actorIndex, anim, x, y);
else
- _vm->loadActorAnim(actorIndex, anim, x, y, 256);
+ _vm->loadActorAnim(actorIndex, anim, x, y, 1.0);
if (funcPtr != nullptr) {
actor->triggerActionWhenAnimFinished = true;
diff --git a/engines/startrek/room.h b/engines/startrek/room.h
index 1442e90162..434ff76eb2 100644
--- a/engines/startrek/room.h
+++ b/engines/startrek/room.h
@@ -27,6 +27,7 @@
#include "common/ptr.h"
#include "common/str.h"
+#include "startrek/fixedint.h"
#include "startrek/startrek.h"
#include "startrek/text.h"
@@ -60,11 +61,13 @@ public:
// Helper stuff for RDF access
uint16 readRdfWord(int offset);
- // Scale-related stuff (rename these later)
- uint16 getVar06() { return readRdfWord(0x06); }
- uint16 getVar08() { return readRdfWord(0x08); }
- uint16 getVar0a() { return readRdfWord(0x0a); }
- uint16 getVar0c() { return readRdfWord(0x0c); }
+ // Scale-related stuff; at the "min Y" position or below, the crewmembers have
+ // "minimum" scale; that value rises to the "max scale" value by the time they reach
+ // the "max Y" value.
+ uint16 getMaxY() { return readRdfWord(0x06); }
+ uint16 getMinY() { return readRdfWord(0x08); }
+ Fixed16 getMinScale() { return Fixed16::fromRaw(readRdfWord(0x0a)); }
+ Fixed16 getMaxScale() { return Fixed16::fromRaw(readRdfWord(0x0c)); }
// words 0x0e and 0x10 in RDF file are pointers to start and end of event code.
// That code is instead rewritten on a per-room basis.
diff --git a/engines/startrek/saveload.cpp b/engines/startrek/saveload.cpp
index 443d4a5446..3d1a1aad3f 100644
--- a/engines/startrek/saveload.cpp
+++ b/engines/startrek/saveload.cpp
@@ -256,7 +256,7 @@ bool StarTrekEngine::saveOrLoadGameData(Common::SeekableReadStream *in, Common::
a->sprite.saveLoadWithSerializer(ser);
ser.syncBytes((byte *)a->bitmapFilename, 10);
- ser.syncAsUint16LE(a->scale);
+ a->scale.saveLoadWithSerializer(ser);
// Can't save "animFile" (will be reloaded)
ser.syncAsUint16LE(a->numAnimFrames);
ser.syncAsUint16LE(a->animFrame);
@@ -274,10 +274,10 @@ bool StarTrekEngine::saveOrLoadGameData(Common::SeekableReadStream *in, Common::
ser.syncAsUint16LE(a->field76);
ser.syncAsSint16LE(a->iwSrcPosition);
ser.syncAsSint16LE(a->iwDestPosition);
- ser.syncAsSint32LE(a->granularPosX);
- ser.syncAsSint32LE(a->granularPosY);
- ser.syncAsSint32LE(a->speedX);
- ser.syncAsSint32LE(a->speedY);
+ a->granularPosX.saveLoadWithSerializer(ser);
+ a->granularPosY.saveLoadWithSerializer(ser);
+ a->speedX.saveLoadWithSerializer(ser);
+ a->speedY.saveLoadWithSerializer(ser);
ser.syncAsSint16LE(a->dest.x);
ser.syncAsSint16LE(a->dest.y);
ser.syncAsUint16LE(a->field90);
diff --git a/engines/startrek/space.cpp b/engines/startrek/space.cpp
index 1171952ed4..a4d09690f8 100644
--- a/engines/startrek/space.cpp
+++ b/engines/startrek/space.cpp
@@ -26,8 +26,8 @@
namespace StarTrek {
void StarTrekEngine::initStarfieldPosition() {
- memset(&_starfieldPosition, 0, sizeof(_starfieldPosition));
- // TODO: matrix initialization
+ _starfieldPosition = Point3(0, 0, 0);
+ _someMatrix = initMatrix();
}
void StarTrekEngine::initStarfield(int16 x, int16 y, int16 width, int16 height, int16 arg8) {
@@ -45,13 +45,35 @@ void StarTrekEngine::initStarfield(int16 x, int16 y, int16 width, int16 height,
_starfieldPointDivisor = 150;
}
+void StarTrekEngine::addR3(R3 *r3) {
+ for (int i = 0; i < NUM_SPACE_OBJECTS; i++) {
+ if (_r3List[i] == nullptr) {
+ _r3List[i] = r3;
+ return;
+ }
+ }
+
+ error("addR3: out of shapes.");
+}
+
+void StarTrekEngine::delR3(R3 *r3) {
+ for (int i = 0; i < NUM_SPACE_OBJECTS; i++) {
+ if (_r3List[i] == r3) {
+ _r3List[i] = nullptr;
+ r3->field1e = 0;
+ return;
+ }
+ }
+
+ error("delR3: shape not found.");
+}
+
void StarTrekEngine::clearStarfieldPixels() {
_gfx->fillBackgroundRect(_starfieldRect, 0);
}
void StarTrekEngine::drawStarfield() {
// TODO: make these class variables
- Point3W starPositionWeightings[] = {{0x4000, 0, 0}, {0, 0x4000, 0}, {0, 0, 0x4000}};
float flt_50898 = 50.0; // ?
int16 var28 = ((_starfieldXVar2 * 3) >> 1);
@@ -72,12 +94,12 @@ void StarTrekEngine::drawStarfield() {
int16 var4 = getRandomWord() / var28 - xvar;
int16 var6 = getRandomWord() / var2a - yvar;
Point3 point = constructPoint3ForStarfield(var4, var6, var8);
- star->pos = applyPointWeightings(starPositionWeightings, point) + _starfieldPosition;
+ star->pos = matrixMult(_starPositionMatrix, point) + _starfieldPosition;
star->active = true;
}
Point3 p = star->pos - _starfieldPosition;
- Point3 point2 = applyPointWeightings2(p, starPositionWeightings);
+ Point3 point2 = matrixMult(p, _starPositionMatrix);
if (point2.z > flt_50898 && point2.z < 0x3fff
&& abs(point2.x) < point2.z && abs(point2.y) < point2.z) {
@@ -111,7 +133,7 @@ void StarTrekEngine::drawStarfield() {
void StarTrekEngine::updateStarfieldAndShips(bool arg0) {
_starfieldSprite.bitmapChanged = true;
- // sub_24b74(...);
+ _starPositionMatrix = _someMatrix.invert();
clearStarfieldPixels();
drawStarfield();
@@ -127,28 +149,32 @@ Point3 StarTrekEngine::constructPoint3ForStarfield(int16 x, int16 y, int16 z) {
return point;
}
-Point3 StarTrekEngine::applyPointWeightings(Point3W *weight, const Point3 &point) {
+Point3 StarTrekEngine::matrixMult(const Matrix &weight, const Point3 &point) {
int32 ret[3];
for (int i = 0; i < 3; i++) {
- ret[i] = weight[i].x * (point.x & 0xffff) + weight[i].y * (point.y & 0xffff) + weight[i].z * (point.z & 0xffff);
- ret[i] <<= 2;
+ ret[i] = weight[i][0].multToInt(point.x & 0xffff) + weight[i][1].multToInt(point.y & 0xffff) + weight[i][2].multToInt(point.z & 0xffff);
}
Point3 p;
- p.x = ret[0] >> 16;
- p.y = ret[1] >> 16;
- p.z = ret[2] >> 16;
+ p.x = ret[0];
+ p.y = ret[1];
+ p.z = ret[2];
return p;
}
-Point3 StarTrekEngine::applyPointWeightings2(const Point3 &point, Point3W *weight) {
+Point3 StarTrekEngine::matrixMult(const Point3 &point, const Matrix &weight) {
Point3 p = Point3();
- p.x = (weight[0].x * (point.x & 0xffff) + weight[1].x * (point.y & 0xffff) + weight[2].x * (point.z & 0xffff)) << 2;
- p.y = (weight[0].y * (point.x & 0xffff) + weight[1].y * (point.y & 0xffff) + weight[2].y * (point.z & 0xffff)) << 2;
- p.z = (weight[0].z * (point.x & 0xffff) + weight[1].z * (point.y & 0xffff) + weight[2].z * (point.z & 0xffff)) << 2;
- p.x >>= 16;
- p.y >>= 16;
- p.z >>= 16;
+ p.x = (weight[0][0].multToInt(point.x & 0xffff) + weight[1][0].multToInt(point.y & 0xffff) + weight[2][0].multToInt(point.z & 0xffff));
+ p.y = (weight[0][1].multToInt(point.x & 0xffff) + weight[1][1].multToInt(point.y & 0xffff) + weight[2][1].multToInt(point.z & 0xffff));
+ p.z = (weight[0][2].multToInt(point.x & 0xffff) + weight[1][2].multToInt(point.y & 0xffff) + weight[2][2].multToInt(point.z & 0xffff));
return p;
}
+Matrix StarTrekEngine::initMatrix() {
+ Matrix mat;
+ mat[0][0] = 1;
+ mat[1][1] = 1;
+ mat[2][2] = 1;
+ return mat;
+}
+
}
diff --git a/engines/startrek/space.h b/engines/startrek/space.h
index f5d08e5d1e..a9c6bdea93 100644
--- a/engines/startrek/space.h
+++ b/engines/startrek/space.h
@@ -1,32 +1,113 @@
-// Pseudo-3D structs
+/* 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.
-struct Point3 {
- int32 x;
- int32 y;
- int32 z;
+ * 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.
- Point3 operator+(const Point3 &p) const {
- Point3 p2;
+ * 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.
+ *
+ */
+
+#ifndef STARTREK_SPACE_H
+#define STARTREK_SPACE_H
+
+#include "fixedint.h"
+
+namespace StarTrek {
+
+class FileStream;
+
+template<typename T>
+struct TPoint {
+ T x;
+ T y;
+ T z;
+
+ TPoint() : x(0), y(0), z(0) {}
+ TPoint(T _x, T _y, T _z) : x(_x), y(_y), z(_z) {}
+
+ TPoint<T> operator+(const TPoint<T> &p) const {
+ TPoint<T> p2;
p2.x = x + p.x;
p2.y = y + p.y;
p2.z = z + p.z;
return p2;
}
- Point3 operator-(const Point3 &p) const {
- Point3 p2;
+ TPoint<T> operator-(const TPoint<T> &p) const {
+ TPoint<T> p2;
p2.x = x - p.x;
p2.y = y - p.y;
p2.z = z - p.z;
return p2;
}
+ T &operator[](int i) {
+ if (i == 0)
+ return x;
+ else if (i == 1)
+ return y;
+ else if (i == 2)
+ return z;
+ assert(false);
+ }
+ T operator[](int i) const {
+ if (i == 0)
+ return x;
+ else if (i == 1)
+ return y;
+ else if (i == 2)
+ return z;
+ assert(false);
+ }
};
-struct Point3W {
- int16 x;
- int16 y;
- int16 z;
+typedef TPoint<int32> Point3;
+typedef TPoint<Fixed14> Point3W;
+
+
+template<typename T>
+struct TMatrix {
+private:
+ T m[3];
+
+public:
+ TMatrix() {}
+ TMatrix(const TMatrix<T> &mat) {
+ m[0] = mat.m[0];
+ m[1] = mat.m[1];
+ m[2] = mat.m[2];
+ }
+ T &operator[](int i) {
+ return m[i];
+ };
+ T operator[](int i) const {
+ return m[i];
+ };
+
+ TMatrix<T> invert() {
+ TMatrix<T> ret;
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ ret[i][j] = m[j][i];
+ }
+ }
+ return ret;
+ }
};
+typedef TMatrix<Point3W> Matrix;
+
struct Star {
bool active;
Point3 pos;
@@ -37,6 +118,10 @@ struct Star {
struct R3 {
Point3 pos; // 0x0
int16 field1e; // 0x1e
+ int16 field20; // 0x20
+ int16 field22; // 0x22
+ int16 field24; // 0x24
+ SharedPtr<FileStream> shpFile; // 0x68
};
// Maximum number of stars visible at once in the starfields
@@ -44,3 +129,7 @@ struct R3 {
// Maximum number of R3 objects in space at once
#define NUM_SPACE_OBJECTS 0x30
+
+}
+
+#endif
diff --git a/engines/startrek/startrek.cpp b/engines/startrek/startrek.cpp
index ab1e3c7ee5..9adba5fd85 100644
--- a/engines/startrek/startrek.cpp
+++ b/engines/startrek/startrek.cpp
@@ -217,6 +217,10 @@ void StarTrekEngine::playIntro() {
_starfieldSprite.bitmap = fakeStarfieldBitmap;
initStarfieldSprite(&_starfieldSprite, fakeStarfieldBitmap, _starfieldRect);
+ //delR3(&_enterpriseR3); // TODO: uncomment
+
+ R3 planetR3 = R3();
+
// TODO: remainder of starfield initialization
_gfx->clearScreenAndPriBuffer();
@@ -312,8 +316,26 @@ void StarTrekEngine::playIntro() {
loadSubtitleSprite(1, &subtitleSprite);
break;
- case 42:
+ case 42: // Enterprise moves toward camera
loadSubtitleSprite(-1, &subtitleSprite);
+ addR3(&_enterpriseR3);
+ _enterpriseR3.field1e = 2;
+ initIntroR3ObjectToMove(&_enterpriseR3, 330, 5000, 0, 0, 18);
+ break;
+
+ case 60: // Enterprise moves away from camera
+ initIntroR3ObjectToMove(&_enterpriseR3, 0, 0, 30, 5000, 6);
+ break;
+
+ case 66: // Cut to scene with planet
+ loadSubtitleSprite(2, &subtitleSprite);
+ planetR3.field22 = 2000;
+ planetR3.field24 = 10000 / _starfieldPointDivisor;
+ planetR3.shpFile = loadFile("planet.shp");
+ initIntroR3ObjectToMove(&planetR3, 6, 10000, 6, 10000, 0);
+ addR3(&planetR3);
+ initIntroR3ObjectToMove(&_enterpriseR3, -15, 250, 15, 500, 18);
+ starfieldZoomSpeed = 0;
break;
case 378:
@@ -344,6 +366,11 @@ void StarTrekEngine::playIntro() {
// TODO: the rest
}
+void StarTrekEngine::initIntroR3ObjectToMove(R3 *r3, int16 srcAngle, int16 srcDepth, int16 destAngle, int16 destDepth, int16 ticks) {
+ srcAngle = (srcAngle << 9) / 180;
+ destAngle = (destAngle << 9) / 180;
+}
+
void StarTrekEngine::loadSubtitleSprite(int index, Sprite *sprite) {
if (_showSubtitles) {
if (index == -1)
@@ -379,25 +406,25 @@ void StarTrekEngine::runTransportSequence(const Common::String &name) {
Common::String filename = getCrewmanAnimFilename(i, name);
int x = crewmanTransportPositions[i][0];
int y = crewmanTransportPositions[i][1];
- loadActorAnim(i, filename, x, y, 256);
+ loadActorAnim(i, filename, x, y, 1.0);
_actorList[i].animationString[0] = '\0';
}
if (_missionToLoad.equalsIgnoreCase("feather") && name[4] == 'b') {
- loadActorAnim(9, "qteleb", 0x61, 0x79, 0x100);
+ loadActorAnim(9, "qteleb", 0x61, 0x79, 1.0);
}
else if (_missionToLoad.equalsIgnoreCase("trial")) {
if (name[4] == 'd') {
- loadActorAnim(9, "qteled", 0x61, 0x79, 0x100);
+ loadActorAnim(9, "qteled", 0x61, 0x79, 1.0);
}
/* TODO
else if (word_51156 >= 3) {
- loadActorAnim(9, "qteleb", 0x61, 0x79, 0x100);
+ loadActorAnim(9, "qteleb", 0x61, 0x79, 1.0);
}
*/
}
- loadActorAnim(8, "transc", 0, 0, 0x100);
+ loadActorAnim(8, "transc", 0, 0, 1.0);
// TODO: redraw mouse and sprite_52c4e?
@@ -570,7 +597,7 @@ bool StarTrekEngine::actorWalkToPosition(int actorIndex, const Common::String &a
if (directPathExists(srcX, srcY, destX, destY)) {
chooseActorDirectionForWalking(actor, srcX, srcY, destX, destY);
- updateActorPositionWhileWalking(actor, (actor->granularPosX + 0x8000) >> 16, (actor->granularPosY + 0x8000) >> 16);
+ updateActorPositionWhileWalking(actor, (actor->granularPosX + 0.5).toInt(), (actor->granularPosY + 0.5).toInt());
return true;
}
else {
@@ -590,7 +617,7 @@ bool StarTrekEngine::actorWalkToPosition(int actorIndex, const Common::String &a
else {
Common::Point iwSrc = _iwFile->_keyPositions[actor->iwSrcPosition];
chooseActorDirectionForWalking(actor, srcX, srcY, iwSrc.x, iwSrc.y);
- updateActorPositionWhileWalking(actor, (actor->granularPosX + 0x8000) >> 16, (actor->granularPosY + 0x8000) >> 16);
+ updateActorPositionWhileWalking(actor, (actor->granularPosX + 0.5).toInt(), (actor->granularPosY + 0.5).toInt());
return true;
}
}
@@ -660,7 +687,7 @@ void StarTrekEngine::updateActorAnimations() {
if (actor->field90 != 0) {
Sprite *sprite = &actor->sprite;
int loops;
- if (getActorScaleAtPosition((actor->granularPosY + 0x8000) >> 16) < 0xa0)
+ if (getActorScaleAtPosition((actor->granularPosY + 0.5).toInt()) < 0.625)
loops = 1;
else
loops = 2;
@@ -668,11 +695,11 @@ void StarTrekEngine::updateActorAnimations() {
if (actor->field90 == 0)
break;
actor->field90--;
- uint32 newX = actor->granularPosX + actor->speedX;
- uint32 newY = actor->granularPosY + actor->speedY;
+ Fixed32 newX = actor->granularPosX + actor->speedX;
+ Fixed32 newY = actor->granularPosY + actor->speedY;
if ((actor->field90 & 3) == 0) {
sprite->bitmap.reset();
- updateActorPositionWhileWalking(actor, (newX + 0x8000) >> 16, (newY + 0x8000) >> 16);
+ updateActorPositionWhileWalking(actor, (newX + 0.5).toInt(), (newY + 0.5).toInt());
actor->field92++;
}
@@ -689,7 +716,7 @@ void StarTrekEngine::updateActorAnimations() {
}
actor->sprite.bitmap.reset();
- updateActorPositionWhileWalking(actor, (actor->granularPosX + 0x8000) >> 16, (actor->granularPosY + 0x8000) >> 16);
+ updateActorPositionWhileWalking(actor, (actor->granularPosX + 0.5).toInt(), (actor->granularPosY + 0.5).toInt());
initStandAnim(i);
}
else { // actor->iwSrcPosition != -1
@@ -834,7 +861,7 @@ void StarTrekEngine::initStandAnim(int actorIndex) {
else // Default to facing south
animName = Common::String(actor->animationString) + 's';
- uint16 scale = getActorScaleAtPosition(actor->pos.y);
+ Fixed16 scale = getActorScaleAtPosition(actor->pos.y);
loadActorAnim(actorIndex, animName, actor->pos.x, actor->pos.y, scale);
actor->animType = 0;
}
@@ -863,8 +890,8 @@ void StarTrekEngine::updateActorPositionWhileWalking(Actor *actor, int16 x, int1
* a destination position it's walking to.
*/
void StarTrekEngine::chooseActorDirectionForWalking(Actor *actor, int16 srcX, int16 srcY, int16 destX, int16 destY) {
- actor->granularPosX = srcX << 16;
- actor->granularPosY = srcY << 16;
+ actor->granularPosX = srcX;
+ actor->granularPosY = srcY;
int16 distX = destX - srcX;
int16 distY = destY - srcY;
@@ -887,11 +914,11 @@ void StarTrekEngine::chooseActorDirectionForWalking(Actor *actor, int16 srcX, in
if (distX != 0) {
if (distX > 0)
- actor->speedX = 1 << 16;
+ actor->speedX = 1.0;
else
- actor->speedX = -1 << 16; // 0xffff0000
+ actor->speedX = -1.0;
- actor->speedY = (distY << 16) / absDistX;
+ actor->speedY = Fixed32(distY) / absDistX;
}
}
else {
@@ -910,11 +937,11 @@ void StarTrekEngine::chooseActorDirectionForWalking(Actor *actor, int16 srcX, in
if (distY != 0) {
if (distY > 0)
- actor->speedY = 1 << 16;
+ actor->speedY = 1.0;
else
- actor->speedY = -1 << 16; // 0xffff0000
+ actor->speedY = -1.0;
- actor->speedX = (distX << 16) / absDistY;
+ actor->speedX = Fixed32(distX) / absDistY;
}
}
}
@@ -939,12 +966,12 @@ bool StarTrekEngine::directPathExists(int16 srcX, int16 srcY, int16 destX, int16
if (distCounter == 0)
return true;
- speedY = (distY << 16) / absDistX;
+ speedY = Fixed32(distY) / absDistX;
if (distX > 0)
- speedX = 1 << 16;
+ speedX = 1.0;
else
- speedX = -1 << 16;
+ speedX = -1.0;
}
else { // absDistX <= absDistY
distCounter = absDistY;
@@ -952,25 +979,25 @@ bool StarTrekEngine::directPathExists(int16 srcX, int16 srcY, int16 destX, int16
if (distCounter == 0)
return true;
- speedX = (distX << 16) / absDistY;
+ speedX = Fixed32(distX) / absDistY;
if (distY > 0)
- speedY = 1 << 16;
+ speedY = 1.0;
else
- speedY = -1 << 16;
+ speedY = -1.0;
}
- Fixed32 fixedX = srcX << 16;
- Fixed32 fixedY = srcY << 16;
+ Fixed32 fixedX = srcX;
+ Fixed32 fixedY = srcY;
- if (isPositionSolid((fixedX + 0x8000) >> 16, (fixedY + 0x8000) >> 16))
+ if (isPositionSolid((fixedX + 0.5).toInt(), (fixedY + 0.5).toInt()))
return false;
while (distCounter-- > 0) {
fixedX += speedX;
fixedY += speedY;
- if (isPositionSolid((fixedX + 0x8000) >> 16, (fixedY + 0x8000) >> 16))
+ if (isPositionSolid((fixedX + 0.5).toInt(), (fixedY + 0.5).toInt()))
return false;
}
@@ -1119,7 +1146,7 @@ SharedPtr<Bitmap> StarTrekEngine::loadAnimationFrame(const Common::String &filen
bitmapToReturn = _gfx->loadBitmap(filename);
}
- if (scale != 256) {
+ if (scale != 1.0) {
bitmapToReturn = scaleBitmap(bitmapToReturn, scale);
}
@@ -1454,7 +1481,7 @@ void StarTrekEngine::updateCrewmanGetupTimers() {
}
else {
const char *dirs = "nsew";
- uint16 scale = getActorScaleAtPosition(actor->sprite.pos.y);
+ Fixed16 scale = getActorScaleAtPosition(actor->sprite.pos.y);
d = dirs[dir];
int16 xOffset = 0, yOffset = 0;
@@ -1466,8 +1493,8 @@ void StarTrekEngine::updateCrewmanGetupTimers() {
xOffset = -35;
yOffset = -12;
}
- actor->sprite.pos.x += (scale * xOffset) >> 8;
- actor->sprite.pos.y += (scale * yOffset) >> 8;
+ actor->sprite.pos.x += scale.multToInt(xOffset);
+ actor->sprite.pos.y += scale.multToInt(yOffset);
}
anim += (char)d;
@@ -1652,12 +1679,9 @@ void StarTrekEngine::initStarfieldSprite(Sprite *sprite, SharedPtr<Bitmap> bitma
sprite->drawMode = 1;
}
-/**
- * A scale of 256 is the baseline.
- */
SharedPtr<Bitmap> StarTrekEngine::scaleBitmap(SharedPtr<Bitmap> bitmap, Fixed16 scale) {
- int scaledWidth = (bitmap->width * scale) >> 8;
- int scaledHeight = (bitmap->height * scale) >> 8;
+ int scaledWidth = scale.multToInt(bitmap->width);
+ int scaledHeight = scale.multToInt(bitmap->height);
int origWidth = bitmap->width;
int origHeight = bitmap->height;
@@ -1667,8 +1691,8 @@ SharedPtr<Bitmap> StarTrekEngine::scaleBitmap(SharedPtr<Bitmap> bitmap, Fixed16
scaledHeight = 1;
SharedPtr<Bitmap> scaledBitmap(new Bitmap(scaledWidth, scaledHeight));
- scaledBitmap->xoffset = (bitmap->xoffset * scale) >> 8;
- scaledBitmap->yoffset = (bitmap->yoffset * scale) >> 8;
+ scaledBitmap->xoffset = scale.multToInt(bitmap->xoffset);
+ scaledBitmap->yoffset = scale.multToInt(bitmap->yoffset);
// sub_344a5(scaledWidth, origWidth);
@@ -1678,7 +1702,7 @@ SharedPtr<Bitmap> StarTrekEngine::scaleBitmap(SharedPtr<Bitmap> bitmap, Fixed16
byte *src = bitmap->pixels;
byte *dest = scaledBitmap->pixels;
- if (scale <= 256) {
+ if (scale <= 1.0) {
int16 var2e = 0;
uint16 var30 = scaledHeight << 1;
uint16 var32 = (scaledHeight - origHeight) << 1;
diff --git a/engines/startrek/startrek.h b/engines/startrek/startrek.h
index 3f5636f9db..1ec54f1ac3 100644
--- a/engines/startrek/startrek.h
+++ b/engines/startrek/startrek.h
@@ -222,7 +222,7 @@ public:
void handleAwayMissionEvents();
void unloadRoom();
int loadActorAnimWithRoomScaling(int actorIndex, const Common::String &animName, int16 x, int16 y);
- uint16 getActorScaleAtPosition(int16 y);
+ Fixed16 getActorScaleAtPosition(int16 y);
void addAction(const Action &action);
void addAction(byte type, byte b1, byte b2, byte b3);
bool checkItemInteractionExists(int action, int activeItem, int passiveItem, int16 arg6);
@@ -240,18 +240,30 @@ public:
private:
// Intro
void playIntro();
+ /**
+ * Initializes an object to spawn at one position and move toward another position.
+ * @param ticks The number of ticks it should take for the object to reach the destination
+ */
+ void initIntroR3ObjectToMove(R3 *r3, int16 srcAngle, int16 srcDepth, int16 destAngle, int16 destDepth, int16 ticks);
void loadSubtitleSprite(int index, Sprite *sprite);
// Space, pseudo-3D (space.cpp)
void initStarfieldPosition();
void initStarfield(int16 x, int16 y, int16 width, int16 height, int16 arg8);
+ void addR3(R3 *r3);
+ void delR3(R3 *r3);
void clearStarfieldPixels();
void drawStarfield();
void updateStarfieldAndShips(bool arg0);
Point3 constructPoint3ForStarfield(int16 x, int16 y, int16 z);
- Point3 applyPointWeightings(Point3W *weight, const Point3 &point);
- Point3 applyPointWeightings2(const Point3 &point, Point3W *weight);
+ Point3 matrixMult(const Matrix &weight, const Point3 &point);
+ Point3 matrixMult(const Point3 &point, const Matrix &weight);
+
+ /**
+ * Creates something like an "identity" matrix? (Value 0x4000 along the diagonal)
+ */
+ Matrix initMatrix();
// Transporter room
void runTransportSequence(const Common::String &name);
@@ -447,7 +459,7 @@ public:
Common::String _screenName; // _screenName = _missionName + _roomIndex
Common::String _mapFilename; // Similar to _screenName, but used for .map files?
SharedPtr<FileStream> _mapFile;
- int32 _playerActorScale;
+ Fixed32 _playerActorScale;
Common::String _txtFilename;
Common::String _loadedText; // TODO: might be OK to delete this
@@ -519,6 +531,10 @@ public:
int16 _starfieldXVar1, _starfieldYVar1;
int16 _starfieldXVar2, _starfieldYVar2;
Common::Rect _starfieldRect;
+ R3 _enterpriseR3;
+ R3 *_r3List[NUM_SPACE_OBJECTS];
+ Matrix _starPositionMatrix;
+ Matrix _someMatrix;
Graphics *_gfx;
Sound *_sound;