mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-23 12:44:02 +00:00
STARTREK: Implement fixed-point decimal class
This commit is contained in:
parent
a024a3fd45
commit
ac9cd1f00a
@ -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() {
|
||||
|
@ -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
|
||||
|
152
engines/startrek/fixedint.h
Normal file
152
engines/startrek/fixedint.h
Normal file
@ -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
|
@ -24,6 +24,7 @@
|
||||
#define STARTREK_OBJECT_H
|
||||
|
||||
#include "startrek/common.h"
|
||||
#include "startrek/fixedint.h"
|
||||
#include "startrek/items.h"
|
||||
#include "startrek/sprite.h"
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user