Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,562 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/base_stars.h"
#include "titanic/star_control/camera.h"
#include "titanic/star_control/star_closeup.h"
#include "titanic/star_control/star_ref.h"
#include "titanic/support/files_manager.h"
#include "titanic/support/simple_file.h"
#include "titanic/titanic.h"
namespace Titanic {
CBaseStarEntry::CBaseStarEntry() : _red(0), _value(0.0) {
Common::fill(&_data[0], &_data[5], 0);
}
void CBaseStarEntry::load(Common::SeekableReadStream &s) {
_red = s.readByte();
_green = s.readByte();
_blue = s.readByte();
_thickness = s.readByte();
_value = s.readFloatLE();
_position._x = s.readFloatLE();
_position._y = s.readFloatLE();
_position._z = s.readFloatLE();
for (int idx = 0; idx < 5; ++idx)
_data[idx] = s.readUint32LE();
}
bool CBaseStarEntry::operator==(const CBaseStarEntry &s) const {
return _red == s._red && _green == s._green
&& _blue == s._blue && _thickness == s._thickness
&& _value == s._value && _position == s._position
&& _data[0] == s._data[0] && _data[1] == s._data[1]
&& _data[2] == s._data[2] && _data[3] == s._data[3]
&& _data[4] == s._data[4];
}
/*------------------------------------------------------------------------*/
CBaseStars::CBaseStars() : _minVal(0.0), _maxVal(1.0), _range(0.0),
_value1(0.0), _value2(0.0), _value3(0.0), _value4(0.0) {
}
void CBaseStars::clear() {
_data.clear();
}
void CBaseStars::initialize() {
_minVal = 9.9999998e10;
_maxVal = -9.9999998e10;
_minMax.reset();
for (uint idx = 0; idx < _data.size(); ++idx) {
const CBaseStarEntry *entry = getDataPtr(idx);
_minMax.expand(entry->_position);
if (entry->_value < _minVal)
_minVal = entry->_value;
if (entry->_value > _maxVal)
_maxVal = entry->_value;
}
_range = (_maxVal - _minVal) / 1.0;
}
const CBaseStarEntry *CBaseStars::getDataPtr(int index) const {
return (index >= 0 && index < (int)_data.size()) ? &_data[index] : nullptr;
}
void CBaseStars::loadData(Common::SeekableReadStream &s) {
uint headerId = s.readUint32LE();
uint count = s.readUint32LE();
if (headerId != 100 || count == 0)
error("Invalid star data");
// Initialize the data array
clear();
_data.resize(count);
// Iterate through reading the data for each entry
for (uint idx = 0; idx < count; ++idx)
_data[idx].load(s);
}
void CBaseStars::loadData(const CString &resName) {
// Get a stream to read the data from the DAT file
Common::SeekableReadStream *stream = g_vm->_filesManager->getResource(resName);
assert(stream);
// Load the stream
loadData(*stream);
delete stream;
}
void CBaseStars::resetEntry(CBaseStarEntry &entry) {
entry._red = 0xFF;
entry._green = 0xFF;
entry._blue = 0xFF;
entry._thickness = 0;
entry._position._x = 0;
entry._position._y = 0;
entry._position._z = 0;
for (int idx = 0; idx < 5; ++idx)
entry._data[idx] = 0;
}
void CBaseStars::draw(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup) {
if (!_data.empty()) {
switch (camera->getStarColor()) {
case WHITE: // draw white, green, and red stars (mostly white)
switch (surfaceArea->_bpp) {
case 1:
draw1(surfaceArea, camera, closeup);
break;
case 2:
draw2(surfaceArea, camera, closeup);
break;
default:
break;
}
break;
case PINK: // draw pink stars
switch (surfaceArea->_bpp) {
case 1:
draw3(surfaceArea, camera, closeup);
break;
case 2:
draw4(surfaceArea, camera, closeup);
break;
default:
break;
}
break;
default:
break;
}
}
}
void CBaseStars::draw1(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup) {
FPose pose = camera->getPose();
camera->getRelativeXCenterPixels(&_value1, &_value2, &_value3, &_value4);
const double MAX_VAL = 1.0e9 * 1.0e9;
FPoint centroid = surfaceArea->_centroid + FPoint(0.5, 0.5);
double threshold = camera->getFrontClip();
double minVal = threshold - 9216.0;
int width1 = surfaceArea->_width - 1;
int height1 = surfaceArea->_height - 1;
double *v1Ptr = &_value1, *v2Ptr = &_value2;
double tempX, tempY, tempZ, total2;
for (uint idx = 0; idx < _data.size(); ++idx) {
CBaseStarEntry &entry = _data[idx];
const FVector &vector = entry._position;
tempZ = vector._x * pose._row1._z + vector._y * pose._row2._z
+ vector._z * pose._row3._z + pose._vector._z;
if (tempZ <= minVal)
continue;
tempY = vector._x * pose._row1._y + vector._y * pose._row2._y + vector._z * pose._row3._y + pose._vector._y;
tempX = vector._x * pose._row1._x + vector._y * pose._row2._x + vector._z * pose._row3._x + pose._vector._x;
total2 = tempY * tempY + tempX * tempX + tempZ * tempZ;
if (total2 < 1.0e12) {
closeup->draw(pose, vector, FVector(centroid._x, centroid._y, total2),
surfaceArea, camera);
continue;
}
if (tempZ <= threshold || total2 >= MAX_VAL)
continue;
int xStart = (int)(*v1Ptr * tempX / tempZ + centroid._x);
int yStart = (int)(*v2Ptr * tempY / tempZ + centroid._y);
if (xStart < 0 || xStart >= width1 || yStart < 0 || yStart >= height1)
continue;
double sVal = sqrt(total2);
sVal = (sVal < 100000.0) ? 1.0 : 1.0 - ((sVal - 100000.0) / 1.0e9);
double red = MIN((double)entry._red * sVal, (double)255.0);
double green = MIN((double)entry._green * sVal, (double)255.0);
double blue = MIN((double)entry._green * sVal, (double)255.0);
int skipCtr = 0;
if (red < 0.0) {
red = 0.0;
++skipCtr;
}
if (green < 0.0) {
green = 0.0;
++skipCtr;
}
if (blue < 0.0) {
blue = 0.0;
++skipCtr;
}
if (skipCtr == 3)
continue;
int r = (int)(red - 0.5) & 0xfff8;
int g = (int)(green - 0.5) & 0xfff8;
int b = (int)(blue - 0.5) & 0xfff8;
int rgb = ((g | (r << 5)) << 2) | ((b >> 3) & 0xfff8);
uint16 *pixelP = (uint16 *)(surfaceArea->_pixelsPtr + surfaceArea->_pitch * yStart + xStart * 2);
switch (entry._thickness) {
case 0:
*pixelP = rgb;
break;
case 1:
*pixelP = rgb;
*(pixelP + 1) = rgb;
*(pixelP + surfaceArea->_pitch / 2) = rgb;
*(pixelP + surfaceArea->_pitch / 2 + 1) = rgb;
break;
default:
break;
}
}
}
void CBaseStars::draw2(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup) {
FPose pose = camera->getPose();
camera->getRelativeXCenterPixels(&_value1, &_value2, &_value3, &_value4);
const double MAX_VAL = 1.0e9 * 1.0e9;
FPoint centroid = surfaceArea->_centroid + FPoint(0.5, 0.5);
double threshold = camera->getFrontClip();
double minVal = threshold - 9216.0;
int width1 = surfaceArea->_width - 1;
int height1 = surfaceArea->_height - 1;
double *v1Ptr = &_value1, *v2Ptr = &_value2;
double tempX, tempY, tempZ, total2;
for (uint idx = 0; idx < _data.size(); ++idx) {
CBaseStarEntry &entry = _data[idx];
const FVector &vector = entry._position;
tempZ = vector._x * pose._row1._z + vector._y * pose._row2._z
+ vector._z * pose._row3._z + pose._vector._z;
if (tempZ <= minVal)
continue;
tempY = vector._x * pose._row1._y + vector._y * pose._row2._y + vector._z * pose._row3._y + pose._vector._y;
tempX = vector._x * pose._row1._x + vector._y * pose._row2._x + vector._z * pose._row3._x + pose._vector._x;
total2 = tempY * tempY + tempX * tempX + tempZ * tempZ;
if (total2 < 1.0e12) {
closeup->draw(pose, vector, FVector(centroid._x, centroid._y, total2),
surfaceArea, camera);
continue;
}
if (tempZ <= threshold || total2 >= MAX_VAL)
continue;
int xStart = (int)(*v1Ptr * tempX / tempZ + centroid._x);
int yStart = (int)(*v2Ptr * tempY / tempZ + centroid._y);
if (xStart < 0 || xStart >= width1 || yStart < 0 || yStart >= height1)
continue;
double sVal = sqrt(total2);
sVal = (sVal < 100000.0) ? 1.0 : 1.0 - ((sVal - 100000.0) / 1.0e9);
double red = MIN((double)entry._red * sVal, (double)255.0);
double green = MIN((double)entry._green * sVal, (double)255.0);
double blue = MIN((double)entry._green * sVal, (double)255.0);
int skipCtr = 0;
if (red < 0.0) {
red = 0.0;
++skipCtr;
}
if (green < 0.0) {
green = 0.0;
++skipCtr;
}
if (blue < 0.0) {
blue = 0.0;
++skipCtr;
}
if (skipCtr == 3)
continue;
int r = (int)(red - 0.5) & 0xf8;
int g = (int)(green - 0.5) & 0xfc;
int b = (int)(blue - 0.5) & 0xfff8;
int rgb = ((g | (r << 5)) << 3) | (b >> 3);
uint16 *pixelP = (uint16 *)(surfaceArea->_pixelsPtr + surfaceArea->_pitch * yStart + xStart * 2);
switch (entry._thickness) {
case 0:
*pixelP = rgb;
break;
case 1:
*pixelP = rgb;
*(pixelP + 1) = rgb;
*(pixelP + surfaceArea->_pitch / 2) = rgb;
*(pixelP + surfaceArea->_pitch / 2 + 1) = rgb;
break;
default:
break;
}
}
}
void CBaseStars::draw3(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup) {
FPose pose = camera->getPose();
camera->getRelativeXCenterPixels(&_value1, &_value2, &_value3, &_value4);
const double MAX_VAL = 1.0e9 * 1.0e9;
FPoint centroid = surfaceArea->_centroid + FPoint(0.5, 0.5);
double threshold = camera->getFrontClip();
double minVal = threshold - 9216.0;
int width1 = surfaceArea->_width - 1;
int height1 = surfaceArea->_height - 1;
double *v1Ptr = &_value1, *v2Ptr = &_value2;
double *v3Ptr = &_value3, *v4Ptr = &_value4;
double tempX, tempY, tempZ, total2, sVal;
int xStart, yStart, rgb;
uint16 *pixelP;
for (uint idx = 0; idx < _data.size(); ++idx) {
CBaseStarEntry &entry = _data[idx];
const FVector &vector = entry._position;
tempZ = vector._x * pose._row1._z + vector._y * pose._row2._z
+ vector._z * pose._row3._z + pose._vector._z;
if (tempZ <= minVal)
continue;
tempY = vector._x * pose._row1._y + vector._y * pose._row2._y + vector._z * pose._row3._y + pose._vector._y;
tempX = vector._x * pose._row1._x + vector._y * pose._row2._x + vector._z * pose._row3._x + pose._vector._x;
total2 = tempY * tempY + tempX * tempX + tempZ * tempZ;
if (total2 < 1.0e12) {
closeup->draw(pose, vector, FVector(centroid._x, centroid._y, total2),
surfaceArea, camera);
continue;
}
if (tempZ <= threshold || total2 >= MAX_VAL)
continue;
// First pixel
xStart = (int)((tempX + *v3Ptr) * *v1Ptr / tempZ + centroid._x);
yStart = (int)(tempY * *v2Ptr / tempZ + centroid._y);
if (xStart < 0 || xStart >= width1 || yStart < 0 || yStart >= height1)
continue;
sVal = sqrt(total2);
sVal = (sVal < 100000.0) ? 1.0 : 1.0 - ((sVal - 100000.0) / 1.0e9);
sVal *= 255.0;
if (sVal > 255.0)
sVal = 255.0;
if (sVal > 2.0) {
pixelP = (uint16 *)(surfaceArea->_pixelsPtr + surfaceArea->_pitch * yStart + xStart * 2);
rgb = ((int)(sVal - 0.5) & 0xf8) << 7;
switch (entry._thickness) {
case 0:
*pixelP = rgb;
break;
case 1:
*pixelP = rgb;
*(pixelP + 1) = rgb;
*(pixelP + surfaceArea->_pitch / 2) = rgb;
*(pixelP + surfaceArea->_pitch / 2 + 1) = rgb;
break;
default:
break;
}
}
// Second pixel
xStart = (int)((tempX + *v4Ptr) * *v1Ptr / tempZ + centroid._x);
yStart = (int)(tempY * *v2Ptr / tempZ + centroid._y);
if (xStart < 0 || xStart >= width1 || yStart < 0 || yStart >= height1)
continue;
sVal = sqrt(total2);
sVal = (sVal < 100000.0) ? 1.0 : 1.0 - ((sVal - 100000.0) / 1.0e9);
sVal *= 255.0;
if (sVal > 255.0)
sVal = 255.0;
if (sVal > 2.0) {
pixelP = (uint16 *)(surfaceArea->_pixelsPtr + surfaceArea->_pitch * yStart + xStart * 2);
rgb = ((int)(sVal - 0.5) & 0xf8) << 7;
switch (entry._thickness) {
case 0:
*pixelP |= rgb;
break;
case 1:
*pixelP |= rgb;
*(pixelP + 1) |= rgb;
*(pixelP + surfaceArea->_pitch / 2) |= rgb;
*(pixelP + surfaceArea->_pitch / 2 + 1) |= rgb;
break;
default:
break;
}
}
}
}
void CBaseStars::draw4(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup) {
FPose pose = camera->getPose();
camera->getRelativeXCenterPixels(&_value1, &_value2, &_value3, &_value4);
const double MAX_VAL = 1.0e9 * 1.0e9;
FPoint centroid = surfaceArea->_centroid + FPoint(0.5, 0.5);
double threshold = camera->getFrontClip();
double minVal = threshold - 9216.0;
int width1 = surfaceArea->_width - 1;
int height1 = surfaceArea->_height - 1;
double *v1Ptr = &_value1, *v2Ptr = &_value2, *v3Ptr = &_value3, *v4Ptr = &_value4;
double tempX, tempY, tempZ, total2, sVal;
int xStart, yStart, rgb;
uint16 *pixelP;
for (uint idx = 0; idx < _data.size(); ++idx) {
const CBaseStarEntry &entry = _data[idx];
const FVector &vector = entry._position;
tempZ = vector._x * pose._row1._z + vector._y * pose._row2._z
+ vector._z * pose._row3._z + pose._vector._z;
if (tempZ <= minVal)
continue;
tempY = vector._x * pose._row1._y + vector._y * pose._row2._y + vector._z * pose._row3._y + pose._vector._y;
tempX = vector._x * pose._row1._x + vector._y * pose._row2._x + vector._z * pose._row3._x + pose._vector._x;
total2 = tempY * tempY + tempX * tempX + tempZ * tempZ;
if (total2 < 1.0e12) {
// We're in close proximity to the given star, so draw a closeup of it
closeup->draw(pose, vector, FVector(centroid._x, centroid._y, total2),
surfaceArea, camera);
continue;
}
if (tempZ <= threshold || total2 >= MAX_VAL)
continue;
// First pixel
xStart = (int)((tempX + *v3Ptr) * *v1Ptr / tempZ + centroid._x);
yStart = (int)(tempY * *v2Ptr / tempZ + centroid._y);
if (xStart < 0 || xStart >= width1 || yStart < 0 || yStart >= height1)
continue;
sVal = sqrt(total2);
sVal = (sVal < 100000.0) ? 1.0 : 1.0 - ((sVal - 100000.0) / 1.0e9);
sVal *= 255.0;
if (sVal > 255.0)
sVal = 255.0;
if (sVal > 2.0) {
pixelP = (uint16 *)(surfaceArea->_pixelsPtr + surfaceArea->_pitch * yStart + xStart * 2);
rgb = ((int)(sVal - 0.5) & 0xf8) << 8;
switch (entry._thickness) {
case 0:
*pixelP = rgb;
break;
case 1:
*pixelP = rgb;
*(pixelP + 1) = rgb;
*(pixelP + surfaceArea->_pitch / 2) = rgb;
*(pixelP + surfaceArea->_pitch / 2 + 1) = rgb;
break;
default:
break;
}
}
// Second pixel
xStart = (int)((tempX + *v4Ptr) * *v1Ptr / tempZ + centroid._x);
yStart = (int)((tempY * *v2Ptr) / tempZ + centroid._y);
if (xStart < 0 || xStart >= width1 || yStart < 0 || yStart >= height1)
continue;
sVal = sqrt(total2);
sVal = (sVal < 100000.0) ? 1.0 : 1.0 - ((sVal - 100000.0) / 1.0e9);
sVal *= 255.0;
if (sVal > 255.0)
sVal = 255.0;
if (sVal > 2.0) {
pixelP = (uint16 *)(surfaceArea->_pixelsPtr + surfaceArea->_pitch * yStart + xStart * 2);
rgb = ((int)(sVal - 0.5) >> 3) & 0xff;
switch (entry._thickness) {
case 0:
*pixelP |= rgb;
break;
case 1:
*pixelP |= rgb;
*(pixelP + 1) |= rgb;
*(pixelP + surfaceArea->_pitch / 2) |= rgb;
*(pixelP + surfaceArea->_pitch / 2 + 1) |= rgb;
break;
default:
break;
}
}
}
}
int CBaseStars::findStar(CSurfaceArea *surfaceArea, CCamera *camera,
const Common::Point &pt) {
CStarRef1 ref(this, pt);
ref.process(surfaceArea, camera);
return ref._index;
}
int CBaseStars::baseFn2(CSurfaceArea *surfaceArea, CCamera *camera) {
CStarRef3 ref(this);
ref.process(surfaceArea, camera);
return ref._index;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,164 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_BASE_STARS_H
#define TITANIC_BASE_STARS_H
#include "titanic/star_control/frange.h"
#include "common/array.h"
namespace Common {
class SeekableReadStream;
}
namespace Titanic {
enum StarMode { MODE_STARFIELD = 0, MODE_PHOTO = 1 };
class CCamera;
class CStarCloseup;
class CString;
class CSurfaceArea;
class SimpleFile;
struct CBaseStarEntry {
byte _red;
byte _green;
byte _blue;
byte _thickness;
double _value;
FVector _position;
uint _data[5];
CBaseStarEntry();
/**
* Loads the data for a star
*/
void load(Common::SeekableReadStream &s);
bool operator==(const CBaseStarEntry &s) const;
};
struct CStarPosition : public Common::Point {
int _index1;
int _index2;
CStarPosition() : _index1(0), _index2(0) {}
bool operator==(const CStarPosition &sp) const {
return x == sp.x && y == sp.y && _index1 == sp._index1 && _index2 == sp._index2;
}
};
/**
* Base class for views that draw a set of stars in simulated 3D space
*/
class CBaseStars {
private:
void draw1(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup);
void draw2(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup);
void draw3(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup);
void draw4(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup);
protected:
FRange _minMax;
double _minVal;
double _maxVal;
double _range;
double _value1, _value2;
double _value3, _value4;
protected:
/**
* Load entry data from a passed stream
*/
void loadData(Common::SeekableReadStream &s);
/**
* Load entry data from a specified resource
*/
void loadData(const CString &resName);
/**
* Reset the data for an entry
*/
void resetEntry(CBaseStarEntry &entry);
public:
Common::Array<CBaseStarEntry> _data;
public:
CBaseStars();
virtual ~CBaseStars() {}
/**
* Draw the item
*/
virtual void draw(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup);
virtual bool loadYale(int v1) { return true; }
/**
* Selects a star
*/
virtual bool selectStar(CSurfaceArea *surfaceArea, CCamera *camera,
const Common::Point &pt, void *handler = nullptr) { return false; }
/**
* Adds a new star, or removes one if already present at the given co-ordinates
*/
virtual bool addStar(const CBaseStarEntry *entry) { return false; }
virtual bool loadStar() { return false; }
/**
* Load the item's data
*/
virtual void load(SimpleFile *file) {}
/**
* Save the item's data
*/
virtual void save(SimpleFile *file, int indent) {}
/**
* Clear allocated data
*/
void clear();
void initialize();
int size() const { return _data.size(); }
/**
* Get a pointer to a data entry
*/
const CBaseStarEntry *getDataPtr(int index) const;
/**
* Checks for the presence of a star at a given position on the
* screen given the specified camera view, and returns it's index
*/
int findStar(CSurfaceArea *surfaceArea, CCamera *camera,
const Common::Point &pt);
int baseFn2(CSurfaceArea *surfaceArea, CCamera *camera);
};
} // End of namespace Titanic
#endif /* TITANIC_BASE_STARS_H */

View File

@@ -0,0 +1,642 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/camera.h"
#include "titanic/debugger.h"
#include "titanic/star_control/motion_control.h"
#include "titanic/star_control/fmatrix.h"
#include "titanic/star_control/fpoint.h"
#include "titanic/star_control/motion_control_marked.h"
#include "titanic/star_control/motion_control_unmarked.h"
#include "titanic/star_control/error_code.h"
#include "titanic/support/simple_file.h"
#include "titanic/titanic.h"
namespace Titanic {
const double rowScale1 = 100000.0;
const double rowScale2 = 1000000.0;
FMatrix *CCamera::_priorOrientation;
FMatrix *CCamera::_newOrientation;
CCamera::CCamera(const CNavigationInfo *data) :
_lockLevel(ZERO_LOCKED), _motion(nullptr), _isMoved(false), _isInLockingProcess(false) {
createMotionControl(data);
}
CCamera::CCamera(CViewport *src) :
_lockLevel(ZERO_LOCKED), _motion(nullptr), _isMoved(false), _isInLockingProcess(false), _viewport(src) {
}
void CCamera::init() {
_priorOrientation = nullptr;
_newOrientation = nullptr;
}
void CCamera::deinit() {
delete _priorOrientation;
delete _newOrientation;
_priorOrientation = nullptr;
_newOrientation = nullptr;
}
bool CCamera::isLocked() {
return _motion->isLocked();
}
bool CCamera::isNotInLockingProcess() {
return !_isInLockingProcess;
}
CCamera::~CCamera() {
deleteMotionController();
}
void CCamera::setViewport(const CViewport *src) {
_viewport.copyFrom(src);
}
void CCamera::setMotion(const CNavigationInfo *src) {
_motion->setMotion(src);
}
void CCamera::setPosition(const FVector &v) {
if (!isLocked()) {
_viewport.setPosition(v);
setIsMoved();
}
}
void CCamera::setOrientation(const FVector &v) {
if (!isLocked())
_viewport.setOrientation(v);
}
// This never gets called
void CCamera::setRoleAngle(double angle) {
if (!isLocked())
_viewport.SetRoleAngle(angle);
}
// This never gets called
void CCamera::setFrontClip(double n) {
if (!isLocked())
_viewport.setFrontClip(n);
}
// This never gets called
void CCamera::SetBackClip(double f) {
if (!isLocked())
_viewport.setBackClip(f);
}
// This never gets called
void CCamera::setCenterYAngle(int v) {
if (!isLocked())
_viewport.setCenterYAngle(v);
}
// This never gets called
void CCamera::setCenterZAngle(int v) {
if (!isLocked())
_viewport.setCenterZAngle(v);
}
void CCamera::randomizeOrientation() {
if (!isLocked())
_viewport.randomizeOrientation();
}
void CCamera::setFields(StarMode mode, double val) {
if (!isLocked())
_viewport.changeStarColorPixel(mode, val);
}
void CCamera::setDestination(const FVector &v) {
FMatrix orientation = _viewport.getOrientation();
FVector oldPos = _viewport._position;
_motion->moveTo(oldPos, v, orientation);
}
void CCamera::updatePosition(CErrorCode *errorCode) {
if (!_priorOrientation)
_priorOrientation = new FMatrix();
if (!_newOrientation)
_newOrientation = new FMatrix();
*_priorOrientation = _viewport.getOrientation();
*_newOrientation = *_priorOrientation;
FVector priorPos = _viewport._position;
FVector newPos = _viewport._position;
_motion->updatePosition(*errorCode, newPos, *_newOrientation);
if (newPos != priorPos) {
_viewport.setPosition(newPos);
setIsMoved();
}
if (*_priorOrientation != *_newOrientation) {
_viewport.setOrientation(*_newOrientation);
}
}
void CCamera::accelerate() {
_motion->accelerate();
}
void CCamera::deccelerate() {
_motion->deccelerate();
}
void CCamera::fullSpeed() {
_motion->fullSpeed();
}
void CCamera::stop() {
_motion->stop();
}
void CCamera::reposition(double factor) {
if (!isLocked())
_viewport.reposition(factor);
}
void CCamera::setPosition(const FPose &pose) {
if (!isLocked()) {
_viewport.setPosition(pose);
setIsMoved();
}
}
void CCamera::changeOrientation(FMatrix &m) {
if (!isLocked())
_viewport.changeOrientation(m);
}
FPose CCamera::getPose() {
return _viewport.getPose();
}
FPose CCamera::getRawPose() {
return _viewport.getRawPose();
}
double CCamera::getFrontClip() const {
return _viewport._frontClip;
}
double CCamera::getBackClip() const {
return _viewport._backClip;
}
StarColor CCamera::getStarColor() const {
return _viewport._starColor;
}
FVector CCamera::getRelativePos(int index, const FVector &src) {
FVector dest;
double val;
if (index == 2) {
val = _viewport._isZero;
} else {
val = _viewport._valArray[index];
}
dest._x = ((val + src._x) * _viewport._centerVector._x)
/ (_viewport._centerVector._y * src._z);
dest._y = src._y * _viewport._centerVector._x / (_viewport._centerVector._z * src._z);
dest._z = src._z;
return dest;
}
FVector CCamera::getRelativePosNoCentering(int index, const FVector &src) {
return _viewport.getRelativePosNoCentering(index, src);
}
FVector CCamera::getRelativePosCentering(int index, const FVector &v) {
return _viewport.getRelativePosCentering(index, v);
}
FVector CCamera::getRelativePosCenteringRaw(int index, const FVector &v) {
return _viewport.getRelativePosCenteringRaw(index, v);
}
void CCamera::setViewportAngle(const FPoint &angles) {
debug(DEBUG_DETAILED, "setViewportAngle %f %f", angles._x, angles._y);
if (isLocked())
return;
switch(_lockLevel) {
case ZERO_LOCKED: {
FPose subX(X_AXIS, angles._y);
FPose subY(Y_AXIS, -angles._x); // needs to be negative or looking left will cause the view to go right
FPose sub(subX, subY);
changeOrientation(sub);
break;
}
case ONE_LOCKED: {
FVector row1 = _lockedStarsPos._row1;
FPose poseX(X_AXIS, angles._y);
FPose poseY(Y_AXIS, -angles._x); // needs to be negative or looking left will cause the view to go right
FPose pose(poseX, poseY);
FMatrix m1 = _viewport.getOrientation();
FVector tempV1 = _viewport._position;
FVector tempV2 = m1._row1 * rowScale1;
FVector tempV3 = tempV2 + tempV1;
FVector tempV4 = tempV3;
tempV2 = m1._row2 * rowScale1;
FVector tempV5 = m1._row3 * rowScale1;
FVector tempV6 = tempV2 + tempV1;
FVector tempV7 = tempV5 + tempV1;
tempV5 = tempV6;
tempV6 = tempV7;
tempV1 -= row1;
tempV4 -= row1;
tempV5 -= row1;
tempV6 -= row1;
tempV1 = tempV1.matProdRowVect(pose);
tempV4 = tempV4.matProdRowVect(pose);
tempV5 = tempV5.matProdRowVect(pose);
tempV6 = tempV6.matProdRowVect(pose);
tempV4 -= tempV1;
tempV5 -= tempV1;
tempV6 -= tempV1;
float unusedScale = 0.0;
if (!tempV4.normalize(unusedScale) ||
!tempV5.normalize(unusedScale) ||
!tempV6.normalize(unusedScale)) {
// Do the normalization, put the scale amount in unusedScale,
// but if it is unsuccessful, crash
assert(unusedScale);
}
tempV1 += row1;
m1.set(tempV4, tempV5, tempV6);
_viewport.setOrientation(m1);
_viewport.setPosition(tempV1);
break;
}
case TWO_LOCKED: {
FVector tempV2;
FPose m1;
FVector mrow1, mrow2, mrow3;
FVector tempV1, diffV, multV, multV2, tempV3, tempV7;
FPose subX(0, _lockedStarsPos._row1);
FPose subY(Y_AXIS, angles._y);
tempV1 = _lockedStarsPos._row2 - _lockedStarsPos._row1;
diffV = tempV1;
m1 = diffV.formRotXY();
FPose m11;
fposeProd(m1, subX, m11);
subX = m11.inverseTransform();
FPose m12;
fposeProd(subX, subY, m12);
FMatrix m3 = _viewport.getOrientation();
tempV2 = _viewport._position;
multV._x = m3._row1._x * rowScale2;
multV._y = m3._row1._y * rowScale2;
multV._z = m3._row1._z * rowScale2;
tempV3._x = tempV2._x;
tempV3._y = tempV2._y;
tempV3._z = tempV2._z;
multV2._z = m3._row2._z * rowScale2;
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 * rowScale2;
multV2._y = m3._row2._y * rowScale2;
mrow1 = tempV1;
multV = multV2 + tempV3;
mrow2 = multV;
tempV7._z = m3._row3._z * rowScale2 + tempV3._z;
tempV7._y = m3._row3._y * rowScale2 + tempV3._y;
tempV7._x = m3._row3._x * rowScale2 + tempV3._x;
mrow3 = tempV7;
tempV3 = tempV3.matProdRowVect(m12);
mrow1 = mrow1.matProdRowVect(m12);
mrow2 = mrow2.matProdRowVect(m12);
mrow3 = mrow3.matProdRowVect(m12);
tempV3 = tempV3.matProdRowVect(m11);
mrow1 = mrow1.matProdRowVect(m11);
mrow2 = mrow2.matProdRowVect(m11);
mrow3 = mrow3.matProdRowVect(m11);
mrow1 -= tempV3;
mrow2 -= tempV3;
mrow3 -= tempV3;
float unusedScale=0.0;
if (!mrow1.normalize(unusedScale) ||
!mrow2.normalize(unusedScale) ||
!mrow3.normalize(unusedScale)) {
// Do the normalization, put the scale amount in unusedScale,
// but if it is unsuccessful, crash
assert(unusedScale);
}
m3.set(mrow1, mrow2, mrow3);
_viewport.setOrientation(m3);
_viewport.setPosition(tempV3);
break;
}
// All three stars are locked on in this case so the camera does not move
// in response to the users mouse movements
case THREE_LOCKED:
default:
break;
}
}
bool CCamera::addLockedStar(const FVector v) {
if (_lockLevel == THREE_LOCKED)
return false;
CNavigationInfo data;
_motion->getMotion(&data);
deleteMotionController();
FVector &row = _lockedStarsPos[(int)_lockLevel];
_lockLevel = (StarLockLevel)((int)_lockLevel + 1);
row = v;
createMotionControl(&data);
return true;
}
bool CCamera::removeLockedStar() {
if (_lockLevel == ZERO_LOCKED)
return false;
CNavigationInfo data;
_motion->getMotion(&data);
deleteMotionController();
_lockLevel = (StarLockLevel)((int)_lockLevel - 1);
createMotionControl(&data);
return true;
}
void CCamera::getRelativeXCenterPixels(double *v1, double *v2, double *v3, double *v4) {
_viewport.getRelativeXCenterPixels(v1, v2, v3, v4);
}
void CCamera::load(SimpleFile *file, int param) {
_viewport.load(file, param);
}
void CCamera::save(SimpleFile *file, int indent) {
_viewport.save(file, indent);
}
bool CCamera::createMotionControl(const CNavigationInfo *src) {
CMotionControl *motion = nullptr;
switch (_lockLevel) {
case ZERO_LOCKED:
motion = new CMotionControlUnmarked(src);
break;
case ONE_LOCKED:
case TWO_LOCKED:
case THREE_LOCKED:
motion = new CMotionControlMarked(src);
break;
default:
break;
}
if (motion) {
assert(!_motion);
_motion = motion;
return true;
} else {
return false;
}
}
void CCamera::deleteMotionController() {
if (_motion) {
delete _motion;
_motion = nullptr;
_isInLockingProcess = false;
}
}
bool CCamera::lockMarker1(FVector v1, FVector firstStarPosition, FVector v3) {
if (_lockLevel != ZERO_LOCKED)
return true;
_isInLockingProcess = true;
FVector tempV;
double val1, val2, val3, val4, val5;
double val6, val7, val8, val9;
val1 = _viewport._centerVector._y * v1._x;
tempV._z = _viewport._frontClip;
val2 = _viewport._centerVector._y * tempV._z * v3._x;
val3 = _viewport._centerVector._z * v1._y;
val4 = _viewport._centerVector._z * tempV._z;
val5 = val1 * v1._z / _viewport._centerVector._x;
v3._z = v1._z;
val6 = val4 * v3._y;
val7 = val3 * v1._z / _viewport._centerVector._x;
val8 = val6 / _viewport._centerVector._x;
val9 = val2 / _viewport._centerVector._x;
v3._x = val5 - _viewport._isZero; // TODO: _viewport._isZero is always zero
v3._y = val7;
tempV._x = val9 - _viewport._isZero; // TODO: _viewport._isZero is always zero
tempV._y = val8;
float unusedScale = 0.0;
if (!v3.normalize(unusedScale) || !tempV.normalize(unusedScale)) {
// Do the normalization, put the scale amount in unusedScale,
// but if it is unsuccessful, crash
assert(unusedScale);
}
FMatrix matrix = _viewport.getOrientation();
const FVector &pos = _viewport._position;
_motion->transitionBetweenOrientations(v3, tempV, pos, matrix);
CCallbackHandler *callback = new CCallbackHandler(this, firstStarPosition);
_motion->setCallback(callback);
return true;
}
bool CCamera::lockMarker2(CViewport *viewport, const FVector &secondStarPosition) {
if (_lockLevel != ONE_LOCKED)
return true;
_isInLockingProcess = true;
FVector firstStarPosition = _lockedStarsPos._row1;
FPose m3(0, firstStarPosition); // Identity matrix and row4 as the 1st stars position
FVector starDelta = secondStarPosition - firstStarPosition;
FPose m10 = starDelta.formRotXY();
FPose m11;
fposeProd(m10, m3, m11);
m10 = m11.inverseTransform();
FVector oldPos = _viewport._position;
FPose m4;
m4._row1 = viewport->_position;
m4._row2 = FVector(0.0, 0.0, 0.0);
m4._row3 = FVector(0.0, 0.0, 0.0);
m4._vector = FVector(0.0, 0.0, 0.0);
FMatrix newOr = viewport->getOrientation();
float yVal1 = newOr._row1._y * rowScale2;
float zVal1 = newOr._row1._z * rowScale2;
float xVal1 = newOr._row2._x * rowScale2;
float yVal2 = newOr._row2._y * rowScale2;
float zVal2 = newOr._row2._z * rowScale2;
float zVal3 = zVal1 + m4._row1._z;
float yVal3 = yVal1 + m4._row1._y;
float xVal2 = newOr._row1._x * rowScale2 + m4._row1._x;
float zVal4 = zVal2 + m4._row1._z;
float yVal4 = yVal2 + m4._row1._y;
float xVal3 = xVal1 + m4._row1._x;
FVector tempV4(xVal2, yVal3, zVal3);
FVector tempV3(xVal3, yVal4, zVal4);
m4._row3 = tempV4;
FVector tempV5;
tempV5._x = newOr._row3._x * rowScale2;
tempV5._y = newOr._row3._y * rowScale2;
m4._row2 = tempV3;
tempV3._x = tempV5._x + m4._row1._x;
tempV3._y = tempV5._y + m4._row1._y;
tempV3._z = newOr._row3._z * rowScale2 + m4._row1._z;
m4._vector = tempV3;
FVector viewPosition2 = oldPos.matProdRowVect(m10);
m3 = m4.compose2(m10);
float minDistance;
FVector x1(viewPosition2);
FVector x2(m3._row1);
// Find the angle of rotation for m4._row1 that gives the minimum distance to viewPosition
float minDegree = calcAngleForMinDist(x1, x2, minDistance);
m3.rotVectAxisY((double)minDegree);
FPose m13;
m13 = m3.compose2(m11);
m13._row3 -= m13._row1;
m13._row2 -= m13._row1;
m13._vector -= m13._row1;
float unusedScale=0.0;
if (!m13._row2.normalize(unusedScale) ||
!m13._row3.normalize(unusedScale) ||
!m13._vector.normalize(unusedScale) ) {
// Do the normalizations, put the scale amount in unusedScale,
// but if any of the normalizations are unsuccessful, crash
assert(unusedScale);
}
newOr.set(m13._row3, m13._row2, m13._vector);
FVector newPos = m13._row1;
FMatrix oldOr = _viewport.getOrientation();
// WORKAROUND: set old position to new position (1st argument), this prevents
// locking issues when locking the 2nd star. Fixes #9961.
_motion->transitionBetweenPosOrients(newPos, newPos, oldOr, newOr);
CCallbackHandler *callback = new CCallbackHandler(this, secondStarPosition);
_motion->setCallback(callback);
return true;
}
bool CCamera::lockMarker3(CViewport *viewport, const FVector &thirdStarPosition) {
if (_lockLevel != TWO_LOCKED)
return true;
_isInLockingProcess = true;
FMatrix newOr = viewport->getOrientation();
FMatrix oldOr = _viewport.getOrientation();
FVector newPos = viewport->_position;
//FVector oldPos = _viewport._position;
// WORKAROUND: set old position to new position (1st argument), this prevents
// locking issues when locking the 3rd star. Fixes #9961.
_motion->transitionBetweenPosOrients(newPos, newPos, oldOr, newOr);
CCallbackHandler *callback = new CCallbackHandler(this, thirdStarPosition);
_motion->setCallback(callback);
return true;
}
float CCamera::calcAngleForMinDist(FVector &x, FVector &y, float &minDistance) {
FVector tempPos;
minDistance = (float)1.0e20;
float minDegree = 0.0;
float degInc = 1.0; // one degree steps
int nDegrees = floor(360.0/degInc);
for (int i = 0; i < nDegrees; ++i) {
tempPos = y;
tempPos.rotVectAxisY((float)degInc*i);
float distance = x.getDistance(tempPos);
if (distance < minDistance) {
minDistance = distance;
minDegree = (float) degInc*i;
}
}
return minDegree;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,277 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_CAMERA_H
#define TITANIC_CAMERA_H
#include "titanic/star_control/fmatrix.h"
#include "titanic/star_control/base_stars.h"
#include "titanic/star_control/viewport.h"
namespace Titanic {
class CMotionControl;
class CErrorCode;
struct CNavigationInfo;
class FPoint;
class SimpleFile;
enum StarLockLevel { ZERO_LOCKED=0, ONE_LOCKED=1, TWO_LOCKED=2, THREE_LOCKED=3 };
/**
* Implements a reference point from which the starmap can be viewed
*/
class CCamera {
private:
static FMatrix *_priorOrientation;
static FMatrix *_newOrientation;
private:
StarLockLevel _lockLevel;
FMatrix _lockedStarsPos; // Each row represents the location of a locked star
CMotionControl *_motion; // A marked or unmarked camera mover, contains an automover
CViewport _viewport;
bool _isMoved; // Used in CPetStarfield to determine if a star destination can be set
bool _isInLockingProcess; // The mover/view is homing in on a new star
private:
/**
* Creates a motion controller for the camera. This needs to be recreated
* when the number of locked stars changes.
* @param src Contains characteristics to set for the motion
*/
bool createMotionControl(const CNavigationInfo *src);
/**
* Deletes the previous mover handle
*/
void deleteMotionController();
/**
* Return whether the handler is locked
*/
bool isLocked();
public:
static void init();
static void deinit();
public:
CCamera(const CNavigationInfo *data);
CCamera(CViewport *src);
virtual ~CCamera();
/**
* Copy the state from a specified viewport
*/
virtual void setViewport(const CViewport *src);
/**
* Set motion from the passed navigation info
*/
virtual void setMotion(const CNavigationInfo *src);
/**
* The mover/view is not currently homing in on a new star
* This can mean it is unmarked, or that it is fully locked
* onto one star or more (but not in the process of doing so)
*/
bool isNotInLockingProcess();
/**
* Set the camera position
*/
virtual void setPosition(const FVector &v);
/**
* Sets the camera orientation
*/
virtual void setOrientation(const FVector &v);
/**
* Assigns a roll angle about the view direction
*/
virtual void setRoleAngle(double angle);
/**
* Assign a near clip plane distance
*/
virtual void setFrontClip(double n);
/**
* Assign a far clipping plane distance
*/
virtual void SetBackClip(double f);
virtual void setCenterYAngle(int v);
virtual void setCenterZAngle(int v);
virtual void randomizeOrientation();
virtual void setFields(StarMode mode, double val);
/**
* Sets the destination to move the camera to
*/
virtual void setDestination(const FVector &v);
/**
* Updates the camera position
*/
virtual void updatePosition(CErrorCode *errorCode);
/**
* Increases movement speed in forward direction
*/
virtual void accelerate();
/**
* Increases movement speed in backward direction
*/
virtual void deccelerate();
/**
* Increase to full speed
*/
virtual void fullSpeed();
/**
* Completely stop
*/
virtual void stop();
virtual void reposition(double factor);
/**
* Set the camera position
*/
virtual void setPosition(const FPose &pose);
virtual void changeOrientation(FMatrix &m);
/**
* Get the position and direction of the camera
*/
virtual FPose getPose();
virtual FPose getRawPose();
/**
* Get the front clipping distance
*/
virtual double getFrontClip() const;
/**
* Get the back clipping distance
*/
virtual double getBackClip() const;
virtual StarColor getStarColor() const;
/**
* Return the passed vector relative to the center of the viewpoint
*/
virtual FVector getRelativePos(int index, const FVector &src);
virtual FVector getRelativePosNoCentering(int index, const FVector &src);
virtual FVector getRelativePosCentering(int index, const FVector &v);
virtual FVector getRelativePosCenteringRaw(int index, const FVector &v);
/**
* Sets the viewport position within the starfield
*/
virtual void setViewportAngle(const FPoint &angles);
/**
* How many stars are currently locked onto
*/
virtual StarLockLevel getLockLevel() const { return _lockLevel; }
/**
* Adds the row for a locked in marker/star
* @remarks This can't be a pass-by-reference, since adding
* the vector for the star destroys the calling star vector
*/
virtual bool addLockedStar(const FVector v);
/**
* Removes the most recent locked in marker/star
* @remarks This can't be a pass-by-reference, since adding
* the vector for the star destroys the calling star vector
*/
virtual bool removeLockedStar();
/**
* All arguments are return values
* First is the x center coordinate relative to y
* Second is the x center coordinate relative to z
* Third is the first x center pixel offset
* Fourth is the second x center pixel offset
*/
virtual void getRelativeXCenterPixels(double *v1, double *v2, double *v3, double *v4);
/**
* Load the data for the class from file
*/
virtual void load(SimpleFile *file, int param);
/**
* Save the data for the class to file
*/
virtual void save(SimpleFile *file, int indent);
/**
* Calculates the angle of rotation of y that achieves
* the minimum distance to x.
* The angle is in degrees.
* Also returns the minimum distance calculated
*/
float calcAngleForMinDist(FVector &x, FVector &y, float &minDistance);
/**
* Returns true for whether the camera has been moved
*/
bool isMoved() const { return _isMoved; }
/**
* Sets the camera as having been moved
*/
void setIsMoved() { _isMoved = true; }
/**
* Resets the flag for whether the camera has moved
*/
void clearIsMoved() { _isMoved = false; }
/**
* Lock in the first matched star marker
*/
bool lockMarker1(FVector v1, FVector v2, FVector v3);
/**
* Lock in the second matched star marker
*/
bool lockMarker2(CViewport *viewport, const FVector &v);
/**
* Lock in the third and final matched star marker
*/
bool lockMarker3(CViewport *viewport, const FVector &v);
};
} // End of namespace Titanic
#endif /* TITANIC_CAMERA_H */

View File

@@ -0,0 +1,123 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/const_boundaries.h"
#include "titanic/star_control/camera.h"
#include "titanic/star_control/star_field.h"
#include "titanic/star_control/surface_area.h"
#include "titanic/support/files_manager.h"
#include "titanic/titanic.h"
#include "math/utils.h"
namespace Titanic {
#define ARRAY_COUNT 876
CConstBoundaries::CConstBoundaries() {
}
bool CConstBoundaries::initialize() {
double y, z, ra, dec, phi, theta;
// Get a reference to the starfield points resource
Common::SeekableReadStream *stream = g_vm->_filesManager->getResource("STARFIELD/POINTS");
assert(stream && stream->size() == (12 * ARRAY_COUNT));
_data.resize(ARRAY_COUNT);
for (int idx = 0; idx < ARRAY_COUNT; ++idx) {
CBoundaryVector &entry = _data[idx];
// Get the next set of values
entry._isDrawn = (idx == 0) ? 0 : stream->readUint32LE() != 0;
y = stream->readSint32LE();
z = stream->readSint32LE();
ra = y * 360.0F / 24000.0F;
dec = z / 100.0F;
// Work the polar coordinates
phi = Math::deg2rad<double>(ra);
theta = Math::deg2rad<double>(dec);
entry._x = UNIVERSE_SCALE * cos(theta) * cos(phi);
entry._y = UNIVERSE_SCALE * cos(theta) * sin(phi);
entry._z = UNIVERSE_SCALE * sin(theta);
}
delete stream;
return true;
}
void CConstBoundaries::draw(CSurfaceArea *surface, CCamera *camera) {
if (_data.empty())
return;
// get the current camera transform.
FPose pose = camera->getPose();
float threshold = camera->getFrontClip();
float centerX = (float)surface->_width / 2.0f;
float centerY = (float)surface->_height / 2.0f;
FVector ec0, ec1, wc;
FVector sc0, sc1;
// Get the starting point
wc = _data[0];
ec0._x = wc._x * pose._row1._x + wc._y * pose._row2._x + wc._z * pose._row3._x + pose._vector._x;
ec0._y = wc._x * pose._row1._y + wc._y * pose._row2._y + wc._z * pose._row3._y + pose._vector._y;
ec0._z = wc._x * pose._row1._z + wc._y * pose._row2._z + wc._z * pose._row3._z + pose._vector._z;
// Set the drawing mode and color
surface->_pixel = 0xff0000;
uint oldPixel = surface->_pixel;
surface->setColorFromPixel();
SurfaceAreaMode oldMode = surface->setMode(SA_SOLID);
// Iterate through each remaining point
for (uint idx = 1; idx < _data.size(); ++idx) {
// Process the next point
wc = _data[idx];
ec1._x = wc._x * pose._row1._x + wc._y * pose._row2._x + wc._z * pose._row3._x + pose._vector._x;
ec1._y = wc._x * pose._row1._y + wc._y * pose._row2._y + wc._z * pose._row3._y + pose._vector._y;
ec1._z = wc._x * pose._row1._z + wc._y * pose._row2._z + wc._z * pose._row3._z + pose._vector._z;
// Is this connected to the previous point?
if (_data[idx]._isDrawn) {
if (ec0._z > threshold && ec1._z > threshold) {
// Render the line
sc0 = camera->getRelativePos(2, ec0);
sc1 = camera->getRelativePos(2, ec1);
surface->drawLine(FPoint(sc0._x + centerX, sc0._y + centerY),
FPoint(sc1._x + centerX, sc1._y + centerY));
}
}
ec0 = ec1;
}
// Reset back to previous
surface->_pixel = oldPixel;
surface->setColorFromPixel();
surface->setMode(oldMode);
}
} // End of namespace Titanic

View File

@@ -0,0 +1,56 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_CONST_BOUNDARIES_H
#define TITANIC_CONST_BOUNDARIES_H
#include "titanic/star_control/fvector.h"
#include "common/array.h"
namespace Titanic {
class CCamera;
class CSurfaceArea;
class CConstBoundaries {
struct CBoundaryVector : public FVector {
bool _isDrawn; // Line is drawn to previous point
CBoundaryVector() : FVector(), _isDrawn(false) {}
};
private:
Common::Array<CBoundaryVector> _data;
public:
CConstBoundaries();
/**
* Initialize the array
*/
bool initialize();
/**
* Draw the boundary structure
*/
void draw(CSurfaceArea *surface, CCamera *camera);
};
} // End of namespace Titanic
#endif /* TITANIC_CONST_BOUNDARIES_H */

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/constellations.h"
#include "titanic/star_control/camera.h"
#include "titanic/star_control/star_field.h"
#include "titanic/star_control/surface_area.h"
#include "titanic/support/files_manager.h"
#include "titanic/titanic.h"
#include "math/utils.h"
namespace Titanic {
#define TOTAL_CONSTELLATIONS 80
bool CConstellations::initialize() {
double ra, dec, phi, theta;
// Get a reference to the starfield points resource
Common::SeekableReadStream *stream = g_vm->_filesManager->getResource("STARFIELD/POINTS2");
_data.resize(TOTAL_CONSTELLATIONS);
for (int rootCtr = 0; rootCtr < TOTAL_CONSTELLATIONS; ++rootCtr) {
// Get the number of points in the constellation
int count = stream->readUint32LE();
// Read in the points
Constellation &rootEntry = _data[rootCtr];
rootEntry.resize(count);
for (int idx = 0; idx < count; ++idx) {
ConstellationLine &cl = rootEntry[idx];
FVector *vectors[2] = { &cl._start, &cl._end};
for (int fctr = 0; fctr < 2; ++fctr) {
ra = (double)stream->readSint32LE() * 360.0f / 24000.0f;
dec = (double)stream->readSint32LE() / 100.0f;
// Work the polar coordinates
phi = Math::deg2rad<double>(ra);
theta = Math::deg2rad<double>(dec);
vectors[fctr]->_x = UNIVERSE_SCALE * cos(theta) * cos(phi);
vectors[fctr]->_y = UNIVERSE_SCALE * cos(theta) * sin(phi);
vectors[fctr]->_z = UNIVERSE_SCALE * sin(theta);
}
}
}
delete stream;
return true;
}
void CConstellations::draw(CSurfaceArea *surface, CCamera *camera) {
if (_data.empty())
return;
FPose pose = camera->getPose();
double threshold = camera->getFrontClip();
double centerX = (double)surface->_width / 2.0F;
double centerY = (double)surface->_height / 2.0F;
FVector ec0, ec1;
FVector sc0, sc1;
// Set the drawing mode, saving the old mode
surface->_pixel = 0xffff00;
uint oldPixel = surface->_pixel;
surface->setColorFromPixel();
SurfaceAreaMode oldMode = surface->setMode(SA_SOLID);
// Iterate through the constellations
for (uint conCtr = 0; conCtr < _data.size(); ++conCtr) {
const Constellation &con = _data[conCtr];
if (con.empty())
continue;
for (uint idx = 0; idx < con.size(); ++idx) {
const FVector &ps = con[idx]._start;
ec0._x = ps._x * pose._row1._x + ps._y * pose._row2._x + ps._z * pose._row3._x + pose._vector._x;
ec0._y = ps._x * pose._row1._y + ps._y * pose._row2._y + ps._z * pose._row3._y + pose._vector._y;
ec0._z = ps._x * pose._row1._z + ps._y * pose._row2._z + ps._z * pose._row3._z + pose._vector._z;
const FVector &pe = con[idx]._end;
ec1._x = pe._x * pose._row1._x + pe._y * pose._row2._x + pe._z * pose._row3._x + pose._vector._x;
ec1._y = pe._x * pose._row1._y + pe._y * pose._row2._y + pe._z * pose._row3._y + pose._vector._y;
ec1._z = pe._x * pose._row1._z + pe._y * pose._row2._z + pe._z * pose._row3._z + pose._vector._z;
// Draw if the constellation line is visible
if (ec0._z > threshold && ec1._z > threshold) {
sc0 = camera->getRelativePos(2, ec0);
sc1 = camera->getRelativePos(2, ec1);
surface->drawLine(Point(sc0._x + centerX, sc0._y + centerY),
Point(sc1._x + centerX, sc1._y + centerY));
}
}
}
// Restore the old state
surface->_pixel = oldPixel;
surface->setColorFromPixel();
surface->setMode(oldMode);
}
} // End of namespace Titanic

View File

@@ -0,0 +1,54 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_CONSTELLATIONS_H
#define TITANIC_CONSTELLATIONS_H
#include "titanic/star_control/fvector.h"
#include "common/array.h"
namespace Titanic {
class CCamera;
class CSurfaceArea;
class CConstellations {
struct ConstellationLine {
FVector _start, _end;
};
typedef Common::Array<ConstellationLine> Constellation;
private:
Common::Array<Constellation> _data;
public:
/**
* Initializes the data
*/
bool initialize();
/**
* Draw the starfield points
*/
void draw(CSurfaceArea *surface, CCamera *camera);
};
} // End of namespace Titanic
#endif /* TITANIC_CONSTELLATIONS_H */

View File

@@ -0,0 +1,50 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_ERROR_CODE_H
#define TITANIC_ERROR_CODE_H
namespace Titanic {
class CErrorCode {
private:
int _value;
public:
CErrorCode() : _value(0) {}
/**
* Sets the error code
*/
void set() { _value = 1; }
/**
* Gets the error code and resets it
*/
int get() {
int result = _value;
_value = 0;
return result;
}
};
} // End of namespace Titanic
#endif /* TITANIC_ERROR_CODE_H */

View File

@@ -0,0 +1,95 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/flight_manager_base.h"
#include "titanic/star_control/fmatrix.h"
namespace Titanic {
CFlightManagerBase::CFlightManagerBase() : _srcPos(0.0, 1000000.0, 0.0) {
_active = false;
_distance = 0.0;
_flight = false;
_step = 0.0;
_step1 = 0;
_accCount = 0;
_traCount = 0;
_decCount = 0;
_totCount = 0;
_currentSpin = 0.0;
_spinStep = 0.0;
}
void CFlightManagerBase::clear() {
_srcPos.clear();
_destPos.clear();
_currentSpin = 1.0;
_distance = 0.0;
_active = false;
_flight = false;
}
void CFlightManagerBase::setPath(const FVector &from, const FVector &to) {
_srcPos = from;
_destPos = to;
_direction = _destPos - _srcPos;
// normalization won't happen if _direction is zero vector and that is okay
float temp = 0.0;
_direction.normalize(temp);
_distance = temp;
_active = false;
_flight = false;
_accCount = -1;
_traCount = -1;
_decCount = -1;
_totCount = -1;
_currentSpin = 1.0;
}
void CFlightManagerBase::buildMotionTable(int sustain, int decay, float distance) {
_step = distance / (sustain + 2 * decay);
_step1 = decay * _step;
_accCount = GAMMA_TABLE_SIZE - 1;
_traCount = sustain;
_decCount = GAMMA_TABLE_SIZE - 1;
_totCount = _accCount + _traCount + _decCount;
// Main calculation loop
double radix = 4.0;
double index = 0.0;
double step = 1.0 / (double)(GAMMA_TABLE_SIZE);
double total = 0.0;
for (int i = 0; i < GAMMA_TABLE_SIZE; ++i) {
_gammaTable[GAMMA_TABLE_SIZE - i - 1] = pow(index, radix);
index += step;
total += _gammaTable[GAMMA_TABLE_SIZE - i - 1];
}
// normalise them
for (int i = 0; i < GAMMA_TABLE_SIZE; ++i)
_gammaTable[i] = _step1 * _gammaTable[i] / total;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,86 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_FLIGHT_MANAGER_BASE_H
#define TITANIC_FLIGHT_MANAGER_BASE_H
#include "titanic/star_control/fvector.h"
#include "titanic/star_control/orientation_changer.h"
#include "common/array.h"
namespace Titanic {
#define GAMMA_TABLE_SIZE 32
class CErrorCode;
class FMatrix;
enum MoverState { NOT_ACTIVE = 0, MOVING = 1, DONE_MOVING = 2 };
/**
* Base class for flight manager handling automated movement
*/
class CFlightManagerBase {
protected:
bool _active;
FVector _srcPos, _destPos;
double _distance;
FVector _direction;
bool _flight;
double _step;
double _step1;
int _accCount;
int _traCount;
int _decCount;
int _totCount;
double _gammaTable[GAMMA_TABLE_SIZE];
double _currentSpin;
double _spinStep;
COrientationChanger _orientationChanger;
public:
CFlightManagerBase();
virtual ~CFlightManagerBase() {}
/**
* Clear src and dest orientation and set some default values for other fields
*/
void clear();
/**
* Setup a transition to from one position to another
*/
void setPath(const FVector &from, const FVector &to);
/**
* Applys speeds to the mover. More than one application is usually done for several transitions
*/
virtual MoverState move(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) { return DONE_MOVING; }
/**
* Given a distance to cover, builds an acceleration table for the journey
*/
virtual void buildMotionTable(int sustain, int decay, float distance);
bool isActive() const { return _active; }
};
} // End of namespace Titanic
#endif /* TITANIC_FLIGHT_MANAGER_BASE_H */

View File

@@ -0,0 +1,102 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/flight_manager_marked.h"
#include "titanic/star_control/error_code.h"
namespace Titanic {
void CMarkedAutoMover::setFlight(const FVector &oldPos, const FVector &newPos,
const FMatrix &oldOrientation, const FMatrix &newOrientation) {
CFlightManagerBase::setPath(oldPos, newPos);
double distance = _distance;
_active = true;
_flight = true;
buildMotionTable(120, 4, distance);
_orientationChanger.load(oldOrientation, newOrientation);
_currentSpin = 0.0;
if (_totCount == 0) {
_spinStep = 0.1;
_active = true;
} else {
_spinStep = 1.0 / _totCount;
_active = true;
}
}
MoverState CMarkedAutoMover::move(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) {
if (!_active)
return NOT_ACTIVE;
_currentSpin += _spinStep;
orientation = _orientationChanger.getOrientation(_currentSpin);
errorCode.set();
if (_accCount >= 0) {
double speedVal = _gammaTable[_accCount];
pos += _direction * speedVal;
getVectorOnPath(pos);
--_accCount;
errorCode.set();
return MOVING;
} else if (_traCount > 0) {
pos += _direction * _step;
getVectorOnPath(pos);
--_traCount;
errorCode.set();
return MOVING;
} else if (_decCount >= 0) {
double speedVal = _gammaTable[GAMMA_TABLE_SIZE - 1 - _decCount];
pos += _direction * speedVal;
getVectorOnPath(pos);
--_decCount;
errorCode.set();
return MOVING;
} else {
_active = false;
return DONE_MOVING;
}
}
void CMarkedAutoMover::getVectorOnPath(FVector &pos) const {
double distance = _direction.getDistance(pos);
distance /= _distance;
if (distance <= 0.0) {
pos = _srcPos;
} else if (distance >= 1.0) {
pos = _destPos;
} else {
pos = FVector(
(_destPos._x - _srcPos._x) * distance + _srcPos._x,
(_destPos._y - _srcPos._y) * distance + _srcPos._y,
(_destPos._z - _srcPos._z) * distance + _srcPos._z
);
}
}
} // End of namespace Titanic

View File

@@ -0,0 +1,54 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_FLIGHT_MANAGER_MARKED_H
#define TITANIC_FLIGHT_MANAGER_MARKED_H
#include "titanic/star_control/flight_manager_base.h"
namespace Titanic {
/**
* Automatic camera mover used when one or more markers have been set
*/
class CMarkedAutoMover : public CFlightManagerBase {
private:
/**
* Given a vector, figures out how far is from the movement source, and
* returns a vector on the proper point along the path to the destination
* with that same distance from the source.
*/
void getVectorOnPath(FVector &pos) const;
public:
~CMarkedAutoMover() override {}
void setFlight(const FVector &oldPos, const FVector &newPos,
const FMatrix &oldOrientation, const FMatrix &newOrientation);
/**
* Applys speeds to the mover. More than one application is usually done for several transitions
*/
MoverState move(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) override;
};
} // End of namespace Titanic
#endif /* TITANIC_FLIGHT_MANAGER_MARKED_H */

View File

@@ -0,0 +1,167 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/flight_manager_unmarked.h"
#include "titanic/star_control/fmatrix.h"
#include "titanic/star_control/error_code.h"
namespace Titanic {
void CFlightManagerUnmarked::setOrientations(const FMatrix &srcOrient, const FMatrix &destOrient) {
CFlightManagerBase::clear();
_orientationChanger.load(srcOrient, destOrient);
_spinStep = 0.1;
_currentSpin = 0.0;
_accCount = _traCount = _decCount = -1;
_active = true;
}
void CFlightManagerUnmarked::setPathOrient(const FVector &srcV, const FVector &destV, const FMatrix &orientation) {
CFlightManagerBase::setPath(srcV, destV);
if (_distance > 8000.0) {
_active = true;
_flight = true;
buildMotionTable(120, 4, _distance - 8000.0);
}
FVector row3 = orientation._row3;
double mult = _direction._x * row3._x + _direction._y * row3._y + _direction._z * row3._z;
_currentSpin = 1.0;
bool flag = false;
if (mult < 1.0) {
if (mult >= 1.0 - 1.0e-10)
flag = true;
} else {
if (mult <= 1.0 + 1.0e-10)
flag = true;
}
if (!flag) {
FVector tempV1;
tempV1 = row3.half(_direction);
tempV1 = row3.half(tempV1);
tempV1 = row3.half(tempV1);
tempV1 = row3.half(tempV1);
FMatrix newOrient;
newOrient.set(tempV1);
_orientationChanger.load(orientation, newOrient);
_currentSpin = 0.0;
_spinStep = 0.1;
_active = true;
}
}
MoverState CFlightManagerUnmarked::move(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) {
FVector v1, v2, v3, v4;
if (!_active)
return NOT_ACTIVE;
// Firstly we have to do a transition of the camera orientation from
// it's current position to one where the destination star is centered
if (_currentSpin < 1.0) {
_currentSpin += _spinStep;
orientation = _orientationChanger.getOrientation(_currentSpin);
errorCode.set();
return MOVING;
}
// From here on, we handle the movement to the given destination
if (!_flight) {
_active = false;
return DONE_MOVING;
}
v2 = orientation._row3;
v3 = _destPos - pos;
float unusedScale = 0.0;
if (!v3.normalize(unusedScale)) {
// Do the normalization, put the scale amount in unusedScale,
// but if it is unsuccessful, crash
assert(unusedScale);
}
double val = orientation._row3._x * v3._x + orientation._row3._y * v3._y + orientation._row3._z * v3._z;
bool flag = false;
if (val < 1.0) {
if (val >= 1.0 - 1.0e-10)
flag = true;
} else {
if (val <= 1.0 + 1.0e-10)
flag = true;
}
if (!flag) {
v1 = v2.half(v3);
v1 = v2.half(v1);
v1 = v2.half(v1);
v1 = v2.half(v1);
orientation.set(v1);
v2 = v1;
}
if (_accCount >= 0) {
double speedVal = _gammaTable[_accCount];
v1 = v2 * speedVal;
pos += v1;
--_accCount;
errorCode.set();
return MOVING;
}
if (_traCount > 0) {
v1._z = v2._z * _step;
v1._x = v2._x * _step;
pos._x = v1._x + pos._x;
pos._y = v2._y * _step + pos._y;
pos._z = v1._z + pos._z;
--_traCount;
errorCode.set();
return MOVING;
}
if (_decCount >= 0) {
double speedVal = _gammaTable[GAMMA_TABLE_SIZE - 1 - _decCount];
v1._y = v2._y * speedVal;
v1._z = v2._z * speedVal;
v1._x = v2._x * speedVal;
pos._y = v1._y + pos._y;
pos._z = v1._z + pos._z;
pos._x = pos._x + v1._x;
--_decCount;
errorCode.set();
return MOVING;
}
_active = false;
return DONE_MOVING;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,48 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_FLIGHT_MANAGER_UNMARKED_H
#define TITANIC_FLIGHT_MANAGER_UNMARKED_H
#include "titanic/star_control/flight_manager_base.h"
namespace Titanic {
/**
* Automatic camera mover used when no markers have been set
*/
class CFlightManagerUnmarked : public CFlightManagerBase {
public:
~CFlightManagerUnmarked() override {}
virtual void setOrientations(const FMatrix &srcOrient, const FMatrix &destOrient);
/**
* Sets the path and starting and ending orientations to animate movement between
*/
void setPathOrient(const FVector &srcV, const FVector &destV, const FMatrix &orientation);
MoverState move(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) override;
};
} // End of namespace Titanic
#endif /* TITANIC_FLIGHT_MANAGER_UNMARKED_H */

View File

@@ -0,0 +1,136 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/fmatrix.h"
#include "titanic/support/simple_file.h"
namespace Titanic {
// Non-member functions
void matProd(const FMatrix &a, const FMatrix &m, FMatrix &C) {
C._row1._x = a._row1._y * m._row2._x + a._row1._z * m._row3._x + a._row1._x * m._row1._x;
C._row1._y = a._row1._x * m._row1._y + m._row2._y * a._row1._y + m._row3._y * a._row1._z;
C._row1._z = a._row1._x * m._row1._z + a._row1._y * m._row2._z + a._row1._z * m._row3._z;
C._row2._x = m._row1._x * a._row2._x + m._row3._x * a._row2._z + m._row2._x * a._row2._y;
C._row2._y = m._row3._y * a._row2._z + m._row1._y * a._row2._x + m._row2._y * a._row2._y;
C._row2._z = a._row2._z * m._row3._z + a._row2._x * m._row1._z + a._row2._y * m._row2._z;
C._row3._x = m._row1._x * a._row3._x + a._row3._z * m._row3._x + a._row3._y * m._row2._x;
C._row3._y = a._row3._y * m._row2._y + a._row3._z * m._row3._y + a._row3._x * m._row1._y;
C._row3._z = a._row3._x * m._row1._z + a._row3._y * m._row2._z + a._row3._z * m._row3._z;
}
// Member functions
FMatrix::FMatrix() :
_row1(1.0, 0.0, 0.0), _row2(0.0, 1.0, 0.0), _row3(0.0, 0.0, 1.0) {
}
FMatrix::FMatrix(const FVector &row1, const FVector &row2, const FVector &row3) {
_row1 = row1;
_row2 = row2;
_row3 = row3;
}
void FMatrix::load(SimpleFile *file, int param) {
_row1._x = file->readFloat();
_row1._y = file->readFloat();
_row1._z = file->readFloat();
_row2._x = file->readFloat();
_row2._y = file->readFloat();
_row2._z = file->readFloat();
_row3._x = file->readFloat();
_row3._y = file->readFloat();
_row3._z = file->readFloat();
}
void FMatrix::save(SimpleFile *file, int indent) {
file->writeFloatLine(_row1._x, indent);
file->writeFloatLine(_row1._y, indent);
file->writeFloatLine(_row1._z, indent);
file->writeFloatLine(_row2._x, indent);
file->writeFloatLine(_row2._y, indent);
file->writeFloatLine(_row2._z, indent);
file->writeFloatLine(_row3._x, indent);
file->writeFloatLine(_row3._y, indent);
file->writeFloatLine(_row3._z, indent);
}
void FMatrix::clear() {
_row1.clear();
_row2.clear();
_row3.clear();
}
void FMatrix::identity() {
_row1 = FVector(1.0, 0.0, 0.0);
_row2 = FVector(0.0, 1.0, 0.0);
_row3 = FVector(0.0, 0.0, 1.0);
}
void FMatrix::set(const FMatrix &m) {
_row1 = m._row1;
_row2 = m._row2;
_row3 = m._row3;
}
void FMatrix::set(const FVector &row1, const FVector &row2, const FVector &row3) {
_row1 = row1;
_row2 = row2;
_row3 = row3;
}
void FMatrix::set(const FVector &v) {
_row3 = v;
_row2 = _row3.swapComponents();
_row1 = _row3.crossProduct(_row2);
float unused_scale=0.0;
if (!_row1.normalize(unused_scale)) {
// Do the normalization, put the scale amount in unused_scale,
// but if it is unsuccessful, crash
assert(unused_scale);
}
_row2 = _row3.crossProduct(_row1);
if (!_row2.normalize(unused_scale)) {
// Do the normalization, put the scale amount in unused_scale,
// but if it is unsuccessful, crash
assert(unused_scale);
}
}
void FMatrix::matRProd(const FMatrix &m) {
FMatrix C = FMatrix();
FMatrix A = FMatrix(_row1, _row2, _row3);
matProd(A, m, C);
this->set(C);
}
void FMatrix::matLProd(const FMatrix &m) {
FMatrix C = FMatrix();
FMatrix A = FMatrix(_row1, _row2, _row3);
matProd(m, A, C);
this->set(C);
}
} // End of namespace Titanic

View File

@@ -0,0 +1,124 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_FMATRIX_H
#define TITANIC_FMATRIX_H
#include "titanic/star_control/fvector.h"
namespace Titanic {
class SimpleFile;
/**
* Floating point matrix class.
*/
class FMatrix {
public:
FVector _row1;
FVector _row2;
FVector _row3;
public:
FMatrix();
FMatrix(const FVector &, const FVector &, const FVector &);
/**
* Load the data for the class from file
*/
void load(SimpleFile *file, int param);
/**
* Save the data for the class to file
*/
void save(SimpleFile *file, int indent);
/**
* Clears the matrix
*/
void clear();
/**
* Sets up an identity matrix
*/
void identity();
/**
* Sets the data for the matrix
*/
void set(const FMatrix &m);
/**
* Sets the data for the matrix
*/
void set(const FVector &row1, const FVector &row2, const FVector &row3);
/**
* Sets the data for the matrix from a vector
*/
void set(const FVector &v);
/**
* Changes this matrix, A, to be C, where C=Am. Matrix m multiplies this matrix (A) on its Right.
* m is said to premultiply A (the previous this matrix).
*/
void matRProd(const FMatrix &m);
/**
* Changes this matrix, A, to be C, where C=mA. Matrix m multiplies this matrix (A) on its Left.
* m is said to postmultiply A (the previous this matrix).
*/
void matLProd(const FMatrix &m);
/**
* Returns true if the passed matrix equals this one
*/
bool operator==(const FMatrix &src) {
return _row1 == src._row1 && _row2 == src._row2 && _row3 == src._row3;
}
/**
* Returns true if the passed matrix does not equal this one
*/
bool operator!=(const FMatrix &src) {
return !operator==(src);
}
/**
* Allows accessing rows as an array
*/
FVector &operator[](int idx) {
assert(idx >= 0 && idx <= 2);
FVector *rows[3] = { &_row1, &_row2, &_row3 };
return *rows[idx];
}
};
/**
* Puts the matrix product between a and m in C, C = am
* Called by MatLProd and MatLProd
* Caller must preallocate output matrix
*/
void matProd(const FMatrix &a, const FMatrix &m, FMatrix &C);
} // End of namespace Titanic
#endif /* TITANIC_FMATRIX_H */

View File

@@ -0,0 +1,36 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/fpoint.h"
namespace Titanic {
float FPoint::normalize() {
float hyp = sqrt(_x * _x + _y * _y);
assert(hyp != 0.0);
float fraction = 1.0 / hyp;
_x *= fraction;
_y *= fraction;
return hyp;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,64 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_FPOINT_H
#define TITANIC_FPOINT_H
#include "common/rect.h"
namespace Titanic {
/**
* Floating point Point class
*/
class FPoint {
public:
float _x, _y;
public:
FPoint() : _x(0), _y(0) {}
FPoint(float x, float y) : _x(x), _y(y) {}
FPoint(const Common::Point &pt) : _x(pt.x), _y(pt.y) {}
bool operator==(const FPoint &p) const { return _x == p._x && _y == p._y; }
bool operator!=(const FPoint &p) const { return _x != p._x || _y != p._y; }
FPoint operator+(const FPoint &delta) const { return FPoint(_x + delta._x, _y + delta._y); }
FPoint operator-(const FPoint &delta) const { return FPoint(_x - delta._x, _y - delta._y); }
void operator+=(const FPoint &delta) {
_x += delta._x;
_y += delta._y;
}
void operator-=(const FPoint &delta) {
_x -= delta._x;
_y -= delta._y;
}
/**
* Normalises the X and Y coordinates as fractions relative to the
* value of the hypotenuse formed by a triangle from the origin (0,0)
*/
float normalize();
};
} // End of namespace Titanic
#endif /* TITANIC_FPOINT_H */

View File

@@ -0,0 +1,237 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/fpose.h"
#include "titanic/star_control/matrix_transform.h"
#include "titanic/star_control/matrix_inv.h"
#include "math/utils.h"
namespace Titanic {
// Non-member functions
void fposeProd(const FPose &a, const FPose &m, FPose &C) {
C._row1._x = a._row1._y * m._row2._x + a._row1._z * m._row3._x + a._row1._x * m._row1._x;
C._row1._y = a._row1._x * m._row1._y + m._row2._y * a._row1._y + m._row3._y * a._row1._z;
C._row1._z = a._row1._x * m._row1._z + a._row1._y * m._row2._z + a._row1._z * m._row3._z;
C._row2._x = m._row1._x * a._row2._x + m._row3._x * a._row2._z + m._row2._x * a._row2._y;
C._row2._y = m._row3._y * a._row2._z + m._row1._y * a._row2._x + m._row2._y * a._row2._y;
C._row2._z = a._row2._z * m._row3._z + a._row2._x * m._row1._z + a._row2._y * m._row2._z;
C._row3._x = m._row1._x * a._row3._x + a._row3._z * m._row3._x + a._row3._y * m._row2._x;
C._row3._y = a._row3._y * m._row2._y + a._row3._z * m._row3._y + a._row3._x * m._row1._y;
C._row3._z = a._row3._x * m._row1._z + a._row3._y * m._row2._z + a._row3._z * m._row3._z;
C._vector._x = a._vector._x * m._row1._x + a._vector._y * m._row2._x + a._vector._z * m._row3._x + m._vector._x;
C._vector._y = a._vector._x * m._row1._y + a._vector._y * m._row2._y + a._vector._z * m._row3._y + m._vector._y;
C._vector._z = a._vector._x * m._row1._z + a._vector._y * m._row2._z + a._vector._z * m._row3._z + m._vector._z;
}
// Member functions
FPose::FPose() {
clear();
}
FPose::FPose(Axis axis, float amount) {
setRotationMatrix(axis, amount);
}
FPose::FPose(const FPose &s1, const FPose &s2) {
fposeProd(s1, s2, *this);
}
FPose::FPose(int mode, const FVector &src) {
switch (mode) {
case 0:
_row1._x = 1.0;
_row2._y = 1.0;
_row3._z = 1.0;
_vector = src;
break;
case 1:
_row1._x = src._x;
_row2._y = src._y;
_row3._z = src._z;
break;
default:
_row1._x = 1.0;
_row2._y = 1.0;
_row3._z = 1.0;
break;
}
}
void FPose::identity() {
FMatrix::identity();
_vector.clear();
}
// Source: https://en.wikipedia.org/wiki/Rotation_matrix
void FPose::setRotationMatrix(Axis axis, float amount) {
float sinVal = sin(Math::deg2rad<float>(amount));
float cosVal = cos(Math::deg2rad<float>(amount));
switch (axis) {
case X_AXIS:
_row1._x = 1.0;
_row1._y = 0.0;
_row1._z = 0.0;
_row2._x = 0.0;
_row2._y = cosVal;
_row2._z = sinVal;
_row3._x = 0.0;
_row3._y = -sinVal;
_row3._z = cosVal;
break;
case Y_AXIS:
_row1._x = cosVal;
_row1._y = 0.0;
_row1._z = -sinVal;
_row2._x = 0.0;
_row2._y = 1.0;
_row2._z = 0.0;
_row3._x = sinVal;
_row3._y = 0.0;
_row3._z = cosVal;
break;
case Z_AXIS:
_row1._x = cosVal;
_row1._y = sinVal;
_row1._z = 0.0;
_row2._x = -sinVal;
_row2._y = cosVal;
_row2._z = 0.0;
_row3._x = 0.0;
_row3._y = 0.0;
_row3._z = 1.0;
break;
default:
break;
}
_vector.clear();
}
void FPose::rotVectAxisY(double angleDeg) {
_row1.rotVectAxisY(angleDeg);
_row2.rotVectAxisY(angleDeg);
_row3.rotVectAxisY(angleDeg);
_vector.rotVectAxisY(angleDeg);
}
void FPose::copyFrom(const FPose &src) {
_row1 = src._row1;
_row2 = src._row2;
_row3 = src._row3;
_vector = src._vector;
}
void FPose::copyFrom(const FMatrix &src) {
_row1 = src._row1;
_row2 = src._row2;
_row3 = src._row3;
}
FPose FPose::inverseTransform() const {
FPose matrix_inv;
matrix_inv._row1._x = _row1._x;
matrix_inv._row2._x = _row1._y;
matrix_inv._row3._x = _row1._z;
matrix_inv._row1._y = _row2._x;
matrix_inv._row2._y = _row2._y;
matrix_inv._row3._y = _row2._z;
matrix_inv._row1._z = _row3._x;
matrix_inv._row2._z = _row3._y;
matrix_inv._row3._z = _row3._z;
float A[16]={_row1._x,_row1._y,_row1._z, 0.0,
_row2._x,_row2._y,_row2._z, 0.0,
_row3._x,_row3._y,_row3._z, 0.0,
_vector._x,_vector._y,_vector._z, 1.0};
// Inverse matrix
float B[16]={};
// B contains inverse of A
matrix4Inverse<float>(A,B);
matrix_inv._vector._x=B[12];
matrix_inv._vector._y=B[13];
matrix_inv._vector._z=B[14];
return matrix_inv;
}
//TODO: Check math and provide source
void FPose::loadTransform(const CMatrixTransform &src) {
double total = src.fn1();
double factor = (total <= 0.0) ? 0.0 : 2.0 / total;
FVector temp1V = src._vector * factor;
FVector temp2V = temp1V * src._vector;
double val1 = temp1V._y * src._vector._x;
double val2 = temp1V._z * src._vector._x;
double val3 = temp1V._z * src._vector._y;
double val4 = temp1V._x * src._field0;
double val5 = temp1V._y * src._field0;
double val6 = temp1V._z * src._field0;
_row1._x = 1.0 - (temp2V._z + temp2V._y);
_row1._y = val1 + val6;
_row1._z = val2 - val5;
_row2._x = val1 - val6;
_row2._y = 1.0 - (temp2V._z + temp2V._x);
_row2._z = val3 + val4;
_row3._x = val2 + val5;
_row3._y = val3 - val4;
_row3._z = 1.0 - (temp2V._y + temp2V._x);
_vector._x = 0;
_vector._y = 0;
_vector._z = 0;
}
FPose FPose::compose(const FMatrix &m) {
FPose dm;
FPose am;
am._row1 = m._row1;
am._row2 = m._row2;
am._row3 = m._row3;
fposeProd(*this, am, dm);
return dm;
}
FPose FPose::compose2(const FPose &m) {
FPose dm;
dm._row1 = _row1.matProdRowVect(m);
dm._row2 = _row2.matProdRowVect(m);
dm._row3 = _row3.matProdRowVect(m);
dm._vector = _vector.matProdRowVect(m);
return dm;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,106 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_FPOSE_H
#define TITANIC_FPOSE_H
#include "titanic/star_control/fmatrix.h"
namespace Titanic {
class CMatrixTransform;
/*
* This class combines a position and orientation in 3D space
*/
class FPose : public FMatrix {
public:
FVector _vector;
public:
FPose();
FPose(Axis axis, float amount);
FPose(int mode, const FVector &src);
/**
* This fpose is the fpose product of s1 (on the left) and s2 (on the right)
*/
FPose(const FPose &s1, const FPose &s2);
/**
* Sets an identity matrix
*/
void identity();
/**
* Sets a rotation matrix for the given axis for the given amount
*/
void setRotationMatrix(Axis axis, float val);
/**
* Rotate this FPose about the Y axis
*/
void rotVectAxisY(double angleDeg);
/**
* Copy from the specified source pose
*/
void copyFrom(const FPose &src);
/**
* Copy from the specified source matrix
*/
void copyFrom(const FMatrix &src);
/**
* Change this Daffine to have its first three columns be some mapping from src matrix
* and the 4rth column to be (three) zeros. The mapping is not as simple as replacing
* matching row/colmn indices
*/
void loadTransform(const CMatrixTransform &src);
/**
* The inverse of rotation and the position vector
*/
FPose inverseTransform() const;
/**
* Multiplication between this FPose (4x3) and a FMatrix (3x3)
* This is done by making the matrix be a FPose with a last row
* of zeros
*/
FPose compose(const FMatrix &m);
/**
* Multiplication between this FPose (4x3) and another FPose
* This FPose is on the left and m is on the right.
* The last row of m is added to the output component wise
*/
FPose compose2(const FPose &m);
};
/**
* Puts the fpose product between a and m in C, C = am
* Caller must preallocate output matrix
* Similar to matProd
*/
void fposeProd(const FPose &a, const FPose &m, FPose &C);
} // End of namespace Titanic
#endif /* TITANIC_FPOSE_H */

View File

@@ -0,0 +1,44 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/frange.h"
#include "common/algorithm.h"
namespace Titanic {
FRange::FRange() {
}
void FRange::reset() {
_min._x = _min._y = _min._z = 9.9999994e27F;
_max._x = _max._y = _max._z = -9.9999994e27F;
}
void FRange::expand(const FVector &v) {
_min._x = MIN(_min._x, v._x);
_min._y = MIN(_min._y, v._y);
_min._z = MIN(_min._z, v._z);
_max._x = MAX(_max._x, v._x);
_max._y = MAX(_max._y, v._y);
_max._z = MAX(_max._z, v._z);
}
} // End of namespace Titanic

View File

@@ -0,0 +1,49 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_FRANGE_H
#define TITANIC_FRANGE_H
#include "titanic/star_control/fvector.h"
namespace Titanic {
class FRange {
private:
FVector _min;
FVector _max;
public:
FRange();
/**
* Resets the minimum & maximum vector values
*/
void reset();
/**
* Expands the minimum & maximum as necessary to encompass the passed vector/
*/
void expand(const FVector &v);
};
} // End of namespace Titanic
#endif /* TITANIC_FRANGE_H */

View File

@@ -0,0 +1,38 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/frect.h"
namespace Titanic {
bool FRect::operator==(const FRect &r) const {
return left == r.left && top == r.top && right == r.right && bottom == r.bottom;
}
bool FRect::operator!=(const FRect &r) const {
return !operator==(r);
}
bool FRect::empty() const {
return left == right && top == bottom;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,57 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_FRECT_H
#define TITANIC_FRECT_H
namespace Titanic {
/**
* Floating point rect class
*/
class FRect {
public:
double left, top;
double right, bottom;
public:
FRect() : left(0), top(0), right(0), bottom(0) {}
FRect(double x1, double y1, double x2, double y2) :
left(x1), top(y1), right(x2), bottom(y2) {}
/**
* Returns true if the rects equal
*/
bool operator==(const FRect &p) const;
/**
* Returns true if the rects are not equal
*/
bool operator!=(const FRect &p) const;
/**
* Returns true if the rect is empty
*/
bool empty() const;
};
} // End of namespace Titanic
#endif /* TITANIC_FRECT_H */

View File

@@ -0,0 +1,140 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/fvector.h"
#include "titanic/star_control/fpose.h"
#include "common/str.h"
#include "math/utils.h"
namespace Titanic {
FVector FVector::swapComponents() const {
return FVector(
(ABS(_x - _y) < 0.00001 && ABS(_y - _z) < 0.00001 &&
ABS(_x - _z) < 0.00001) ? -_y : _y,
_z,
_x
);
}
FVector FVector::crossProduct(const FVector &src) const {
return FVector(
src._z * _y - _z * src._y,
src._x * _z - _x * src._z,
src._y * _x - _y * src._x
);
}
void FVector::rotVectAxisY(float angleDeg) {
float sinVal = sin(Math::deg2rad<double>(angleDeg));
float cosVal = cos(Math::deg2rad<double>(angleDeg));
float x = cosVal * _x - sinVal * _z;
float z = cosVal * _z + sinVal * _x;
_x = x;
_z = z;
}
bool FVector::normalize(float & hyp) {
hyp = sqrt(_x * _x + _y * _y + _z * _z);
if (hyp==0) {
return false;
}
_x *= 1.0 / hyp;
_y *= 1.0 / hyp;
_z *= 1.0 / hyp;
return true;
}
FVector FVector::half(const FVector &v) const {
FVector tempV = *this + v;
tempV.normalize();
return tempV;
}
FVector FVector::getPolarCoord() const {
FVector vector = *this;
FVector dest;
if (!vector.normalize(dest._x)) {
// Makes this vector have magnitude=1, put the scale amount in dest._x,
// but if it is unsuccessful, crash
assert(dest._x);
}
dest._y = acos(vector._y); // radian distance/angle that this vector's y component is from the +y axis,
// result is restricted to [0,pi]
dest._z = atan2(vector._x,vector._z); // result is restricted to [-pi,pi]
return dest;
}
float FVector::getDistance(const FVector &src) const {
float xd = src._x - _x;
float yd = src._y - _y;
float zd = src._z - _z;
return sqrt(xd * xd + yd * yd + zd * zd);
}
FVector FVector::matProdRowVect(const FPose &pose) const {
FVector v;
v._x = pose._row2._x * _y + pose._row3._x * _z + pose._row1._x * _x + pose._vector._x;
v._y = pose._row2._y * _y + pose._row3._y * _z + pose._row1._y * _x + pose._vector._y;
v._z = pose._row3._z * _z + pose._row2._z * _y + pose._row1._z * _x + pose._vector._z;
return v;
}
FPose FVector::getFrameTransform(const FVector &v) {
FPose matrix1, matrix2, matrix3, matrix4;
FVector vector1 = getPolarCoord();
matrix1.setRotationMatrix(X_AXIS, Math::rad2deg<double>(vector1._y));
matrix2.setRotationMatrix(Y_AXIS, Math::rad2deg<double>(vector1._z));
fposeProd(matrix1, matrix2, matrix3);
matrix4 = matrix3.inverseTransform();
vector1 = v.getPolarCoord();
matrix1.setRotationMatrix(X_AXIS, Math::rad2deg<double>(vector1._y));
matrix2.setRotationMatrix(Y_AXIS, Math::rad2deg<double>(vector1._z));
fposeProd(matrix1, matrix2, matrix3);
fposeProd(matrix4, matrix3, matrix1);
return matrix1;
}
FPose FVector::formRotXY() const {
FVector v1 = getPolarCoord();
FPose m1, m2;
m1.setRotationMatrix(X_AXIS, Math::rad2deg<double>(v1._y));
m2.setRotationMatrix(Y_AXIS, Math::rad2deg<double>(v1._z));
FPose m3;
fposeProd(m1, m2, m3);
return m3;
}
Common::String FVector::toString() const {
return Common::String::format("(%.3f,%.3f,%.3f)", _x, _y, _z);
}
} // End of namespace Titanic

View File

@@ -0,0 +1,176 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_FVECTOR_H
#define TITANIC_FVECTOR_H
#include "titanic/star_control/fpoint.h"
namespace Titanic {
enum Axis { X_AXIS, Y_AXIS, Z_AXIS };
class FPose;
/**
* Floating point vector class.
*/
class FVector {
public:
float _x, _y, _z;
public:
FVector() : _x(0), _y(0), _z(0) {}
FVector(float x, float y, float z) : _x(x), _y(y), _z(z) {}
/**
* Clears the vector
*/
void clear() {
_x = _y = _z = 0.0;
}
/**
* Returns a vector with all components of this vector circularlly rotated up 1.
* this x being _y, this y being _z, and this z being _x. A sign change may also
* be done on x/_y based on some conditions.
*/
FVector swapComponents() const;
/**
* Calculates the cross-product between this matrix and a passed one
*/
FVector crossProduct(const FVector &src) const;
/**
* Rotate this vector about the Y axis
*/
void rotVectAxisY(float angleDeg);
/**
* Attempts to normalizes the vector so the length from origin equals 1.0
* Return value is whether or not it was successful in normalizing
* First argument is scale value that normalizes the vector
*/
bool normalize(float &hyp);
void normalize() {
float hyp;
bool result = normalize(hyp);
assert(result);
}
/**
* Calculates a vector halfway between two given vectors
*/
FVector half(const FVector &v) const;
/**
* Returns a vector, v, that represents a magnitude, and two angles in radians
* 1. Scale this vector to be unit magnitude and store scale in x component of v
* 2. X rotation angle from +y axis of this vector is put in y component of v
* 3. z component output of v is the 4-quadrant angle that z makes with x (Y axis rotation)
*/
FVector getPolarCoord() const;
/**
* Returns the distance between a specified point and this one
*/
float getDistance(const FVector &src) const;
/**
* Returns a vector that is this vector on the left as a row vector
* times the 3x4 affine matrix on the right.
*/
FVector matProdRowVect(const FPose &pose) const;
/**
* Returns a matrix that contains the frame rotation based on this vector and
* a vector rotation based on input vector v
*/
FPose getFrameTransform(const FVector &v);
/**
* Constructs an affine matrix that does a x then a y axis frame rotation
* based on the orientation of this vector
*/
FPose formRotXY() const;
/**
* Returns true if the passed vector equals this one
*/
bool operator==(const FVector &src) const {
return _x == src._x && _y == src._y && _z == src._z;
}
/**
* Returns true if the passed vector does not equal this one
*/
bool operator!=(const FVector &src) const {
return _x != src._x || _y != src._y || _z != src._z;
}
FVector operator+(const FVector &delta) const {
return FVector(_x + delta._x, _y + delta._y, _z + delta._z);
}
FVector operator-(const FVector &delta) const {
return FVector(_x - delta._x, _y - delta._y, _z - delta._z);
}
const FVector operator*(float right) const {
return FVector(_x * right, _y * right, _z * right);
}
const FVector operator*(const FVector &right) const {
return FVector(_x * right._x, _y * right._y, _z * right._z);
}
void operator+=(const FVector &delta) {
_x += delta._x;
_y += delta._y;
_z += delta._z;
}
void operator-=(const FVector &delta) {
_x -= delta._x;
_y -= delta._y;
_z -= delta._z;
}
void operator+=(const FPoint &delta) {
_x += delta._x;
_y += delta._y;
}
void operator-=(const FPoint &delta) {
_x -= delta._x;
_y -= delta._y;
}
/**
* Converts the vector to a string
*/
Common::String toString() const;
};
} // End of namespace Titanic
#endif /* TITANIC_FVECTOR_H */

View File

@@ -0,0 +1,189 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Files matrix_inv.h are a part of the MESA 3D Library (MIT License)
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#ifndef TITANIC_MATRIX_INV_H
#define TITANIC_MATRIX_INV_H
namespace Titanic {
// 4x4 Matrix m is column major, e.x., m[3] is the row 4 column 1 element
// Modified version of MESA 3D library function (MIT license)
template <typename T>
bool matrix4Inverse(const T m[16], T invOut[16])
{
T temp_inv[16];
T determinant;
T determinant_inv;
int i;
temp_inv[0] = m[5] * m[10] * m[15] -
m[5] * m[11] * m[14] -
m[9] * m[6] * m[15] +
m[9] * m[7] * m[14] +
m[13] * m[6] * m[11] -
m[13] * m[7] * m[10];
temp_inv[4] = -m[4] * m[10] * m[15] +
m[4] * m[11] * m[14] +
m[8] * m[6] * m[15] -
m[8] * m[7] * m[14] -
m[12] * m[6] * m[11] +
m[12] * m[7] * m[10];
temp_inv[8] = m[4] * m[9] * m[15] -
m[4] * m[11] * m[13] -
m[8] * m[5] * m[15] +
m[8] * m[7] * m[13] +
m[12] * m[5] * m[11] -
m[12] * m[7] * m[9];
temp_inv[12] = -m[4] * m[9] * m[14] +
m[4] * m[10] * m[13] +
m[8] * m[5] * m[14] -
m[8] * m[6] * m[13] -
m[12] * m[5] * m[10] +
m[12] * m[6] * m[9];
temp_inv[1] = -m[1] * m[10] * m[15] +
m[1] * m[11] * m[14] +
m[9] * m[2] * m[15] -
m[9] * m[3] * m[14] -
m[13] * m[2] * m[11] +
m[13] * m[3] * m[10];
temp_inv[5] = m[0] * m[10] * m[15] -
m[0] * m[11] * m[14] -
m[8] * m[2] * m[15] +
m[8] * m[3] * m[14] +
m[12] * m[2] * m[11] -
m[12] * m[3] * m[10];
temp_inv[9] = -m[0] * m[9] * m[15] +
m[0] * m[11] * m[13] +
m[8] * m[1] * m[15] -
m[8] * m[3] * m[13] -
m[12] * m[1] * m[11] +
m[12] * m[3] * m[9];
temp_inv[13] = m[0] * m[9] * m[14] -
m[0] * m[10] * m[13] -
m[8] * m[1] * m[14] +
m[8] * m[2] * m[13] +
m[12] * m[1] * m[10] -
m[12] * m[2] * m[9];
temp_inv[2] = m[1] * m[6] * m[15] -
m[1] * m[7] * m[14] -
m[5] * m[2] * m[15] +
m[5] * m[3] * m[14] +
m[13] * m[2] * m[7] -
m[13] * m[3] * m[6];
temp_inv[6] = -m[0] * m[6] * m[15] +
m[0] * m[7] * m[14] +
m[4] * m[2] * m[15] -
m[4] * m[3] * m[14] -
m[12] * m[2] * m[7] +
m[12] * m[3] * m[6];
temp_inv[10] = m[0] * m[5] * m[15] -
m[0] * m[7] * m[13] -
m[4] * m[1] * m[15] +
m[4] * m[3] * m[13] +
m[12] * m[1] * m[7] -
m[12] * m[3] * m[5];
temp_inv[14] = -m[0] * m[5] * m[14] +
m[0] * m[6] * m[13] +
m[4] * m[1] * m[14] -
m[4] * m[2] * m[13] -
m[12] * m[1] * m[6] +
m[12] * m[2] * m[5];
temp_inv[3] = -m[1] * m[6] * m[11] +
m[1] * m[7] * m[10] +
m[5] * m[2] * m[11] -
m[5] * m[3] * m[10] -
m[9] * m[2] * m[7] +
m[9] * m[3] * m[6];
temp_inv[7] = m[0] * m[6] * m[11] -
m[0] * m[7] * m[10] -
m[4] * m[2] * m[11] +
m[4] * m[3] * m[10] +
m[8] * m[2] * m[7] -
m[8] * m[3] * m[6];
temp_inv[11] = -m[0] * m[5] * m[11] +
m[0] * m[7] * m[9] +
m[4] * m[1] * m[11] -
m[4] * m[3] * m[9] -
m[8] * m[1] * m[7] +
m[8] * m[3] * m[5];
temp_inv[15] = m[0] * m[5] * m[10] -
m[0] * m[6] * m[9] -
m[4] * m[1] * m[10] +
m[4] * m[2] * m[9] +
m[8] * m[1] * m[6] -
m[8] * m[2] * m[5];
determinant = m[0] * temp_inv[0] + m[1] * temp_inv[4] + m[2] * temp_inv[8] + m[3] * temp_inv[12];
if (determinant == 0)
return false;
determinant_inv = 1.0 / determinant;
for (i = 0; i < 16; i++)
invOut[i] = temp_inv[i] * determinant_inv;
return true;
}
} // End of namespace Titanic
#endif /* TITANIC_MATRIX_INV_H */

View File

@@ -0,0 +1,146 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/matrix_transform.h"
#include "titanic/star_control/fpose.h"
#include "common/textconsole.h"
namespace Titanic {
void CMatrixTransform::setup(double val1, double x, double y, double z) {
_field0 = val1;
_vector._x = x;
_vector._y = y;
_vector._z = z;
}
void CMatrixTransform::copyFrom(const CMatrixTransform &src) {
_field0 = src._field0;
_vector = src._vector;
}
double CMatrixTransform::fn1() const {
return _vector._x * _vector._x + _vector._y * _vector._y +
_vector._z * _vector._z + _field0 * _field0;
}
double CMatrixTransform::fn2(const CMatrixTransform &src) {
return _field0 * src._field0 + _vector._x * src._vector._x
+ _vector._y * src._vector._y + _vector._z * src._vector._z;
}
CMatrixTransform CMatrixTransform::resize(double factor) const {
CMatrixTransform dest;
dest.setup(_field0 * factor, _vector._x * factor, _vector._y * factor,
_vector._z * factor);
return dest;
}
void CMatrixTransform::fn4(const FMatrix &m) {
double total = m._row1._x + m._row3._z + m._row2._y + 1.0;
if (total <= 0.00001) {
total = m._row3._z;
if (m._row1._x <= m._row3._z) {
if (m._row2._y > total)
total = m._row2._y;
} else if (m._row1._x > total) {
total = m._row1._x;
}
if (total == m._row1._x) {
double val1 = sqrt(m._row1._x - -1.0 - m._row2._y - m._row3._z);
double val2 = 0.5 / val1;
_vector._x = val1 * 0.5;
_field0 = (m._row2._z - m._row3._y) * val2;
_vector._y = (m._row2._x + m._row1._y) * val2;
_vector._z = (m._row3._x + m._row1._z) * val2;
} else if (total == m._row2._y) {
double val1 = sqrt(m._row2._y - -1.0 - m._row3._z - m._row1._x);
double val2 = 0.5 / val1;
_vector._y = val1 * 0.5;
_field0 = (m._row3._x - m._row1._z) * val2;
_vector._z = (m._row3._y + m._row2._z) * val2;
_vector._x = (m._row2._x + m._row1._y) * val2;
} else if (total == m._row3._z) {
double val1 = sqrt(m._row3._z - -1.0 - m._row1._x - m._row2._y);
double val2 = 0.5 / val1;
_vector._z = val1 * 0.5;
_field0 = (m._row1._y - m._row2._x) * val2;
_vector._x = (m._row3._x + m._row1._z) * val2;
_vector._y = (m._row3._y + m._row2._z) * val2;
}
} else {
double val1 = 0.5 / sqrt(total);
_field0 = sqrt(total) * 0.5;
_vector._x = (m._row2._z - m._row3._y) * val1;
_vector._y = (m._row3._x - m._row1._z) * val1;
_vector._z = (m._row1._y - m._row2._x) * val1;
}
}
CMatrixTransform CMatrixTransform::fn5(double percent, const CMatrixTransform &src) {
CMatrixTransform sub1 = *this;
CMatrixTransform sub2, sub4;
CMatrixTransform dest;
double val1 = sub1.fn2(src);
if (val1 < 0.0) {
val1 = -val1;
sub2.setup(-sub1._field0, -sub1._vector._x, -sub1._vector._y, -sub1._vector._z);
sub1 = sub2;
}
if (val1 + 1.0 <= 0.00001) {
dest._vector._x = -sub1._vector._y;
dest._vector._y = sub1._vector._x;
dest._vector._z = -sub1._field0;
dest._field0 = sub1._vector._z;
double sin1 = sin(percent * M_PI);
double sin2 = sin((0.5 - percent) * M_PI);
dest._vector._x = sin1 * dest._vector._x + sub1._vector._x * sin2;
dest._vector._y = sub1._vector._y * sin2 + sub1._vector._x * sin1;
dest._vector._z = sin1 * -sub1._field0 + sub1._vector._z * sin2;
return dest;
}
CMatrixTransform t1, t2;
double val2;
if (1.0 - val1 <= 0.00001) {
val2 = 1.0 - percent;
t1 = src.resize(percent);
} else {
double cosVal = acos(val1);
double sinVal = sin(cosVal);
val2 = sin((1.0 - percent) * cosVal) / sinVal;
t1 = src.resize(sin(cosVal * percent) / sinVal);
}
t2 = sub1.resize(val2);
dest.setup(t2._field0 + t1._field0, t1._vector._x + t2._vector._x,
t1._vector._y + t2._vector._y, t1._vector._z + t2._vector._z);
return dest;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,58 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_MATRIX_TRANSFORM_H
#define TITANIC_MATRIX_TRANSFORM_H
#include "titanic/star_control/fvector.h"
namespace Titanic {
class FMatrix;
class CMatrixTransform {
private:
double fn2(const CMatrixTransform &src);
CMatrixTransform resize(double factor) const;
public:
double _field0;
FVector _vector;
public:
CMatrixTransform() : _field0(1.0) {}
/**
* Sets the field values
*/
void setup(double val1, double x, double y, double z);
/**
* Copies from another instance
*/
void copyFrom(const CMatrixTransform &src);
double fn1() const;
void fn4(const FMatrix &m);
CMatrixTransform fn5(double percent, const CMatrixTransform &src);
};
} // End of namespace Titanic
#endif /* TITANIC_MATRIX_TRANSFORM_H */

View File

@@ -0,0 +1,157 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/motion_control.h"
#include "titanic/star_control/base_stars.h"
#include "titanic/star_control/error_code.h"
#include "titanic/star_control/camera.h"
#include "titanic/support/simple_file.h"
namespace Titanic {
void CCallbackHandler::apply() {
_owner->addLockedStar(_vector);
}
/*------------------------------------------------------------------------*/
CMotionControl::CMotionControl(const CNavigationInfo *src) {
_lockCounter = 0;
_callback = nullptr;
if (src) {
setMotion(src);
} else {
reset();
}
}
CMotionControl::~CMotionControl() {
clear();
}
void CMotionControl::clear() {
if (_callback) {
delete _callback;
_callback = nullptr;
}
}
void CMotionControl::reset() {
_currVelocity = 0.0;
_incVelocity = 0.0;
_incAcceleration = 20.0;
_minVelocity = 0.0;
_maxVelocity = 50000.0;
_rotationX = 1.0;
_rotationY = 1.0;
_rotationZ = 0.0;
}
void CMotionControl::setCallback(CCallbackHandler *callback) {
clear();
_callback = callback;
}
void CMotionControl::setMotion(const CNavigationInfo *src) {
_currVelocity = src->_initialVelocity;
_minVelocity = src->_minVelocity;
_maxVelocity = src->_maxVelocity;
_incVelocity = src->_velocity;
_incAcceleration = src->_acceleration;
_rotationX = src->_rotationX;
_rotationY = src->_rotationY;
_rotationZ = src->_rotationZ;
}
void CMotionControl::getMotion(CNavigationInfo *dest) {
dest->_initialVelocity = _currVelocity;
dest->_minVelocity = _minVelocity;
dest->_maxVelocity = _maxVelocity;
dest->_velocity = _incVelocity;
dest->_acceleration = _incAcceleration;
dest->_rotationX = _rotationX;
dest->_rotationY = _rotationY;
dest->_rotationZ = _rotationZ;
}
void CMotionControl::accelerate() {
if (!isLocked() && _currVelocity < _maxVelocity) {
_incVelocity += _incAcceleration;
_currVelocity += ABS(_incVelocity);
}
}
void CMotionControl::deccelerate() {
if (!isLocked() && _currVelocity > -_maxVelocity) {
_incVelocity -= _incAcceleration;
_currVelocity -= ABS(_incVelocity);
}
}
void CMotionControl::fullSpeed() {
if (!isLocked())
_currVelocity = _maxVelocity;
}
void CMotionControl::stop() {
if (!isLocked()) {
_currVelocity = 0.0;
_incVelocity = 0.0;
}
}
// TODO: this is confusing to negate the val value
void CMotionControl::load(SimpleFile *file, int version) {
if (version == 0) {
_currVelocity = file->readFloat();
_incVelocity = file->readFloat();
_incAcceleration = file->readFloat();
_minVelocity = file->readFloat();
_maxVelocity = file->readFloat();
_rotationX = file->readFloat();
_rotationY = file->readFloat();
_rotationZ = file->readFloat();
}
}
void CMotionControl::save(SimpleFile *file, int indent) {
file->writeFloatLine(_currVelocity, indent);
file->writeFloatLine(_incVelocity, indent);
file->writeFloatLine(_incAcceleration, indent);
file->writeFloatLine(_minVelocity, indent);
file->writeFloatLine(_maxVelocity, indent);
file->writeFloatLine(_rotationX, indent);
file->writeFloatLine(_rotationY, indent);
file->writeFloatLine(_rotationZ, indent);
}
void CMotionControl::incLockCount() {
if (_lockCounter < 3)
++_lockCounter;
}
void CMotionControl::decLockCount() {
if (_lockCounter > 0)
--_lockCounter;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,167 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_MOTION_CONTROL_H
#define TITANIC_MOTION_CONTROL_H
#include "titanic/star_control/fmatrix.h"
namespace Titanic {
class CCamera;
class CErrorCode;
class FMatrix;
class FVector;
class SimpleFile;
struct CNavigationInfo {
double _initialVelocity;
double _minVelocity;
double _maxVelocity;
double _velocity;
double _acceleration;
double _rotationX;
double _rotationY;
double _rotationZ;
};
/**
* Handles doing a callback to the starfield to lock in a star after movement finishes
*/
class CCallbackHandler {
private:
CCamera *_owner;
FVector _vector;
public:
CCallbackHandler(CCamera *owner, const FVector &v) : _owner(owner), _vector(v) {
}
/**
* Locks in the star at the given position
*/
void apply();
};
class CMotionControl {
protected:
double _currVelocity;
double _incVelocity;
double _incAcceleration;
double _minVelocity;
double _maxVelocity;
double _rotationX;
double _rotationY;
double _rotationZ;
public:
int _lockCounter;
CCallbackHandler *_callback;
public:
CMotionControl(const CNavigationInfo *src);
virtual ~CMotionControl();
virtual void setMotion(const CNavigationInfo *src);
virtual void getMotion(CNavigationInfo *dest);
/**
* delete _starVector
*/
virtual void clear();
/**
* Set default values for CNavigationInfo
*/
virtual void reset();
/**
* Sets this CCallbackHandler
*/
virtual void setCallback(CCallbackHandler *callback);
/**
* Increases movement speed in forward direction
*/
virtual void accelerate();
/**
* Decreases movement speed in backward direction
*/
virtual void deccelerate();
/**
* Increase to full speed
*/
virtual void fullSpeed();
/**
* Completely stop
*/
virtual void stop();
/**
* Move the mover from an old position and orientation to a new
* position and orientation
*/
virtual void transitionBetweenPosOrients(const FVector &oldPos, const FVector &newPos,
const FMatrix &oldOrientation, const FMatrix &newOrientation) {}
/**
* Start a movement to a given specified destination
*/
virtual void moveTo(const FVector &srcV, const FVector &destV, const FMatrix &orientation) {}
/**
* First two vectors are used to form a new orientation that gets transitioned to from the old
* orientation m.
*/
virtual void transitionBetweenOrientations(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m) {}
/**
* Update the passed position and orientation matrix
*/
virtual void updatePosition(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) {}
/**
* Load the class
*/
virtual void load(SimpleFile *file, int version = 0);
/**
* Save the class
*/
virtual void save(SimpleFile *file, int indent);
/**
* Increment tthe lock counter
*/
void incLockCount();
/**
* Decrement the lock counter
*/
void decLockCount();
/**
* Returns true if the lock counter is non-zero
*/
bool isLocked() const { return _lockCounter > 0; }
};
} // End of namespace Titanic
#endif /* TITANIC_MOTION_CONTROL_H */

View File

@@ -0,0 +1,61 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/motion_control_marked.h"
#include "titanic/star_control/base_stars.h"
#include "titanic/star_control/error_code.h"
#include "titanic/star_control/fmatrix.h"
namespace Titanic {
CMotionControlMarked::CMotionControlMarked(const CNavigationInfo *src) :
CMotionControl(src) {
}
void CMotionControlMarked::transitionBetweenPosOrients(const FVector &oldPos, const FVector &newPos,
const FMatrix &oldOrientation, const FMatrix &newOrientation) {
if (isLocked())
decLockCount();
_autoMover.setFlight(oldPos, newPos, oldOrientation, newOrientation);
incLockCount();
}
void CMotionControlMarked::updatePosition(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) {
if (_autoMover.isActive()) {
decLockCount();
MoverState moveState = _autoMover.move(errorCode, pos, orientation);
if (moveState == MOVING)
incLockCount();
if (moveState == DONE_MOVING) {
stop();
if (_callback)
_callback->apply();
}
} else if (_currVelocity != 0.0) {
pos._x += orientation._row3._x * _currVelocity;
pos._y += orientation._row3._y * _currVelocity;
pos._z += orientation._row3._z * _currVelocity;
errorCode.set();
}
}
} // End of namespace Titanic

View File

@@ -0,0 +1,55 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_MOTION_CONTROL_MARKED_H
#define TITANIC_MOTION_CONTROL_MARKED_H
#include "titanic/star_control/motion_control.h"
#include "titanic/star_control/flight_manager_marked.h"
namespace Titanic {
class FMatrix;
class FVector;
class CMotionControlMarked : public CMotionControl {
private:
CMarkedAutoMover _autoMover;
public:
CMotionControlMarked(const CNavigationInfo *src);
~CMotionControlMarked() override {}
/**
* Move the mover from an old position and orientation to a new
* position and orientation
*/
void transitionBetweenPosOrients(const FVector &oldPos, const FVector &newPos,
const FMatrix &oldOrientation, const FMatrix &newOrientation) override;
/**
* Update the passed position and orientation matrix
*/
void updatePosition(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) override;
};
} // End of namespace Titanic
#endif /* TITANIC_MOTION_CONTROL_MARKED_H */

View File

@@ -0,0 +1,78 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/motion_control_unmarked.h"
#include "titanic/star_control/base_stars.h"
#include "titanic/star_control/fpose.h"
#include "titanic/star_control/error_code.h"
#include "titanic/star_control/fmatrix.h"
#include "titanic/debugger.h"
#include "titanic/titanic.h"
namespace Titanic {
CMotionControlUnmarked::CMotionControlUnmarked(const CNavigationInfo *src) :
CMotionControl(src) {
}
void CMotionControlUnmarked::moveTo(const FVector &srcV, const FVector &destV, const FMatrix &orientation) {
if (isLocked())
decLockCount();
debugC(DEBUG_BASIC, kDebugStarfield, "Starfield move %s to %s", srcV.toString().c_str(),
destV.toString().c_str());
_autoMover.setPathOrient(srcV, destV, orientation);
}
// TODO: v3 is unused
void CMotionControlUnmarked::transitionBetweenOrientations(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m) {
if (isLocked())
decLockCount();
FVector vector1 = v1;
FVector vector2 = v2;
FPose matrix1 = vector2.getFrameTransform(vector1);
FPose matrix2 = matrix1.compose(m);
_autoMover.setOrientations(m, matrix2);
incLockCount();
}
void CMotionControlUnmarked::updatePosition(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) {
if (_autoMover.isActive()) {
decLockCount();
MoverState moverState = _autoMover.move(errorCode, pos, orientation);
if (moverState == MOVING)
incLockCount();
if (moverState == DONE_MOVING) {
stop();
if (_callback)
_callback->apply();
}
} else if (_currVelocity != 0.0) {
pos._x += orientation._row3._x * _currVelocity;
pos._y += orientation._row3._y * _currVelocity;
pos._z += orientation._row3._z * _currVelocity;
errorCode.set();
}
}
} // End of namespace Titanic

View File

@@ -0,0 +1,55 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_MOTION_CONTROL_UNMARKED_H
#define TITANIC_MOTION_CONTROL_UNMARKED_H
#include "titanic/star_control/motion_control.h"
#include "titanic/star_control/flight_manager_unmarked.h"
namespace Titanic {
class FMatrix;
class FVector;
class CMotionControlUnmarked : public CMotionControl {
private:
CFlightManagerUnmarked _autoMover;
public:
CMotionControlUnmarked(const CNavigationInfo *src);
~CMotionControlUnmarked() override {}
/**
* Start a movement to a given specified destination
*/
void moveTo(const FVector &srcV, const FVector &destV, const FMatrix &orientation) override;
void transitionBetweenOrientations(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m) override;
/**
* Update the passed position and orientation matrix
*/
void updatePosition(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) override;
};
} // End of namespace Titanic
#endif /* TITANIC_MOTION_CONTROL_UNMARKED_H */

View File

@@ -0,0 +1,50 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/orientation_changer.h"
#include "titanic/star_control/fpose.h"
#include "titanic/star_control/fmatrix.h"
namespace Titanic {
void COrientationChanger::load(const FMatrix &minOrient, const FMatrix &maxOrient) {
_minOrient = minOrient;
_maxOrient = maxOrient;
_sub1.fn4(_minOrient);
_sub2.fn4(_maxOrient);
}
FMatrix COrientationChanger::getOrientation(double percent) {
if (percent <= 0.0) {
return _minOrient;
} else if (percent > 1.0) {
return _maxOrient;
} else {
CMatrixTransform tfm = _sub1.fn5(percent, _sub2);
FPose m1;
m1.loadTransform(tfm);
return m1;
}
}
} // End of namespace Titanic

View File

@@ -0,0 +1,53 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_ORIENTATION_CHANGER_H
#define TITANIC_ORIENTATION_CHANGER_H
#include "titanic/star_control/fmatrix.h"
#include "titanic/star_control/matrix_transform.h"
namespace Titanic {
class COrientationChanger {
public:
FMatrix _minOrient;
FMatrix _maxOrient;
CMatrixTransform _sub1;
CMatrixTransform _sub2;
public:
/**
* Loads the constraints for the minimum and maximum orientation
*/
void load(const FMatrix &minOrient, const FMatrix &maxOrient);
/**
* Returns the orientation for a given percentage between the two
* extremes
* @param percent Percentage transition 0.0 to 1.0
* @returns New orientation for the given percentage between the two
*/
FMatrix getOrientation(double percent);
};
} // End of namespace Titanic
#endif /* TITANIC_ORIENTATION_CHANGER_H */

View File

@@ -0,0 +1,560 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/star_closeup.h"
#include "titanic/star_control/error_code.h"
#include "titanic/star_control/camera.h"
#include "titanic/star_control/surface_area.h"
#include "titanic/titanic.h"
#include "math/utils.h"
namespace Titanic {
#define MKTAG_BE(a3,a2,a1,a0) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24)))
void CStarCloseup::SubEntry::clear() {
_data1.clear();
_data2.clear();
}
/*------------------------------------------------------------------------*/
bool CStarCloseup::SineTable::setup() {
if (_data.empty()) {
_data.resize(1024);
for (int idx = 0; idx < 1024; ++idx)
_data[idx] = sin((float)idx * 2 * M_PI / 512.0);
}
return true;
}
/*------------------------------------------------------------------------*/
CStarCloseup::CStarCloseup() : _flag(true), _multiplier(0) {
}
bool CStarCloseup::setup() {
bool success = setupEntry(5, 5, 4, 1024.0)
&& setupEntry(7, 7, 3, 1024.0)
&& setupEntry(8, 8, 2, 1024.0)
&& setupEntry(16, 16, 1, 1024.0)
&& setupEntry(24, 24, 0, 1024.0);
if (success)
success = setup2(24, 24);
return success;
}
bool CStarCloseup::setup2(int val1, int val2) {
const int VALUES1[] = { 0x800, 0xC00, 0x1000, 0x1400, 0x1800 };
const int VALUES2[] = {
0xF95BCD, 0xA505A0, 0xFFAD43, 0x98F4EB, 0xF3EFA5, 0,
0xFFFFFF, 0x81EEF5, 0x5FFD3, 0x4EE4FA, 0x11C3FF, 0x28F3F4,
0x36FCF2, 0x29F1FD, 0x29BCFD, 0x98E3F4, 0xBBF3D9, 0x8198F5,
0x5BE4F9, 0x0D6E2, 0x74EEF6, 0x68DEF8
};
Entry *e = &_entries[0];
for (int idx = 0; idx < 256; ++idx) {
if (idx == 0) {
e->_field0 = 0x4C8;
e->_pixel1 = 0x40;
e->_pixel2 = 0x40;
e->_pixel3 = 0x40;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = Math::deg2rad<double>(7.0);
e->_field14 = 0.0084687499;
++e;
e->_field0 = 0x574;
e->_pixel1 = 0x7f;
e->_pixel2 = 0;
e->_pixel3 = 0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = Math::deg2rad<double>(3.0);
e->_field14 = 0.021011719;
++e;
e->_field0 = 0x603;
e->_pixel1 = 0;
e->_pixel2 = 0;
e->_pixel3 = 0xff;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = 0;
e->_field14 = 0.022144532;
++e;
e->_field0 = 0x712;
e->_pixel1 = 0xff;
e->_pixel2 = 0;
e->_pixel3 = 0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = Math::deg2rad<double>(2.0);
e->_field14 = 0.01178125;
++e;
e->_field0 = 0xe7f;
e->_pixel1 = 0xe6;
e->_pixel2 = 0xbe;
e->_pixel3 = 0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = Math::deg2rad<double>(1.0);
e->_field14 = 0.24791406;
++e;
e->_field0 = 0x173f;
e->_pixel1 = 0xf0;
e->_pixel2 = 0xf0;
e->_pixel3 = 0xe6;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = Math::deg2rad<double>(3.0);
e->_field14 = 0.20832032;
++e;
e->_field0 = 0x2ab8;
e->_pixel1 = 0x28;
e->_pixel2 = 0x32;
e->_pixel3 = 0x28;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = Math::deg2rad<double>(1.0);
e->_field14 = 0.088164061;
++e;
e->_field0 = 0x40ac;
e->_pixel1 = 0x0;
e->_pixel2 = 0xbe;
e->_pixel3 = 0xf0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = Math::deg2rad<double>(2.0);
e->_field14 = 0.084375001;
++e;
e->_field0 = 0x539c;
e->_pixel1 = 0x20;
e->_pixel2 = 0x20;
e->_pixel3 = 0x20;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = Math::deg2rad<double>(17.0);
e->_field14 = 1 / 256.0;
} else {
for (int ctr = 0; ctr < 5; ++ctr) {
e->_field0 = static_cast<int>(g_vm->getRandomFloat() * 1350.0
- 675.0) + VALUES1[ctr];
int val = VALUES2[g_vm->getRandomNumber(15)];
e->_pixel1 = val & 0xff;
e->_pixel2 = (val >> 8) & 0xff;
e->_pixel3 = (val >> 16) & 0xff;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = Math::deg2rad<double>((double)g_vm->getRandomNumber(15));
e->_field14 = ((float)g_vm->getRandomNumber(0xfffffffe)
* 50.0 / 65536.0) / 256.0;
}
}
}
if (_sineTable.setup()) {
_grid.resize((val2 - 2) * val1 + 2);
return true;
}
return false;
}
void CStarCloseup::draw(const FPose &pose, const FVector &vector, const FVector &vector2,
CSurfaceArea *surfaceArea, CCamera *camera) {
const int VALUES[] = { 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4 };
float val1 = camera->getFrontClip();
StarColor starColor = camera->getStarColor();
if (!_flag)
return;
int f1, f3, size2, size1;
float f2, f4, f5, f6, f7, f8, f9;
float f10, incr, f12, f13, f14, f15, f16, f17, f18, f19;
float f20, f21, f22;
FVector tempV;
if (vector2._z < 6.0e9) {
int count, start;
if (vector._x != 0.0 && (vector._y != 0.0 || vector._z != 0.0)) {
// WORKAROUND: Ignoring non-sensical randSeed((int)vector._x);
count = VALUES[g_vm->getRandomNumber(15)];
start = 5 * g_vm->getRandomNumber(255);
} else {
count = 9;
start = 0;
}
Entry *entryP = &_entries[start];
for (; count > 0; --count, ++entryP) {
f1 = _multiplier * entryP->_field8;
f2 = entryP->_field14;
f3 = (f1 + entryP->_fieldC) & 0x1FF;
f4 = _sineTable[f1 & 0x1FF] * entryP->_field10;
f5 = _sineTable[f3];
f6 = cos(f4);
f7 = sin(f4);
f8 = _sineTable[f3 + 128];
f9 = f7;
f10 = f6 * f8;
incr = f6;
f12 = f6 * f5;
f13 = f2 * f10;
f14 = f8 * f2;
f15 = f9 * f2;
f16 = f2 * f12;
f17 = -(f7 * f8 * f2);
f18 = incr * f2;
f19 = -(f9 * f5 * f2);
f20 = -(f5 * f2);
f21 = f14;
_sub1._row1._x = f13;
_sub1._row1._y = f15;
_sub1._row1._z = f16;
_sub1._row2._x = f17;
_sub1._row2._y = f18;
_sub1._row2._z = f19;
_sub1._row3._x = f20;
_sub1._row3._z = f14;
f22 = (float)entryP->_field0;
_sub1._vector._x = f22 * f10 + vector._x;
_sub1._vector._y = f9 * f22 + vector._y;
_sub1._vector._z = f22 * f12 + vector._z;
_sub2._row1._x = pose._row1._x * f13 + f16 * pose._row3._x + f15 * pose._row2._x;
_sub2._row1._y = f15 * pose._row2._y + f16 * pose._row3._y + f13 * pose._row1._y;
_sub2._row1._z = f16 * pose._row3._z + f13 * pose._row1._z + f15 * pose._row2._z;
_sub2._row2._x = pose._row1._x * f17 + f19 * pose._row3._x + f18 * pose._row2._x;
_sub2._row2._y = f18 * pose._row2._y + f17 * pose._row1._y + f19 * pose._row3._y;
_sub2._row2._z = f18 * pose._row2._z + f19 * pose._row3._z + f17 * pose._row1._z;
_sub2._row3._x = pose._row1._x * f20 + f21 * pose._row3._x;
_sub2._row3._y = f20 * pose._row1._y + f21 * pose._row3._y;
_sub2._row3._z = f20 * pose._row1._z + f21 * pose._row3._z;
_sub2._vector._x = pose._row1._x * _sub1._vector._x
+ pose._row3._x * _sub1._vector._z
+ pose._row2._x * _sub1._vector._y + pose._vector._x;
_sub2._vector._y = pose._row2._y * _sub1._vector._y
+ pose._row3._y * _sub1._vector._z
+ pose._row1._y * _sub1._vector._x + pose._vector._y;
_sub2._vector._z = pose._row3._z * _sub1._vector._z
+ pose._row1._z * _sub1._vector._x
+ pose._row2._z * _sub1._vector._y + pose._vector._z;
size2 = (int)_array[1]._data2.size();
size1 = (int)_array[1]._data1.size();
if (size2 > 0) {
for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
FVector &currVector = _array[1]._data2[ctr2];
GridEntry &gridEntry = _grid[ctr2];
gridEntry._x = currVector._z * _sub2._row3._x
+ currVector._y * _sub2._row2._x
+ currVector._x * _sub2._row1._x + _sub2._vector._x;
gridEntry._y = currVector._z * _sub2._row3._y
+ currVector._y * _sub2._row2._y
+ currVector._x * _sub2._row1._y + _sub2._vector._y;
gridEntry._z = currVector._z * _sub2._row3._z
+ currVector._y * _sub2._row2._z
+ currVector._x * _sub2._row1._z + _sub2._vector._z;
}
}
switch (starColor) {
case WHITE:
surfaceArea->setMode(SA_SOLID);
surfaceArea->_pixel = MKTAG_BE(entryP->_pixel1, entryP->_pixel2,
entryP->_pixel3, 0);
surfaceArea->setColorFromPixel();
for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
GridEntry &gridEntry = _grid[ctr2];
tempV = camera->getRelativePos(2, gridEntry);
gridEntry._position._x = tempV._x;
gridEntry._position._y = tempV._y + vector2._y;
}
for (int ctr2 = 0; ctr2 < size1; ++ctr2) {
Data1 &d1 = _array[1]._data1[ctr2];
GridEntry &grid1 = _grid[d1._index1];
GridEntry &grid2 = _grid[d1._index2];
if (grid1._z > val1 && grid2._z > val1) {
surfaceArea->drawLine(FRect(grid1._position._x, grid1._position._y,
grid2._position._x, grid2._position._y));
}
}
break;
case PINK:
surfaceArea->setMode(SA_SOLID);
surfaceArea->_pixel = entryP->_pixel1;
surfaceArea->setColorFromPixel();
for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
GridEntry &gridEntry = _grid[ctr2];
tempV = camera->getRelativePos(0, gridEntry);
gridEntry._position._x = tempV._x + vector2._x;
gridEntry._position._y = tempV._y + vector2._y;
}
for (int ctr2 = 0; ctr2 < size1; ++ctr2) {
Data1 &d1 = _array[1]._data1[ctr2];
GridEntry &grid1 = _grid[d1._index1];
GridEntry &grid2 = _grid[d1._index2];
if (grid1._z > val1 && grid2._z > val1) {
surfaceArea->drawLine(FRect(grid1._position._x, grid1._position._y,
grid2._position._x, grid2._position._y));
}
}
surfaceArea->_pixel = entryP->_pixel3;
surfaceArea->setColorFromPixel();
surfaceArea->setMode(SA_MODE2);
for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
GridEntry &gridEntry = _grid[ctr2];
tempV = camera->getRelativePos(1, gridEntry);
gridEntry._position._x = tempV._x + vector2._x;
gridEntry._position._y = tempV._y + vector2._y;
}
for (int ctr2 = 0; ctr2 < size1; ++ctr2) {
Data1 &d1 = _array[1]._data1[ctr2];
GridEntry &grid1 = _grid[d1._index1];
GridEntry &grid2 = _grid[d1._index2];
if (grid1._z > val1 && grid2._z > val1) {
surfaceArea->drawLine(FRect(grid1._position._x, grid1._position._y,
grid2._position._x, grid2._position._y));
}
}
break;
default:
assert(0);
}
}
}
uint pixel1 = 0x81EEF5, pixel2 = 0xF5, pixel3 = 0x810000;
int arrIndex = 0;
if (vector2._z >= 200000000.0) {
if (vector2._z >= 900000000.0) {
if (vector2._z >= 6000000000.0) {
arrIndex = 3;
if (vector2._z >= 1.0e10)
arrIndex = 4;
} else {
arrIndex = 2;
}
} else {
arrIndex = 1;
}
} else {
arrIndex = 0;
}
SubEntry &entry = _array[arrIndex];
for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
GridEntry &gridEntry = _grid[ctr];
const FVector &d2v = entry._data2[ctr];
FVector newV = d2v + vector;
gridEntry._x = pose._row1._x * newV._x + pose._row3._x * newV._z
+ pose._row2._x * newV._y + pose._vector._x;
gridEntry._y = newV._y * pose._row2._y + newV._z * pose._row3._y
+ newV._x * pose._row1._y + pose._vector._y;
gridEntry._z = newV._z * pose._row3._z + newV._y * pose._row2._z
+ newV._x * pose._row1._z + pose._vector._z;
}
switch(starColor) {
case WHITE:
surfaceArea->setMode(SA_SOLID);
surfaceArea->_pixel = pixel1;
surfaceArea->setColorFromPixel();
for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
GridEntry &gridEntry = _grid[ctr];
tempV = camera->getRelativePos(2, gridEntry);
gridEntry._position._x = tempV._x + vector2._x;
gridEntry._position._y = tempV._y + vector2._y;
}
for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) {
Data1 &d1 = entry._data1[ctr];
GridEntry &grid1 = _grid[d1._index1];
GridEntry &grid2 = _grid[d1._index2];
if (grid2._z > val1 && grid1._z > val1) {
surfaceArea->drawLine(FRect(grid1._position._x, grid1._position._y,
grid2._position._x, grid2._position._y));
}
}
break;
case PINK:
surfaceArea->setMode(SA_SOLID);
surfaceArea->_pixel = pixel2;
surfaceArea->setColorFromPixel();
for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
GridEntry &gridEntry = _grid[ctr];
tempV = camera->getRelativePos(2, gridEntry);
gridEntry._position._x = tempV._x + vector2._x;
gridEntry._position._y = tempV._y + vector2._y;
}
for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) {
Data1 &d1 = entry._data1[ctr];
GridEntry &grid1 = _grid[d1._index1];
GridEntry &grid2 = _grid[d1._index2];
if (grid2._z > val1 && grid1._z > val1) {
surfaceArea->drawLine(FRect(grid1._position._x, grid1._position._y,
grid2._position._x, grid2._position._y));
}
}
surfaceArea->_pixel = pixel3;
surfaceArea->setColorFromPixel();
surfaceArea->setMode(SA_MODE2);
for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
GridEntry &gridEntry = _grid[ctr];
tempV = camera->getRelativePos(2, gridEntry);
gridEntry._position._x = tempV._x + vector2._x;
gridEntry._position._y = tempV._y + vector2._y;
}
for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) {
Data1 &d1 = entry._data1[ctr];
GridEntry &grid1 = _grid[d1._index1];
GridEntry &grid2 = _grid[d1._index2];
if (grid2._z > val1 && grid1._z > val1) {
surfaceArea->drawLine(FRect(grid1._position._x, grid1._position._y,
grid2._position._x, grid2._position._y));
}
}
break;
default:
assert(0);
}
}
void CStarCloseup::proc3(CErrorCode *errorCode) {
++_multiplier;
errorCode->set();
}
void CStarCloseup::fn1() {
_flag = !_flag;
}
bool CStarCloseup::setupEntry(int width, int height, int index, float val) {
if (width < 2 || height < 3)
return false;
SubEntry &entry = _array[index];
entry.clear();
int d1Count, d2Count, size3, height1;
int ctr, ctr2, idx, incr;
float vx, vy, yVal, degrees, cosVal, sinVal, angle;
d1Count = width * (2 * height - 3);
d2Count = (height - 2) * width + 2;
entry._data1.resize(d1Count);
entry._data2.resize(d2Count);
height1 = height - 1;
vy = 180.0 / (float)height1;
vx = 360.0 / (float)width;
// Build up the vector list
entry._data2[0]._y = val;
for (ctr = height - 2, idx = 1, yVal = vy; ctr > 0; --ctr, yVal += vy) {
degrees = 0.0;
cosVal = cos(Math::deg2rad<float>(yVal));
sinVal = sin(Math::deg2rad<float>(yVal));
if (width > 0) {
for (int xCtr = 0; xCtr < width; ++xCtr, ++idx, degrees += vx) {
angle = Math::deg2rad<float>(degrees);
FVector &tempV = entry._data2[idx];
tempV._x = sin(angle) * sinVal * val;
tempV._y = cosVal * val;
tempV._z = cos(angle) * sinVal * val;
}
}
}
entry._data2[idx] = FVector(0.0, -1.0 * val, 0.0);
size3 = width * (height - 3) + 1;
Data1 *data1P = &entry._data1[0];
for (ctr = 0; ctr < width; ++ctr, ++size3) {
data1P->_index1 = 0;
data1P->_index2 = size3 - width * (height - 3);
++data1P;
data1P->_index1 = d2Count - 1;
data1P->_index2 = size3;
++data1P;
}
incr = 1;
for (ctr = 1; ctr < height1; ++ctr, incr += width) {
for (ctr2 = 0; ctr2 < width; ++ctr2, ++data1P) {
data1P->_index1 = ctr2 + incr;
if (ctr2 == width - 1)
data1P->_index2 = incr;
else
data1P->_index2 = ctr2 + incr + 1;
if (ctr < height - 2) {
++data1P;
data1P->_index1 = ctr2 + incr;
data1P->_index2 = width + ctr2 + incr;
}
}
}
return true;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,139 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_STAR_CLOSEUP_H
#define TITANIC_STAR_CLOSEUP_H
#include "titanic/star_control/fvector.h"
#include "titanic/star_control/fpose.h"
#include "titanic/star_control/surface_area.h"
#include "common/array.h"
namespace Titanic {
class CErrorCode;
class CCamera;
class CSurfaceArea;
/**
* Handles drawing a 3D rendered closeup of a star
*/
class CStarCloseup {
struct Data1 {
int _index1;
int _index2;
Data1() : _index1(0), _index2(0) {}
};
struct SubEntry {
Common::Array<Data1> _data1;
Common::Array<FVector> _data2;
~SubEntry() { clear(); }
/**
* Clears the entry
*/
void clear();
};
struct Entry {
int _field0;
byte _pixel1;
byte _pixel2;
byte _pixel3;
int _field8;
int _fieldC;
double _field10;
double _field14;
Entry() : _field0(0), _pixel1(0), _pixel2(0), _pixel3(0), _field8(0),
_fieldC(0), _field10(0), _field14(0) {}
};
struct GridEntry : public FVector {
FPoint _position;
GridEntry() : FVector() {}
};
/**
* Maintains a pre-calculated table of sine values
* TODO: May be able to reuse common/sinetables.h
*/
struct SineTable {
private:
Common::Array<float> _data;
public:
SineTable() {}
/**
* Sets up the table
*/
bool setup();
/**
* Get a value
*/
double operator[](int idx) { return _data[idx]; }
};
private:
bool _flag;
FPose _sub1, _sub2;
SubEntry _array[5];
Entry _entries[1284];
int _multiplier;
SineTable _sineTable;
Common::Array<GridEntry> _grid;
private:
/**
* Sets up the data for an array entry
* @return True if success
*/
bool setupEntry(int width, int height, int index, float val);
/**
* Secondary setup method
* @return True if success
*/
bool setup2(int val1, int val2);
public:
CStarCloseup();
virtual ~CStarCloseup() {}
virtual bool setup();
/**
* Draws the star globe
*/
virtual void draw(const FPose &pose, const FVector &vector, const FVector &vector2,
CSurfaceArea *surfaceArea, CCamera *camera);
virtual void proc3(CErrorCode *errorCode);
bool get4() const { return _flag; }
void set4(bool val) { _flag = val; }
void fn1();
};
} // End of namespace Titanic
#endif /* TITANIC_STAR_CLOSEUP_H */

View File

@@ -0,0 +1,296 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/star_control.h"
#include "titanic/core/dont_save_file_item.h"
#include "titanic/core/project_item.h"
#include "titanic/game_manager.h"
#include "titanic/pet_control/pet_control.h"
#include "titanic/star_control/motion_control.h"
#include "titanic/star_control/error_code.h"
#include "titanic/support/screen_manager.h"
namespace Titanic {
BEGIN_MESSAGE_MAP(CStarControl, CGameObject)
ON_MESSAGE(MouseMoveMsg)
ON_MESSAGE(MouseButtonDownMsg)
ON_MESSAGE(ActionMsg)
ON_MESSAGE(FrameMsg)
ON_MESSAGE(MovementMsg)
END_MESSAGE_MAP()
CStarControl::CStarControl() : _enabled(false), _petControl(nullptr),
_starRect(20, 10, 620, 350) {
CCamera::init();
}
CStarControl::~CStarControl() {
CCamera::deinit();
}
void CStarControl::save(SimpleFile *file, int indent) {
file->writeNumberLine(0, indent);
_starField.save(file, indent);
_view.save(file, indent);
CGameObject::save(file, indent);
}
void CStarControl::load(SimpleFile *file) {
int val = file->readNumber();
if (!val) {
_starField.load(file);
if (!_starField.initDocument())
error("Couldn't initialise the StarField document");
_view.load(file, 0);
CScreenManager *screenManager = CScreenManager::setCurrent();
if (!screenManager)
error("There's no screen manager during loading");
_view.setup(screenManager, &_starField, this);
_view.takeCurrentHomePhoto();
_enabled = true;
}
CGameObject::load(file);
}
void CStarControl::draw(CScreenManager *screenManager) {
if (_visible)
_view.draw(screenManager);
}
bool CStarControl::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
if (_visible && _starRect.contains(msg->_mousePos)) {
_view.MouseButtonDownMsg(0, Point(msg->_mousePos.x - 20,
msg->_mousePos.y - 10));
return true;
} else {
return false;
}
}
bool CStarControl::MouseMoveMsg(CMouseMoveMsg *msg) {
if (_visible && _starRect.contains(msg->_mousePos)) {
_view.MouseMoveMsg(0, Point(msg->_mousePos.x - 20,
msg->_mousePos.y - 10));
makeDirty();
return true;
} else {
return false;
}
}
bool CStarControl::ActionMsg(CActionMsg *msg) {
if (_visible) {
CErrorCode errorCode;
_view.ActionMsg(msg, &errorCode);
return errorCode.get();
}
return false;
}
bool CStarControl::FrameMsg(CFrameMsg *msg) {
if (_visible) {
Point pt = getMousePos();
if (_starRect.contains(pt))
_view.MouseMoveMsg(0, pt);
newFrame();
makeDirty();
return true;
} else {
return false;
}
}
void CStarControl::newFrame() {
if (!_petControl)
_petControl = getPetControl();
if (_petControl) {
int matchIndex = _starField.getMatchedIndex();
bool isClose = false;
if (_starField.getMode() == MODE_STARFIELD) {
isClose = _starField.isCloseToMarker();
if ((matchIndex + 2) != _starField.getMarkerCount())
isClose = false;
}
_petControl->starsSetButtons(matchIndex, isClose);
}
}
bool CStarControl::isStarFieldMode() {
if (!_petControl)
_petControl = getPetControl();
if (_petControl) {
if (_starField.getMode() == MODE_STARFIELD)
return true;
}
return false;
}
void CStarControl::doAction(StarControlAction action) {
if (!_enabled)
return;
switch (action) {
case STAR_SHOW: {
CGameManager *gameManager = getGameManager();
CViewItem *view = gameManager ? gameManager->getView() : nullptr;
if (view) {
detach();
addUnder(view);
_view.resetView();
_view.triggerFade(true);
_visible = true;
}
break;
}
case STAR_HIDE: {
CProjectItem *root = getRoot();
CDontSaveFileItem *fileItem = root ? root->getDontSaveFileItem() : nullptr;
if (fileItem) {
detach();
addUnder(fileItem);
_visible = false;
}
break;
}
case STAR_VIEW_EARTH:
_view.viewEarth();
break;
case STAR_VIEW_FROM_EARTH:
_view.viewFromEarth();
break;
case STAR_VIEW_BOUNDARIES:
_view.viewBoundaries();
break;
case STAR_VIEW_CONSTELLATIONS:
_view.viewConstellations();
break;
case STAR_VIEW_RANDOM_STAR:
_view.viewRandomStar();
break;
case STAR_FULL_SPEED:
_view.fullSpeed();
break;
case STAR_TOGGLE_STEREO_PAIR:
_view.toggleSteroPair();
break;
case STAR_TOGGLE_HOME_PHOTO:
_view.toggleHomePhoto();
break;
case STAR_TOGGLE_SOLAR_RENDERING:
_view.toggleSolarRendering();
break;
case STAR_TOGGLE_POS_FRAME:
_view.TogglePosFrame();
break;
case STAR_STEREO_PAIR_ON:
_view.stereoPairOn();
break;
case STAR_STEREO_PAIR_OFF:
_view.stereoPairOff();
break;
case STAR_SET_REFERENCE: {
_view.takeHomePhoto();
CPetControl *pet = getPetControl();
if (pet)
pet->starsSetReference();
break;
}
case STAR_FADE_IN:
_view.triggerFade(true);
break;
case STAR_FADE_OUT:
_view.triggerFade(false);
break;
case LOCK_STAR:
_view.lockStar();
break;
case UNLOCK_STAR:
_view.unlockStar();
break;
case STAR_CLEAR_MODIFIED:
_view.starDestinationSet();
break;
default:
break;
}
}
bool CStarControl::isSolved() const {
return _starField.isSolved();
}
bool CStarControl::isSkipped() const {
return _starField.isSkipped();
}
void CStarControl::forceSolved() {
_starField.skipPuzzle();
}
bool CStarControl::canSetStarDestination() const {
return _view.canSetStarDestination();
}
void CStarControl::starDestinationSet() {
_view.starDestinationSet();
}
bool CStarControl::MovementMsg(CMovementMsg *msg) {
// The star control view has an unused turn right link hidden
// under the star view. For cleanliness, explicitly consume any
// movements in the star view so the link is never used
return true;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,114 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_STAR_CONTROL_H
#define TITANIC_STAR_CONTROL_H
#include "titanic/core/game_object.h"
#include "titanic/star_control/star_field.h"
#include "titanic/star_control/star_view.h"
namespace Titanic {
class CPetControl;
class CStarControl : public CGameObject {
DECLARE_MESSAGE_MAP;
bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
bool MouseMoveMsg(CMouseMoveMsg *msg);
bool ActionMsg(CActionMsg *msg);
bool FrameMsg(CFrameMsg *msg);
bool MovementMsg(CMovementMsg *msg);
private:
bool _enabled;
CStarField _starField;
CStarView _view;
Rect _starRect;
CPetControl *_petControl;
private:
/**
* Called for ever new game frame
*/
void newFrame();
public:
CLASSDEF;
CStarControl();
~CStarControl() override;
/**
* Save the data for the class to file
*/
void save(SimpleFile *file, int indent) override;
/**
* Load the data for the class from file
*/
void load(SimpleFile *file) override;
/**
* Allows the item to draw itself
*/
void draw(CScreenManager *screenManager) override;
/**
* _starField is currently showing the starfield
*/
bool isStarFieldMode();
/**
* Does an action in the star control
*/
void doAction(StarControlAction action);
/**
* Returns true if the starfield puzzle has been solved
*/
bool isSolved() const;
/**
* Return true if the starfield puzzle was skipped
*/
bool isSkipped() const;
/**
* Forces the starfield to be solved
*/
void forceSolved();
/**
* Returns true if a star destination can be set
*/
bool canSetStarDestination() const;
/**
* Called when a star destination is set
*/
void starDestinationSet();
/**
* Updates the camerea for the star view
*/
void updateCamera() { _view.updateCamera(); }
};
} // End of namespace Titanic
#endif /* TITANIC_STAR_CONTROL_H */

View File

@@ -0,0 +1,266 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/star_crosshairs.h"
#include "titanic/star_control/star_markers.h"
#include "titanic/star_control/camera.h"
#include "titanic/star_control/star_field.h"
#include "titanic/star_control/star_ref.h"
#include "titanic/support/simple_file.h"
namespace Titanic {
CStarCrosshairs::CStarCrosshairs() : _matchIndex(-1), _entryIndex(-1) {
}
void CStarCrosshairs::selectStar(int index, CVideoSurface *surface,
CStarField *starField, CStarMarkers *markers) {
if (_entryIndex >= 0) {
// There are existing selected stars already
if (_entryIndex == _matchIndex) {
// All the stars selected so far have been matched. Only allow
// a selection addition if not all three stars have been found
if (!isSolved()) {
// Don't allow the most recent match or the one before
// it to be re-selected (while they are locked/matched)
if (_positions[index] != _entries[_entryIndex]) {
if (_entryIndex == 1) {
// 2 stars are matched
if (_positions[index] == _entries[_entryIndex - 1])
return;
}
surface->lock();
// Draw crosshairs around the selected star
CSurfaceArea surfaceArea(surface);
drawStar(index, &surfaceArea);
surface->unlock();
// Copy the star into the list of selected ones
++_entryIndex;
CStarPosition &newP = _entries[_entryIndex];
newP = _positions[index];
// Set up a marker in the main starfield for that same star
const CBaseStarEntry *starP = starField->getDataPtr(newP._index1);
markers->addStar(starP);
}
}
} else if (_entryIndex == _matchIndex + 1) {
// There is a most recently selected star that has not yet been matched.
// So we allow the user to reselect it to remove the selection, or shift
// the selection to some other star
if (_positions[index] == _entries[_entryIndex]) {
// Player has selected the most recent star
// Remove the crosshairs for the previously selected star
surface->lock();
CSurfaceArea surfaceArea(surface);
eraseCurrent(&surfaceArea);
surface->unlock();
// Decrement number of selections
--_entryIndex;
// Call the markers addStar method, which will remove the existing marker
const CBaseStarEntry *starP = starField->getDataPtr(_positions[index]._index1);
markers->addStar(starP);
} else {
// Player has selected some other star other than the most recent
// Remove/Add it if it is not one of the other star(s) already matched
// Check that it is not a previously star and don't remove it if it is
for (int i = 0; i < _entryIndex; ++i) {
if (_positions[index] == _entries[i])
return;
}
// Erase the prior selection and draw the new one
surface->lock();
CSurfaceArea surfaceArea(surface);
eraseCurrent(&surfaceArea);
drawStar(index, &surfaceArea);
surface->unlock();
// Remove the old selection from the starfield markers
const CBaseStarEntry *starP;
starP = starField->getDataPtr(_entries[_entryIndex]._index1);
markers->addStar(starP);
// Add the new selection to the markers list
starP = starField->getDataPtr(_positions[index]._index1);
markers->addStar(starP);
// Copy the newly selected star's details into our selections list
CStarPosition &newP = _entries[_entryIndex];
newP = _positions[index];
}
}
} else {
// Very first star being selected
// Draw crosshairs around the selected star
surface->lock();
CSurfaceArea surfaceArea(surface);
drawStar(index, &surfaceArea);
surface->unlock();
// Copy the star into the list of selected ones
++_entryIndex;
const CStarPosition &srcPos = _positions[index];
CStarPosition &destPos = _entries[_entryIndex];
destPos = srcPos;
// Set up a marker in the main starfield for that same star
const CBaseStarEntry *starP = starField->getDataPtr(destPos._index1);
markers->addStar(starP);
}
}
bool CStarCrosshairs::fn1(CStarField *starField, CSurfaceArea *surfaceArea, CCamera *camera) {
int count = starField->baseFn2(surfaceArea, camera);
if (count > 0) {
allocate(count);
CStarRefArray starRef(starField, &_positions);
starRef.process(surfaceArea, camera);
return true;
} else {
clear();
return false;
}
}
void CStarCrosshairs::decMatches(CVideoSurface *surface, CStarField *starField, CStarMarkers *markers) {
if (_matchIndex <= -1) {
if (_entryIndex > -1) {
drawEntry(_entryIndex, surface, starField, markers);
--_entryIndex;
}
} else {
--_matchIndex;
if (_entryIndex - _matchIndex > 1) {
drawEntry(_entryIndex, surface, starField, markers);
--_entryIndex;
}
}
}
void CStarCrosshairs::incMatches() {
if (_matchIndex < 3)
++_matchIndex;
}
FPoint CStarCrosshairs::getPosition() const {
return (_entryIndex >= 0 && _entryIndex <= 2) ?
FPoint(_entries[_entryIndex]) : FPoint();
}
void CStarCrosshairs::draw(CSurfaceArea *surfaceArea) {
if (!_positions.empty()) {
uint savedPixel = surfaceArea->_pixel;
surfaceArea->_pixel = 0xff;
surfaceArea->setColorFromPixel();
SurfaceAreaMode savedMode = surfaceArea->setMode(SA_SOLID);
for (int idx = 0; idx <= _entryIndex; ++idx) {
const CStarPosition &src = _entries[idx];
double xp = src.x, yp = src.y;
surfaceArea->drawLine(FRect(xp - 8.0, yp, xp - 4.0, yp));
surfaceArea->drawLine(FRect(xp + 4.0, yp, xp + 8.0, yp));
surfaceArea->drawLine(FRect(xp, yp - 8.0, xp, yp - 4.0));
surfaceArea->drawLine(FRect(xp, yp + 4.0, xp, yp + 8.0));
}
surfaceArea->_pixel = savedPixel;
surfaceArea->setColorFromPixel();
surfaceArea->setMode(savedMode);
}
}
void CStarCrosshairs::allocate(int count) {
if (!_positions.empty()) {
if ((int)_positions.size() == count)
return;
clear();
}
_positions.resize(count);
}
void CStarCrosshairs::clear() {
_positions.clear();
_matchIndex = _entryIndex = -1;
}
int CStarCrosshairs::indexOf(const Common::Point &pt) const {
Common::Rect r(pt.x - 2, pt.y - 2, pt.x + 2, pt.y + 2);
for (int idx = 0; idx < (int)_positions.size(); ++idx) {
if (r.contains(_positions[idx]))
return idx;
}
return -1;
}
void CStarCrosshairs::drawStar(int index, CSurfaceArea *surfaceArea) {
if (index >= 0 && index < (int)_positions.size()) {
const CStarPosition &pt = _positions[index];
drawAt(pt, surfaceArea);
}
}
void CStarCrosshairs::drawEntry(int index, CVideoSurface *surface, CStarField *starField, CStarMarkers *markers) {
surface->lock();
CSurfaceArea surfaceArea(surface);
drawAt(_entries[index], &surfaceArea);
surface->unlock();
const CBaseStarEntry *starP = starField->getDataPtr(_entries[index]._index1);
markers->addStar(starP);
}
void CStarCrosshairs::eraseCurrent(CSurfaceArea *surfaceArea) {
assert(_entryIndex >= 0);
const CStarPosition &pt = _entries[_entryIndex];
drawAt(pt, surfaceArea);
}
void CStarCrosshairs::drawAt(const FPoint &pt, CSurfaceArea *surfaceArea) {
uint savedPixel = surfaceArea->_pixel;
surfaceArea->_pixel = 255;
surfaceArea->setColorFromPixel();
SurfaceAreaMode savedMode = surfaceArea->setMode(SA_XOR);
surfaceArea->drawLine(FRect(pt._x - 8.0, pt._y, pt._x - 4.0, pt._y));
surfaceArea->drawLine(FRect(pt._x + 4.0, pt._y, pt._x + 8.0, pt._y));
surfaceArea->drawLine(FRect(pt._x, pt._y - 8.0, pt._x, pt._y - 4.0));
surfaceArea->drawLine(FRect(pt._x, pt._y + 4.0, pt._x, pt._y + 8.0));
surfaceArea->_pixel = savedPixel;
surfaceArea->setColorFromPixel();
surfaceArea->setMode(savedMode);
}
} // End of namespace Titanic

View File

@@ -0,0 +1,136 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_STAR_CROSSHAIRS_H
#define TITANIC_STAR_CROSSHAIRS_H
#include "titanic/star_control/base_stars.h"
#include "titanic/star_control/fpoint.h"
#include "titanic/star_control/surface_area.h"
#include "titanic/support/video_surface.h"
#include "common/array.h"
#include "common/rect.h"
namespace Titanic {
class CStarField;
class CStarMarkers;
class CCamera;
class SimpleFile;
class CStarCrosshairs {
private:
Common::Array<CStarPosition> _positions;
CStarPosition _entries[3];
private:
/**
* Allocates space in the _rects array
*/
void allocate(int count);
/**
* Clears any current data
*/
void clear();
public:
int _matchIndex;
int _entryIndex;
public:
CStarCrosshairs();
~CStarCrosshairs() { clear(); }
/**
* Load the data for the class from file
*/
void load(SimpleFile *file) {}
/**
* Save the data for the class to file
*/
void save(SimpleFile *file, int indent) {}
/**
* Returns true if there are no crosshairs present
*/
bool isEmpty() const { return _entryIndex == -1; }
void selectStar(int starNum, CVideoSurface *surface, CStarField *starField,
CStarMarkers *markers);
void draw(CSurfaceArea *surfaceArea);
bool fn1(CStarField *starField, CSurfaceArea *surfaceArea, CCamera *camera);
/**
* Increments the number of matches
*/
void incMatches();
/**
* Decrements the number of matches
*/
void decMatches(CVideoSurface *surface, CStarField *starField, CStarMarkers *markers);
/**
* Draw the crosshairs for a given star
*/
void drawStar(int index, CSurfaceArea *surfaceArea);
/**
* Draws the crosshairs for a specified entry, and adds the star
* to the starfield markers
*/
void drawEntry(int index, CVideoSurface *surface, CStarField *starField, CStarMarkers *markers);
/**
* Erase crosshairs for the most recently selected star
*/
void eraseCurrent(CSurfaceArea *surfaceArea);
/**
* Draw crosshairs at the given position
*/
void drawAt(const FPoint &pt, CSurfaceArea *surfaceArea);
/**
* Returns the position of the most recently selected star
*/
FPoint getPosition() const;
/**
* Returns the index of an entry in the rects list a given point falls within
*/
int indexOf(const Common::Point &pt) const;
/**
* Returns true if the starfield is solved
*/
bool isSolved() const { return _matchIndex >= 2; }
/**
* Return true if the starfield puzzle was skipped
*/
bool isSkipped() const { return _matchIndex == 3; }
};
} // End of namespace Titanic
#endif /* TITANIC_STAR_CROSSHAIRS_H */

View File

@@ -0,0 +1,267 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/star_field.h"
#include "titanic/star_control/surface_area.h"
#include "titanic/star_control/camera.h"
#include "titanic/titanic.h"
namespace Titanic {
CStarField::CStarField() : _renderBoundaries(false), _renderConstMap(false), _mode(MODE_STARFIELD),
_showBox(true), _closeToMarker(false), _isSolved(false) {
}
void CStarField::load(SimpleFile *file) {
_markers.load(file);
_crosshairs.load(file);
_renderBoundaries = file->readNumber();
_renderConstMap = file->readNumber();
_mode = (StarMode)file->readNumber();
_showBox = file->readNumber();
_isSolved = file->readNumber();
}
void CStarField::save(SimpleFile *file, int indent) {
_markers.save(file, indent);
_crosshairs.save(file, indent);
file->writeNumberLine(_renderBoundaries, indent);
file->writeNumberLine(_renderConstMap, indent);
file->writeNumberLine(_mode, indent);
file->writeNumberLine(_showBox, indent);
file->writeNumberLine(_isSolved, indent);
}
bool CStarField::initDocument() {
bool valid = setup() && _constBounds.initialize();
if (valid)
valid = _starCloseup.setup();
if (valid)
valid = _constMap.initialize();
return valid;
}
void CStarField::render(CVideoSurface *surface, CCamera *camera) {
CSurfaceArea surfaceArea(surface);
draw(&surfaceArea, camera, &_starCloseup);
if (_showBox)
drawBox(&surfaceArea);
_markers.draw(&surfaceArea, camera, nullptr);
_crosshairs.draw(&surfaceArea);
if (_renderConstMap)
_constMap.draw(&surfaceArea, camera);
if (_renderBoundaries)
_constBounds.draw(&surfaceArea, camera);
renderLockLine(&surfaceArea, camera);
}
bool CStarField::getBoundaryState() const {
return _renderBoundaries;
}
void CStarField::setBoundaryState(bool state) {
_renderBoundaries = state;
}
bool CStarField::getConstMapState() const {
return _renderConstMap;
}
void CStarField::setConstMapState(bool state) {
_renderConstMap = state;
}
int CStarField::get54() const {
return _starCloseup.get4();
}
void CStarField::set54(int val) {
_starCloseup.set4(val);
}
StarMode CStarField::getMode() const {
return _mode;
}
void CStarField::setMode(StarMode mode) {
_mode = mode;
}
void CStarField::toggleBox() {
_showBox = !_showBox;
}
bool CStarField::setBoxVisible(bool isVisible) {
bool oldVal = _showBox;
_showBox = isVisible;
return oldVal;
}
int CStarField::getMatchedIndex() const {
return _crosshairs._matchIndex;
}
bool CStarField::isCloseToMarker() const {
return _closeToMarker;
}
void CStarField::setSolved() {
_isSolved = _crosshairs._matchIndex >= 2;
}
bool CStarField::isSolved() const {
return _isSolved;
}
bool CStarField::isSkipped() const {
return _crosshairs.isSkipped();
}
void CStarField::skipPuzzle() {
_crosshairs._matchIndex = 3;
setSolved();
}
void CStarField::fn1(CErrorCode *errorCode) {
_starCloseup.proc3(errorCode);
}
void CStarField::drawBox(CSurfaceArea *surfaceArea) {
uint oldPixel = surfaceArea->_pixel;
surfaceArea->_pixel = 0x323232;
surfaceArea->setColorFromPixel();
surfaceArea->drawLine(FRect(202.60417, 63.75, 397.39584, 63.75));
surfaceArea->drawLine(FRect(202.60417, 276.25, 397.39584, 276.25));
surfaceArea->drawLine(FRect(193.75, 72.604164, 193.75, 267.39584));
surfaceArea->drawLine(FRect(406.25, 72.604164, 406.25, 267.39584));
surfaceArea->drawLine(FRect(202.60417, 63.75, 202.60417, 68.177086));
surfaceArea->drawLine(FRect(397.39584, 63.75, 397.39584, 68.177086));
surfaceArea->drawLine(FRect(202.60417, 276.25, 202.60417, 271.82291));
surfaceArea->drawLine(FRect(397.39584, 276.25, 397.39584, 271.82291));
surfaceArea->drawLine(FRect(193.75, 72.604164, 198.17708, 72.604164));
surfaceArea->drawLine(FRect(193.75, 267.39584, 198.17708, 267.39584));
surfaceArea->drawLine(FRect(406.25, 72.604164, 401.82291, 72.604164));
surfaceArea->drawLine(FRect(406.25, 267.39584, 401.82291, 267.39584));
surfaceArea->drawLine(FRect(300.0, 63.75, 300.0, 54.895832));
surfaceArea->drawLine(FRect(300.0, 276.25, 300.0, 285.10416));
surfaceArea->drawLine(FRect(193.75, 170.0, 184.89583, 170.0));
surfaceArea->drawLine(FRect(406.25, 170.0, 415.10416, 170.0));
surfaceArea->_pixel = oldPixel;
surfaceArea->setColorFromPixel();
}
void CStarField::renderLockLine(CSurfaceArea *surfaceArea, CCamera *camera) {
FVector screenCoord, worldCoord, photoPos;
_closeToMarker = false;
if (_mode == MODE_STARFIELD) {
if (lockDistance(surfaceArea, camera, screenCoord, worldCoord, photoPos) > -1.0) {
surfaceArea->_pixel = 0xA0A0;
surfaceArea->setColorFromPixel();
surfaceArea->drawLine(FRect(screenCoord._x, screenCoord._y, photoPos._x, photoPos._y));
}
}
}
double CStarField::lockDistance(CSurfaceArea *surfaceArea, CCamera *camera,
FVector &screenCoord, FVector &worldCoord, FVector &photoPos) {
if (_crosshairs.isEmpty())
// No crosshairs selection yet
return -1.0;
if (_crosshairs._entryIndex == _crosshairs._matchIndex)
// Trying to re-lock on a previously locked star
return -1.0;
const CBaseStarEntry *dataP = _markers.getDataPtr(_crosshairs._entryIndex);
worldCoord = dataP->_position;
FVector tv = camera->getRelativePosNoCentering(2, worldCoord);
if (camera->getFrontClip() >= tv._z)
return -1.0;
tv = camera->getRelativePos(2, tv);
screenCoord = FVector(tv._x + surfaceArea->_centroid._x,
tv._y + surfaceArea->_centroid._y, tv._z);
FPoint pt = _crosshairs.getPosition();
photoPos = FVector(pt._x, pt._y, 1.0);
double incr = (screenCoord._x - pt._x) * (screenCoord._x - pt._x);
if (incr > 3600.0)
return -1.0;
incr += (screenCoord._y - pt._y) * (screenCoord._y - pt._y);
if (incr > 3600.0)
return -1.0;
_closeToMarker = true;
return incr;
}
void CStarField::fn6(CVideoSurface *surface, CCamera *camera) {
CSurfaceArea surfaceArea(surface);
_crosshairs.fn1(this, &surfaceArea, camera);
}
void CStarField::incLockLevel() {
_crosshairs.incMatches();
setSolved();
}
void CStarField::decLockLevel(CVideoSurface *surface) {
_crosshairs.decMatches(surface, this, &_markers);
setSolved();
}
bool CStarField::mouseButtonDown(CVideoSurface *surface, CCamera *camera,
int flags, const Common::Point &pt) {
if (_mode == MODE_STARFIELD) {
CSurfaceArea surfaceArea(surface);
return selectStar(&surfaceArea, camera, pt);
} else {
int starNum = _crosshairs.indexOf(pt);
if (starNum >= 0) {
_crosshairs.selectStar(starNum, surface, this, &_markers);
return true;
}
return false;
}
}
const CBaseStarEntry *CStarField::getRandomStar() const {
if (_data.empty())
return nullptr;
return getDataPtr(g_vm->getRandomNumber(_data.size() - 1));
}
const CBaseStarEntry *CStarField::getStar(int index) const {
return (index < 0 || index >= (int)_data.size()) ? nullptr : getDataPtr(index);
}
} // End of namespace Titanic

View File

@@ -0,0 +1,190 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_STAR_FIELD_H
#define TITANIC_STAR_FIELD_H
#include "titanic/star_control/star_field_base.h"
#include "titanic/star_control/star_closeup.h"
#include "titanic/star_control/star_markers.h"
#include "titanic/star_control/star_crosshairs.h"
#include "titanic/star_control/const_boundaries.h"
#include "titanic/star_control/constellations.h"
namespace Titanic {
#define STAR_SCALE 1024.0F
#define UNIVERSE_SCALE 3000000.0f
class CStarField : public CStarFieldBase {
private:
CStarMarkers _markers;
CStarCrosshairs _crosshairs;
CConstBoundaries _constBounds;
CConstellations _constMap;
CStarCloseup _starCloseup;
bool _renderBoundaries;
bool _renderConstMap;
StarMode _mode;
bool _showBox;
bool _closeToMarker;
bool _isSolved;
private:
/**
* Draws the big square box in the middle of the screen
*/
void drawBox(CSurfaceArea *surfaceArea);
/**
* If the player's home photo has a selected star, and the starfield view
* is close enough to it, draw a lock line
*/
void renderLockLine(CSurfaceArea *surfaceArea, CCamera *camera);
public:
CStarField();
/**
* Load the data for the class from file
*/
void load(SimpleFile *file) override;
/**
* Save the data for the class to file
*/
void save(SimpleFile *file, int indent) override;
bool initDocument();
/**
* Renders the contents of the starfield
*/
void render(CVideoSurface *surface, CCamera *camera);
bool getBoundaryState() const;
void setBoundaryState(bool state);
bool getConstMapState() const;
void setConstMapState(bool state);
int get54() const;
void set54(int val);
/**
* Gets the current display mode
*/
StarMode getMode() const;
/**
* Sets the display mode
*/
void setMode(StarMode mode);
/**
* Toggles whether the big box is visible
*/
void toggleBox();
/**
* Sets whether the big box is visible
*/
bool setBoxVisible(bool isVisible);
/**
* Returns the index for the number of star matches
*/
int getMatchedIndex() const;
/**
* Returns true if the center of the starfield viewpoint is close to a marker
*/
bool isCloseToMarker() const;
/**
* Sets the flag that the starfield has been solved
*/
void setSolved();
/**
* Returns true if the starfield puzzle has been solved
*/
bool isSolved() const;
/**
* Return true if the starfield puzzle was skipped
*/
bool isSkipped() const;
/**
* Skips the starfield puzzle
*/
void skipPuzzle();
/**
* Returns the number of markers placed in the starfield
*/
int getMarkerCount() const {
return _markers.size();
}
void fn1(CErrorCode *errorCode);
/**
* Gets the lock distance to a star
*/
double lockDistance(CSurfaceArea *surfaceArea, CCamera *camera,
FVector &screenCoord, FVector &worldCoord, FVector &photoPos);
void fn6(CVideoSurface *surface, CCamera *camera);
/**
* Increments the number of matched markers
*/
void incLockLevel();
/**
* Decrements the number of matched markers
*/
void decLockLevel(CVideoSurface *surface);
void ToggleSolarRendering() { _starCloseup.fn1(); }
/**
* Called when the starfield is clicked
*/
bool mouseButtonDown(CVideoSurface *surface, CCamera *camera,
int flags, const Common::Point &pt);
/**
* Gets a random star
*/
const CBaseStarEntry *getRandomStar() const;
/**
* Gets a specified star
*/
const CBaseStarEntry *getStar(int index) const;
};
} // End of namespace Titanic
#endif /* TITANIC_STAR_FIELD_H */

View File

@@ -0,0 +1,58 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/star_field_base.h"
#include "titanic/debugger.h"
#include "titanic/star_control/camera.h"
#include "titanic/support/simple_file.h"
namespace Titanic {
bool CStarFieldBase::setup() {
loadData("STARFIELD/132");
return true;
}
bool CStarFieldBase::loadYale(int v1) {
clear();
error("Original loadYale not supported");
return true;
}
bool CStarFieldBase::selectStar(CSurfaceArea *surfaceArea,
CCamera *camera, const Common::Point &pt, void *handler) {
int index = findStar(surfaceArea, camera, pt);
if (index == -1) {
return false;
} else if (!handler) {
debugC(DEBUG_BASIC, kDebugStarfield, "Select star %d", index);
camera->setDestination(_data[index]._position);
return true;
} else {
error("no handler ever passed in original");
}
}
bool CStarFieldBase::loadStar() {
error("loadStar not supported");
}
} // End of namespace Titanic

View File

@@ -0,0 +1,51 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_STAR_FIELD_BASE_H
#define TITANIC_STAR_FIELD_BASE_H
#include "titanic/star_control/base_stars.h"
namespace Titanic {
class CStarFieldBase: public CBaseStars {
public:
~CStarFieldBase() override {}
bool loadYale(int v1) override;
/**
* Selects a star
*/
bool selectStar(CSurfaceArea *surfaceArea, CCamera *camera,
const Common::Point &pt, void *handler = nullptr) override;
bool loadStar() override;
/**
* Setup the control
*/
bool setup();
};
} // End of namespace Titanic
#endif /* TITANIC_STAR_FIELD_BASE_H */

View File

@@ -0,0 +1,93 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/star_markers.h"
#include "titanic/star_control/camera.h"
#include "titanic/star_control/surface_area.h"
namespace Titanic {
void CStarMarkers::draw(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup) {
if (_data.empty())
return;
FPose pose = camera->getPose();
double threshold = camera->getFrontClip();
FPoint center((double)surfaceArea->_width * 0.5,
surfaceArea->_height * 0.5);
FVector newV;
double xl, xc, xr, yt, yc, yb;
uint savedPixel = surfaceArea->_pixel;
surfaceArea->_pixel = 0xffff;
surfaceArea->setColorFromPixel();
for (uint idx = 0; idx < _data.size(); ++idx) {
const CBaseStarEntry &star = _data[idx];
newV._x = pose._row1._x * star._position._x + pose._row3._x * star._position._z
+ pose._row2._x * star._position._y + pose._vector._x;
newV._y = pose._row1._y * star._position._x + pose._row3._y * star._position._z
+ pose._row2._y * star._position._y + pose._vector._y;
newV._z = pose._row1._z * star._position._x + pose._row3._z * star._position._z
+ pose._row2._z * star._position._y + pose._vector._z;
if (newV._z > threshold) {
FVector vTemp = camera->getRelativePos(2, newV);
xc = center._x + vTemp._x;
yc = center._y + vTemp._y;
xl = xc - 4.0;
yt = yc - 4.0;
xr = xc + 4.0;
yb = yc + 4.0;
surfaceArea->drawLine(FPoint(xl, yc), FPoint(xc, yb)); // bottom-left
surfaceArea->drawLine(FPoint(xc, yb), FPoint(xr, yc)); // bottom-right
surfaceArea->drawLine(FPoint(xr, yc), FPoint(xc, yt)); // top-right
surfaceArea->drawLine(FPoint(xc, yt), FPoint(xl, yc)); // top-left
}
}
surfaceArea->_pixel = savedPixel;
surfaceArea->setColorFromPixel();
}
bool CStarMarkers::addStar(const CBaseStarEntry *entry) {
// iterate through the existing stars
for (uint idx = 0; idx < _data.size(); ++idx) {
CBaseStarEntry &star = _data[idx];
if (star == *entry) {
// Found a matching star at the exact same position, so remove it instead
_data.remove_at(idx);
return true;
}
}
// No existing match
if (_data.size() == 32)
// Out of space, so delete oldest star
_data.remove_at(0);
// Add new star
_data.push_back(*entry);
return true;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,46 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_STAR_MARKERS_H
#define TITANIC_STAR_MARKERS_H
#include "titanic/star_control/base_stars.h"
namespace Titanic {
class CStarMarkers : public CBaseStars {
public:
~CStarMarkers() override { clear(); }
/**
* Draw the item
*/
void draw(CSurfaceArea *surfaceArea, CCamera *camera, CStarCloseup *closeup) override;
/**
* Adds a new star, or removes one if already present at the given co-ordinates
*/
bool addStar(const CBaseStarEntry *entry) override;
};
} // End of namespace Titanic
#endif /* TITANIC_STAR_MARKERS_H */

View File

@@ -0,0 +1,116 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/star_ref.h"
#include "titanic/star_control/camera.h"
#include "titanic/star_control/surface_area.h"
namespace Titanic {
void CBaseStarRef::process(CSurfaceArea *surface, CCamera *camera) {
if (_stars->_data.empty())
return;
const double MAX_VAL = 1.0e9 * 1.0e9;
FPose pose = camera->getPose();
double threshold = camera->getFrontClip();
double vWidth2 = (double)surface->_width * 0.5;
double vHeight2 = (double)surface->_height * 0.5;
FVector vTemp, vector1, vector2;
double val1, green, blue, red;
for (int idx = 0; idx < _stars->size(); ++idx) {
const CBaseStarEntry &se = _stars->_data[idx];
vTemp = se._position;
vector1._x = vTemp._x * pose._row1._x + vTemp._y * pose._row2._x + vTemp._z * pose._row3._x + pose._vector._x;
vector1._y = vTemp._x * pose._row1._y + vTemp._y * pose._row2._y + vTemp._z * pose._row3._y + pose._vector._y;
vector1._z = vTemp._x * pose._row1._z + vTemp._y * pose._row2._z + vTemp._z * pose._row3._z + pose._vector._z;
double hyp = vector1._x * vector1._x + vector1._y * vector1._y + vector1._z * vector1._z;
if (vector1._z > threshold && hyp >= 1.0e12 && hyp < MAX_VAL) {
vector2 = camera->getRelativePos(2, vector1);
const Common::Point pt((int)(vector2._x + vWidth2 - -0.5),
(int)(vector2._y + vHeight2 - -0.5));
if (pt.y >= 0 && pt.y < (surface->_height - 1) &&
pt.x >= 0 && pt.x < (surface->_width - 1)) {
val1 = sqrt(hyp);
if (val1 >= 100000.0)
val1 = 1.0 - (val1 - 100000.0) / 1000000000.0;
else
val1 = 1.0;
red = val1 * (double)se._red;
green = val1 * (double)se._green;
blue = val1 * (double)se._blue;
int count = 0;
if (red < 0.0)
++count;
if (green < 0.0)
++count;
if (blue < 0.0)
++count;
if (count < 3) {
if (!check(pt, idx))
break;
}
}
}
}
}
/*------------------------------------------------------------------------*/
bool CStarRef1::check(const Common::Point &pt, int index) {
Common::Rect r(pt.x - 2, pt.y - 2, pt.x + 2, pt.y + 2);
if (r.contains(_position)) {
_index = index;
return false;
} else {
return true;
}
}
/*------------------------------------------------------------------------*/
bool CStarRefArray::check(const Common::Point &pt, int index) {
if (_index >= (int)_positions->size())
// Positions array full, so ignore
return false;
CStarPosition &sp = (*_positions)[_index++];
sp.x = pt.x;
sp.y = pt.y;
sp._index1 = sp._index2 = index;
return true;
}
/*------------------------------------------------------------------------*/
bool CStarRef3::check(const Common::Point &pt, int index) {
++_index;
return true;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,84 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/base_stars.h"
#include "common/rect.h"
#ifndef TITANIC_STAR_REF_H
#define TITANIC_STAR_REF_H
namespace Titanic {
class CCamera;
class CSurfaceArea;
class CBaseStarRef {
protected:
CBaseStars *_stars;
public:
CBaseStarRef(CBaseStars *stars) : _stars(stars) {}
CBaseStarRef() : _stars(nullptr) {}
virtual ~CBaseStarRef() {}
void process(CSurfaceArea *surface, CCamera *camera);
virtual bool check(const Common::Point &pt, int index) { return false; }
};
class CStarRef1 : public CBaseStarRef {
private:
Common::Point _position;
public:
int _index;
public:
CStarRef1(CBaseStars *stars, const Common::Point &pt) :
CBaseStarRef(stars), _position(pt), _index(-1) {}
~CStarRef1() override {}
bool check(const Common::Point &pt, int index) override;
};
class CStarRefArray : public CBaseStarRef {
private:
Common::Array<CStarPosition> *_positions;
public:
int _index;
public:
CStarRefArray(CBaseStars *stars, Common::Array<CStarPosition> *positions) :
CBaseStarRef(stars), _positions(positions), _index(0) {}
~CStarRefArray() override {}
bool check(const Common::Point &pt, int index) override;
};
class CStarRef3 : public CBaseStarRef {
public:
int _index;
public:
CStarRef3(CBaseStars *stars) :CBaseStarRef(stars), _index(0) {}
~CStarRef3() override {}
bool check(const Common::Point &pt, int index) override;
};
} // End of namespace Titanic
#endif /* TITANIC_STAR_REF_H */

View File

@@ -0,0 +1,537 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/star_view.h"
#include "titanic/star_control/motion_control.h"
#include "titanic/star_control/error_code.h"
#include "titanic/star_control/fvector.h"
#include "titanic/star_control/star_control.h"
#include "titanic/star_control/star_field.h"
#include "titanic/support/screen_manager.h"
#include "titanic/support/simple_file.h"
#include "titanic/core/game_object.h"
#include "titanic/messages/pet_messages.h"
#include "titanic/pet_control/pet_control.h"
#include "titanic/titanic.h"
namespace Titanic {
CStarView::CStarView() : _camera((const CNavigationInfo *)nullptr), _owner(nullptr),
_starField(nullptr), _videoSurface(nullptr), _lensValid(false),
_photoSurface(nullptr), _homePhotoMask(nullptr),
_stereoPair(false), _showingPhoto(false) {
CNavigationInfo data = { 0, 0, 100000.0, 0, 20.0, 1.0, 1.0, 1.0 };
_camera.setMotion(&data);
}
CStarView::~CStarView() {
delete _videoSurface;
delete _photoSurface;
}
void CStarView::load(SimpleFile *file, int param) {
if (!param) {
_camera.load(file, param);
_lensValid = file->readNumber();
if (_lensValid)
_photoViewport.load(file, 0);
_stereoPair = file->readNumber();
_showingPhoto = file->readNumber();
}
}
void CStarView::save(SimpleFile *file, int indent) {
_camera.save(file, indent);
file->writeNumberLine(_lensValid, indent);
if (_lensValid)
_photoViewport.save(file, indent);
file->writeNumberLine(_stereoPair, indent);
file->writeNumberLine(_showingPhoto, indent);
}
void CStarView::setup(CScreenManager *screenManager, CStarField *starField, CStarControl *starControl) {
_starField = starField;
_owner = starControl;
}
void CStarView::takeCurrentHomePhoto() {
if (_lensValid) {
CCamera camera(&_photoViewport);
takeHomePhotoHelper(&camera);
}
}
void CStarView::draw(CScreenManager *screenManager) {
if (!screenManager || !_videoSurface || !_starField)
return;
if (_fader.isActive()) {
CVideoSurface *surface = _showingPhoto ? _photoSurface : _videoSurface;
surface = _fader.draw(screenManager, surface);
screenManager->blitFrom(SURFACE_PRIMARY, surface);
} else {
Point destPos(20, 10);
if (_showingPhoto) {
if (_photoSurface)
screenManager->blitFrom(SURFACE_PRIMARY, _photoSurface, &destPos);
if (!_homePhotoMask && _owner) {
_homePhotoMask = _owner->getHiddenObject("HomePhotoMask");
}
if (_homePhotoMask)
_homePhotoMask->draw(screenManager, Point(20, 187));
} else {
updateCamera();
// Render the display
_videoSurface->clear();
_videoSurface->lock();
_starField->render(_videoSurface, &_camera);
_videoSurface->unlock();
// Blit the resulting surface to the screen
screenManager->blitFrom(SURFACE_PRIMARY, _videoSurface, &destPos);
}
}
}
bool CStarView::MouseButtonDownMsg(int flags, const Point &pt) {
if (_starField) {
return _starField->mouseButtonDown(
_showingPhoto ? _photoSurface : _videoSurface,
&_camera, flags, pt);
}
return false;
}
bool CStarView::MouseMoveMsg(int unused, const Point &pt) {
if (!_showingPhoto && (_fader._index < 0 || _fader._count >= 0)) {
FPoint fpt = pt;
FPoint centerPt(300.0, 170.0);
if (fpt != centerPt) {
float threshold = MIN(centerPt._x, centerPt._y) * 0.5;
FPoint tempPt = fpt - centerPt;
float distance = tempPt.normalize();
if (distance >= threshold) {
distance -= threshold;
FPoint angle(tempPt._x * -2.0 * distance / threshold,
tempPt._y * -2.0 * distance / threshold);
_camera.setViewportAngle(angle);
return true;
}
}
}
return false;
}
bool CStarView::ActionMsg(CActionMsg *msg, CErrorCode *errorCode) {
FPose pose;
int lockLevel = _starField ? _starField->getMatchedIndex() : -1;
Common::CustomEventType action = msg->_action;
switch (action) {
case kActionStarMapToggle:
if (_starField) {
toggleHomePhoto();
return true;
}
break;
case kActionStarMapLock: {
CPetControl *pet = _owner->getPetControl();
if (pet && pet->_remoteTarget) {
CPETStarFieldLockMsg lockMsg(1);
lockMsg.execute(pet->_remoteTarget);
}
return true;
}
case kActionStarMapUnlock: {
CPetControl *pet = _owner->getPetControl();
if (pet && pet->_remoteTarget) {
CPETStarFieldLockMsg lockMsg(0);
lockMsg.execute(pet->_remoteTarget);
}
return true;
}
case kActionStarMapLeft:
if (lockLevel == -1) {
pose.setRotationMatrix(Y_AXIS, -1.0);
_camera.changeOrientation(pose);
_camera.updatePosition(errorCode);
return true;
}
break;
case kActionStarMapForward:
if (lockLevel == -1) {
_camera.accelerate();
errorCode->set();
return true;
}
break;
case kActionStarMapBackward:
if (lockLevel == -1) {
_camera.deccelerate();
errorCode->set();
return true;
}
break;
case kActionStarMapStop:
if (lockLevel == -1) {
_camera.stop();
errorCode->set();
return true;
}
break;
case kActionStarMapRight:
if (lockLevel == -1) {
pose.setRotationMatrix(Y_AXIS, 1.0);
_camera.changeOrientation(pose);
_camera.updatePosition(errorCode);
return true;
}
break;
case kActionStarMapUp:
if (lockLevel == -1) {
pose.setRotationMatrix(X_AXIS, 1.0);
_camera.changeOrientation(pose);
_camera.updatePosition(errorCode);
return true;
}
break;
case kActionStarMapDown:
if (lockLevel == -1) {
pose.setRotationMatrix(X_AXIS, -1.0);
_camera.changeOrientation(pose);
_camera.updatePosition(errorCode);
return true;
}
break;
// New for ScummVM to show the boundaries sphere code the original implemented,
// but wasn't actually hooked up to any player action
case kActionStarMapBoundaries:
viewBoundaries();
return true;
// New for ScummVM to show the constellations sphere code the original implemented,
// but wasn't actually hooked up to any player action
case kActionStarMapConstellations:
viewConstellations();
return true;
default:
break;
}
return false;
}
bool CStarView::canSetStarDestination() const {
return _camera.isMoved();
}
void CStarView::starDestinationSet() {
_camera.clearIsMoved();
}
bool CStarView::updateCamera() {
if (_fader.isActive() || _showingPhoto)
return false;
if (_videoSurface) {
CErrorCode errorCode;
_camera.updatePosition(&errorCode);
if (_fader._index < 0 || _fader._index >= _fader._count)
_starField->fn1(&errorCode);
else
errorCode.set();
return errorCode.get();
}
return false;
}
void CStarView::resetView() {
if (!_videoSurface) {
CScreenManager *scrManager = CScreenManager::setCurrent();
if (scrManager)
resizeSurface(scrManager, 600, 340, &_videoSurface);
if (_videoSurface) {
stereoPairOn();
viewRequiredStar(244);
draw(scrManager);
}
}
}
void CStarView::triggerFade(bool fadeIn) {
_fader.reset();
_fader.setFadeIn(fadeIn);
}
void CStarView::viewFromEarth() {
_camera.setPosition(FVector(0.0, 0.0, 0.0));
}
void CStarView::viewEarth() {
FVector pos, dir;
getRandomViewpoint(pos, dir);
_camera.setPosition(pos);
_camera.setOrientation(dir);
}
void CStarView::viewBoundaries() {
_starField->setBoundaryState(!_starField->getBoundaryState());
}
void CStarView::viewConstellations() {
_starField->setConstMapState(!_starField->getConstMapState());
}
void CStarView::viewRandomStar() {
const CBaseStarEntry *star = _starField->getRandomStar();
if (star) {
FVector pos, orientation;
getRandomViewpoint(pos, orientation);
pos += star->_position;
_camera.setPosition(pos);
_camera.setOrientation(orientation);
}
}
void CStarView::viewRequiredStar(int index) {
const CBaseStarEntry *star = _starField->getStar(index);
if (star) {
FVector pos, orientation;
getRandomViewpoint(pos, orientation);
pos += star->_position;
_camera.setPosition(pos);
_camera.setOrientation(orientation);
}
}
void CStarView::fullSpeed() {
_camera.fullSpeed();
}
void CStarView::toggleSteroPair() {
_stereoPair = !_stereoPair;
if (_stereoPair) {
_camera.setFields(MODE_PHOTO, 30.0);
_camera.setFields(MODE_STARFIELD, 28000.0);
} else {
_camera.setFields(MODE_PHOTO, 0.0);
_camera.setFields(MODE_STARFIELD, 0.0);
}
}
void CStarView::toggleHomePhoto() {
if (!_photoSurface)
return;
_showingPhoto = !_showingPhoto;
if (_starField)
_starField->setMode(_showingPhoto ? MODE_PHOTO : MODE_STARFIELD);
}
void CStarView::toggleSolarRendering() {
if (_starField)
_starField->ToggleSolarRendering();
}
void CStarView::TogglePosFrame() {
if (_starField)
_starField->toggleBox();
}
void CStarView::stereoPairOn() {
_stereoPair = true;
_camera.setFields(MODE_PHOTO, 30.0);
_camera.setFields(MODE_STARFIELD, 28000.0);
}
void CStarView::stereoPairOff() {
_stereoPair = false;
_camera.setFields(MODE_PHOTO, 0.0);
_camera.setFields(MODE_STARFIELD, 0.0);
}
void CStarView::takeHomePhoto() {
FVector pos, orientation;
getRandomPhotoViewpoint(pos, orientation);
_photoViewport.setPosition(pos);
_photoViewport.setOrientation(orientation);
_stereoPair = false;
_photoViewport.changeStarColorPixel(MODE_PHOTO, 0.0);
_photoViewport.changeStarColorPixel(MODE_STARFIELD, 0.0);
_lensValid = true;
takeCurrentHomePhoto();
_stereoPair = true;
}
void CStarView::lockStar() {
if (_starField && !_showingPhoto) {
CSurfaceArea surfaceArea(_videoSurface);
FVector screenCoord, worldCoord, photoPos;
double dist = _starField->lockDistance(&surfaceArea, &_camera,
screenCoord, worldCoord, photoPos);
bool lockSuccess = false;
if (dist > -1.0) {
screenCoord -= surfaceArea._centroid;
photoPos -= surfaceArea._centroid;
switch (_starField->getMatchedIndex()) {
case -1:
// First star match
lockSuccess = _camera.lockMarker1(screenCoord, worldCoord, photoPos);
assert(lockSuccess); // lockMarker1 should always succeed
_starField->incLockLevel();
break;
case 0:
// Second star match
lockSuccess = _camera.lockMarker2(&_photoViewport, worldCoord);
if (lockSuccess) // lockMarker2 may have issues
_starField->incLockLevel();
break;
case 1:
// Third star match
lockSuccess = _camera.lockMarker3(&_photoViewport, worldCoord);
assert(lockSuccess); // lockMarker3 should always succeed
_starField->incLockLevel();
break;
default:
break;
}
}
}
}
void CStarView::unlockStar() {
if (_starField && !_showingPhoto && _camera.isNotInLockingProcess()) {
_camera.removeLockedStar();
_starField->decLockLevel(_photoSurface);
}
}
void CStarView::takeHomePhotoHelper(CCamera *camera) {
if (_starField) {
if (!_photoSurface) {
CScreenManager *scrManager = CScreenManager::setCurrent();
if (scrManager)
resizeSurface(scrManager, 600, 340, &_photoSurface);
}
if (_photoSurface) {
int oldVal = _starField->get54();
bool oldCrosshairs = _starField->setBoxVisible(false);
// Render the starfield for the photograph view
_photoSurface->clear();
_photoSurface->lock();
_starField->render(_photoSurface, camera);
// Render any previously set crosshairs
_starField->setBoxVisible(oldCrosshairs);
_starField->set54(oldVal);
_starField->fn6(_photoSurface, camera);
_photoSurface->unlock();
}
}
}
void CStarView::getRandomViewpoint(FVector &pos, FVector &orientation) {
const double MIN_RADIUS = 3.0F * STAR_SCALE;
const double RADIUS = 4.0F * STAR_SCALE;
pos._x = MIN_RADIUS + g_vm->getRandomFloat() * RADIUS;
pos._y = MIN_RADIUS + g_vm->getRandomFloat() * RADIUS;
pos._z = MIN_RADIUS + g_vm->getRandomFloat() * RADIUS;
orientation._x = -pos._x;
orientation._y = -pos._y;
orientation._z = -pos._z;
orientation.normalize();
}
void CStarView::getRandomPhotoViewpoint(FVector &pos, FVector &orientation) {
const double MIN_RADIUS = 3.0F * STAR_SCALE;
const double RADIUS = 4.0F * STAR_SCALE;
pos._x = MIN_RADIUS + g_vm->getRandomFloat() * RADIUS;
pos._y = MIN_RADIUS + g_vm->getRandomFloat() * RADIUS;
pos._z = MIN_RADIUS + g_vm->getRandomFloat() * RADIUS;
orientation._x = g_vm->getRandomFloat() * (STAR_SCALE * 8) - pos._x;
orientation._y = g_vm->getRandomFloat() * STAR_SCALE - pos._y;
orientation._z = -pos._z;
orientation.normalize();
}
void CStarView::resizeSurface(CScreenManager *scrManager, int width, int height,
CVideoSurface **surface) {
if (!surface)
// Surface pointer must be provided
return;
if (*surface) {
// If there's an existing surface of the correct size, re-use it
if ((*surface)->getWidth() == width && (*surface)->getHeight() == height)
return;
// Delete the old surface
delete *surface;
*surface = nullptr;
}
CVideoSurface *newSurface = scrManager->createSurface(width, height);
if (newSurface)
*surface = newSurface;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,224 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_STAR_VIEW_H
#define TITANIC_STAR_VIEW_H
#include "titanic/messages/messages.h"
#include "titanic/star_control/camera.h"
#include "titanic/star_control/surface_fader.h"
#include "titanic/star_control/viewport.h"
#include "titanic/support/rect.h"
namespace Titanic {
class CErrorCode;
class CGameObject;
class CStarControl;
class CStarField;
class CVideoSurface;
class FVector;
class CStarView {
private:
CStarControl *_owner;
CStarField *_starField;
CVideoSurface *_videoSurface;
CCamera _camera;
bool _lensValid;
CViewport _photoViewport;
CSurfaceFader _fader;
CVideoSurface *_photoSurface;
CGameObject *_homePhotoMask;
bool _stereoPair;
bool _showingPhoto;
private:
/**
* Take a photograph of a view specified by the camera
*/
void takeHomePhotoHelper(CCamera *camera);
/**
* View a specified star
*/
void viewRequiredStar(int index);
/**
* Gets a random position and orientation
*/
void getRandomViewpoint(FVector &pos, FVector &orientation);
/**
* Gets a random position and orientation
*/
void getRandomPhotoViewpoint(FVector &pos, FVector &orientation);
/**
* Handles resizing the surface
*/
void resizeSurface(CScreenManager *scrManager, int width, int height,
CVideoSurface **surface);
public:
CStarView();
~CStarView();
/**
* Load the data for the class from file
*/
void load(SimpleFile *file, int param);
/**
* Save the data for the class to file
*/
void save(SimpleFile *file, int indent);
/**
* Sets references used by the view
*/
void setup(CScreenManager *screenManager, CStarField *starField, CStarControl *starControl);
/**
* Take a photograph of a view specified by the current home photo lens
*/
void takeCurrentHomePhoto();
/**
* Allows the item to draw itself
*/
void draw(CScreenManager *screenManager);
/**
* Updates the camera, allowing for movement
*/
bool updateCamera();
/**
* Handles mouse down messages
*/
bool MouseButtonDownMsg(int unused, const Point &pt);
/**
* Handles mouse move messages
*/
bool MouseMoveMsg(int unused, const Point &pt);
/**
* Handles action messages
*/
bool ActionMsg(CActionMsg *msg, CErrorCode *errorCode);
/**
* Returns true if a star destination can be set
*/
bool canSetStarDestination() const;
/**
* Called when a star destination is set
*/
void starDestinationSet();
/**
* Reset the starfield view
*/
void resetView();
void triggerFade(bool fadeIn);
/**
* View the solar system
*/
void viewEarth();
/**
* Set the view to be from earth
*/
void viewFromEarth();
/**
* Turn on constellation boundaries
*/
void viewBoundaries();
/**
* Turn on the constellation lines
*/
void viewConstellations();
/**
* Look at a random star
*/
void viewRandomStar();
/**
* Increase starfield movement to full speed
*/
void fullSpeed();
/**
* Enable stereo pair vision
*/
void toggleSteroPair();
/**
* Toggles between starfield and photo modes
*/
void toggleHomePhoto();
/**
* Toggles the solar object rendering
*/
void toggleSolarRendering();
/**
* Toggles whether the viewpoint box is visible in the starfield
*/
void TogglePosFrame();
/**
* Turn on Stereo Pair imaging
*/
void stereoPairOn();
/**
* Turn off Stereo Pair imaging
*/
void stereoPairOff();
/**
* Called when the photograph is used on the navigation computer,
* takes a photograph of the current view, writing it to the home photo surface
*/
void takeHomePhoto();
/**
* Handles locking in a star
*/
void lockStar();
/**
* Handles unlocking a star
*/
void unlockStar();
};
} // End of namespace Titanic
#endif /* TITANIC_STAR_VIEW_H */

View File

@@ -0,0 +1,233 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/surface_area.h"
#include "graphics/primitives.h"
namespace Titanic {
CSurfaceArea::CSurfaceArea(CVideoSurface *surface) {
_width = surface->getWidth();
_height = surface->getHeight();
_pitch = surface->getPitch();
_field0 = 0;
_colorMask = _color = 0;
_mode = SA_SOLID;
_surface = nullptr;
// Original supported other pixel depths
_bpp = surface->getPixelDepth();
_pixelsPtr = (byte *)surface->getPixels();
assert(_bpp == 2 && _pixelsPtr);
initialize();
}
void CSurfaceArea::initialize() {
_bounds = Rect(0, 0, _width - 1, _height - 1);
_centroid = FPoint(_width / 2.0, _height / 2.0);
_pixel = 0xffffff;
_field27 = _field26 = _field25 = 0;
_field24 = 0;
_rgb = _field2C = 0;
_mode = SA_SOLID;
}
void CSurfaceArea::setColor(uint rgb) {
switch (_mode) {
case SA_MODE1:
_color = 0;
_colorMask = rgb;
break;
case SA_MODE2:
_color = rgb;
_colorMask = ~rgb;
break;
case SA_XOR:
_color = rgb;
_colorMask = 0xFFFFFFFF;
break;
case SA_MODE4:
_color = 0;
_colorMask = ~rgb;
break;
default:
break;
}
}
SurfaceAreaMode CSurfaceArea::setMode(SurfaceAreaMode mode) {
SurfaceAreaMode oldMode = _mode;
_mode = mode;
setColor(_rgb);
return oldMode;
}
void CSurfaceArea::setColorFromPixel() {
pixelToRGB(_pixel, &_rgb);
setColor(_rgb);
}
Graphics::PixelFormat CSurfaceArea::getPixelFormat() const {
switch (_bpp) {
case 1:
case 2:
return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
case 4:
return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
default:
return Graphics::PixelFormat::createFormatCLUT8();
}
}
void CSurfaceArea::pixelToRGB(uint pixel, uint *rgb) {
switch (_bpp) {
case 0:
*rgb = 0;
break;
case 1:
case 2: {
Graphics::PixelFormat pf = getPixelFormat();
*rgb = pf.RGBToColor(pixel & 0xff, (pixel >> 8) & 0xff, (pixel >> 16) & 0xff);
break;
}
case 3:
case 4:
*rgb = pixel;
break;
default:
break;
}
}
template<typename T>
class CSurfacePrimitives : public Graphics::Primitives {
void drawPoint(int x, int y, uint32 color, void *data) override {
CSurfaceArea *sa = (CSurfaceArea *)data;
if (x >= 0 && x < sa->_width && y >= 0 && y < sa->_height) {
T *ptr = (T *)sa->_surface->getBasePtr(x, y);
*ptr = (*ptr & sa->_colorMask) ^ sa->_color;
}
}
};
double CSurfaceArea::drawLine(const FPoint &pt1, const FPoint &pt2) {
if (pt1 == pt2)
return pt1._y;
FPoint p1 = pt1, p2 = pt2;
double xp = pt1._x, yp = pt1._y;
int flags1 = (p1._x < _bounds.left ? 1 : 0)
| (p1._x > _bounds.right ? 2 : 0)
| (p1._y < _bounds.top ? 4 : 0)
| (p1._y > _bounds.bottom ? 8 : 0);
int flags2 = (p2._x < _bounds.left ? 1 : 0)
| (p2._x > _bounds.right ? 2 : 0)
| (p2._y < _bounds.top ? 4 : 0)
| (p2._y > _bounds.bottom ? 8 : 0);
// Handle any clipping
while (flags1 | flags2) {
if (flags1 & flags2)
return p1._y;
int flags = flags1 ? flags1 : flags2;
if ((flags & 1) || (flags & 2)) {
xp = (flags & 1) ? _bounds.left : _bounds.right;
yp = (p2._y - p1._y) * (xp - p1._x) / (p2._x - p1._x) + p1._y;
} else if ((flags & 4) || (flags & 8)) {
yp = (flags & 4) ? _bounds.top : _bounds.bottom;
xp = (p2._x - p1._x) * (yp - p1._y) / (p2._y - p1._y) + p1._x;
}
if (flags == flags1) {
p1._x = xp;
p1._y = yp;
flags1 = 0;
if (xp < _bounds.left)
flags1 |= 1;
if (xp > _bounds.right)
flags1 |= 2;
if (yp < _bounds.top)
flags1 |= 4;
if (yp > _bounds.bottom)
flags1 |= 8;
} else {
p2._x = xp;
p2._y = yp;
flags2 = 0;
if (xp < _bounds.left)
flags2 |= 1;
if (xp > _bounds.right)
flags2 |= 2;
if (yp < _bounds.top)
flags2 |= 4;
if (yp > _bounds.bottom)
flags2 |= 8;
}
}
Common::Point srcPos((int)(p1._x - 0.5), (int)(p1._y - 0.5));
Common::Point destPos((int)(p2._x - 0.5), (int)(p2._y - 0.5));
Graphics::Surface s;
s.setPixels(_pixelsPtr);
s.pitch = _pitch;
s.format = getPixelFormat();
s.w = _width;
s.h = _height;
_surface = &s;
switch (_bpp) {
case 0:
if (_mode != SA_SOLID) {
CSurfacePrimitives<byte>().drawLine(srcPos.x, srcPos.y, destPos.x, destPos.y, 0, this);
return p1._y;
}
break;
case 1:
case 2:
if (_mode != SA_SOLID) {
CSurfacePrimitives<uint16>().drawLine(srcPos.x, srcPos.y, destPos.x, destPos.y, 0, this);
return p1._y;
}
break;
case 4:
if (_mode != SA_SOLID) {
CSurfacePrimitives<uint32>().drawLine(srcPos.x, srcPos.y, destPos.x, destPos.y, 0, this);
return p1._y;
}
break;
default:
error("Unknown bpp");
}
s.drawLine(srcPos.x, srcPos.y, destPos.x, destPos.y, _rgb);
return p1._y;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,100 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_SURFACE_OBJ_H
#define TITANIC_SURFACE_OBJ_H
#include "titanic/support/rect.h"
#include "titanic/support/video_surface.h"
#include "titanic/star_control/fpoint.h"
#include "titanic/star_control/frect.h"
namespace Titanic {
enum SurfaceAreaMode {
SA_SOLID = 0, SA_MODE1 = 1, SA_MODE2 = 2, SA_XOR = 3, SA_MODE4 = 4
};
class CSurfaceArea {
private:
/**
* Initialize data for the class
*/
void initialize();
/**
* Sets the drawing color and mask
*/
void setColor(uint rgb);
void pixelToRGB(uint pixel, uint *rgb);
Graphics::PixelFormat getPixelFormat() const;
public:
int _field0;
int _width;
int _height;
int _pitch;
int _bpp;
byte *_pixelsPtr;
FPoint _centroid;
uint _pixel;
byte _field24;
byte _field25;
byte _field26;
byte _field27;
uint _rgb;
int _field2C;
uint _colorMask;
uint _color;
SurfaceAreaMode _mode;
Rect _bounds;
Graphics::Surface *_surface;
public:
CSurfaceArea(CVideoSurface *surface);
/**
* Sets the drawing mode, and returns the old mode
*/
SurfaceAreaMode setMode(SurfaceAreaMode mode);
/**
* Sets the color from the current pixel
*/
void setColorFromPixel();
/**
* Draws a line on the surface
*/
double drawLine(const FPoint &pt1, const FPoint &pt2);
/**
* Draws a line on the surface from the rect's top-left
* to bottom-right corners
*/
double drawLine(const FRect &rect) {
return drawLine(FPoint(rect.left, rect.top), FPoint(rect.right, rect.bottom));
}
};
} // End of namespace Titanic
#endif /* TITANIC_STAR_CONTROL_SUB16_H */

View File

@@ -0,0 +1,121 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/surface_fader.h"
#include "titanic/star_control/surface_area.h"
#include "titanic/support/screen_manager.h"
#include "titanic/support/video_surface.h"
#include "common/system.h"
#include "graphics/pixelformat.h"
namespace Titanic {
CSurfaceFader::CSurfaceFader() : _index(-1), _count(32), _fadeIn(false), _videoSurface(nullptr) {
_dataP = new byte[_count];
for (int idx = 0; idx < _count; ++idx)
_dataP[idx] = (byte)(pow((double)idx / (double)_count, 1.299999952316284)
* (double)_count + 0.5);
}
CSurfaceFader::~CSurfaceFader() {
delete _videoSurface;
delete[] _dataP;
}
void CSurfaceFader::reset() {
_index = 0;
}
bool CSurfaceFader::setupSurface(CScreenManager *screenManager, CVideoSurface *srcSurface) {
int width = srcSurface->getWidth();
int height = srcSurface->getHeight();
if (_videoSurface) {
if (width == _videoSurface->getWidth() && _videoSurface->getHeight())
// Allocated surface already matches new size
return true;
// Different sizes, so delete old surface
delete _videoSurface;
}
_videoSurface = screenManager->createSurface(width, height);
return true;
}
CVideoSurface *CSurfaceFader::draw(CScreenManager *screenManager, CVideoSurface *srcSurface) {
if (_index < 0 || _index >= _count)
return srcSurface;
// On the first iteration, set up a temporary surface
if (_index == 0 && !setupSurface(screenManager, srcSurface))
return nullptr;
srcSurface->lock();
_videoSurface->lock();
CSurfaceArea srcSurfaceArea(srcSurface);
CSurfaceArea destSurfaceArea(_videoSurface);
// Copy the surface with fading
step(srcSurfaceArea, destSurfaceArea);
srcSurface->unlock();
_videoSurface->unlock();
++_index;
return _videoSurface;
}
void CSurfaceFader::step(CSurfaceArea &srcSurface, CSurfaceArea &destSurface) {
const uint16 *srcPixelP = (const uint16 *)srcSurface._pixelsPtr;
uint16 *destPixelP = (uint16 *)destSurface._pixelsPtr;
// Currently we only support 2 bytes per pixel surfaces
assert(srcSurface._bpp == 2);
byte dataVal = _dataP[_index];
double fraction = (double)dataVal / ((double)(_count - 1));
if (!_fadeIn)
// For fade outs, reverse the percentage visibility
fraction = 1.0 - fraction;
// Iterate through the pixels
byte r, g, b;
Graphics::PixelFormat format = g_system->getScreenFormat();
for (int yp = 0; yp < srcSurface._height; ++yp) {
for (int xp = 0; xp < srcSurface._width; ++xp, ++srcPixelP, ++destPixelP) {
format.colorToRGB(*srcPixelP, r, g, b);
r = (byte)((double)r * fraction);
g = (byte)((double)g * fraction);
b = (byte)((double)b * fraction);
*destPixelP = format.RGBToColor(r, g, b);
}
}
}
void CSurfaceFader::setFadeIn(bool fadeIn) {
_fadeIn = fadeIn;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,79 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_SURFACE_FADER_H
#define TITANIC_SURFACE_FADER_H
#include "common/scummsys.h"
namespace Titanic {
class CVideoSurface;
class CScreenManager;
class CSurfaceArea;
class CSurfaceFader {
private:
byte *_dataP;
bool _fadeIn;
private:
/**
* Create a faded version of the source surface for the new step
*/
void step(CSurfaceArea &srcSurface, CSurfaceArea &destSurface);
/**
* Sets up an internal surface to match the size of the specified one
*/
bool setupSurface(CScreenManager *screenManager, CVideoSurface *srcSurface);
public:
int _index;
int _count;
CVideoSurface *_videoSurface;
public:
CSurfaceFader();
~CSurfaceFader();
/**
* Reset fading back to the start
*/
void reset();
/**
* Creates a faded version of the passed source surface, based on a percentage
* visibility specified by _index of _count
*/
CVideoSurface *draw(CScreenManager *screenManager, CVideoSurface *srcSurface);
/**
* Sets whether a fade in (versus a fade out) should be done
*/
void setFadeIn(bool fadeIn);
/**
* Returns true if a fade is in progress
*/
bool isActive() const { return _index >= 0 && _index < _count; }
};
} // End of namespace Titanic
#endif /* TITANIC_SURFACE_SHADER_H */

View File

@@ -0,0 +1,308 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "titanic/star_control/viewport.h"
#include "titanic/star_control/fvector.h"
#include "titanic/debugger.h"
#include "titanic/support/simple_file.h"
#include "titanic/titanic.h"
#include "math/utils.h"
namespace Titanic {
CViewport::CViewport() {
_spin = 0.0;
_frontClip = 800.0;
_backClip = 10000.0;
_centerYAngleDegrees = 20.0;
_centerZAngleDegrees = 20.0;
_width = 600;
_height = 340;
_starColor = PINK; // default for starview
_poseUpToDate = false;
Common::fill(&_valArray[0], &_valArray[2], 0.0);
_isZero = 0.0; // seems to always be zero
_pixel1OffSetX = 0.0;
_pixel2OffSetX = 0.0;
}
CViewport::CViewport(CViewport *src) :
_orientation(src->_orientation), _currentPose(src->_currentPose), _rawPose(src->_rawPose) {
_position = src->_position;
_spin = src->_spin;
_frontClip = src->_frontClip;
_backClip = src->_backClip;
_centerYAngleDegrees = src->_centerYAngleDegrees;
_centerZAngleDegrees = src->_centerZAngleDegrees;
_width = src->_width;
_height = src->_height;
_center = src->_center;
_centerVector = src->_centerVector;
_starColor = src->_starColor;
Common::copy(&src->_valArray[0], &src->_valArray[2], &_valArray[0]);
_isZero = src->_isZero;
_pixel1OffSetX = src->_pixel1OffSetX;
_pixel2OffSetX = src->_pixel2OffSetX;
_poseUpToDate = false;
}
void CViewport::copyFrom(const CViewport *src) {
error("Unused function");
}
void CViewport::load(SimpleFile *file, int param) {
_position._x = file->readFloat();
_position._y = file->readFloat();
_position._z = file->readFloat();
_spin = file->readFloat();
_frontClip = file->readFloat();
_backClip = file->readFloat();
_centerYAngleDegrees = file->readFloat();
_centerZAngleDegrees = file->readFloat();
int widthHeight = file->readNumber();
_width = widthHeight & 0xffff;
_height = widthHeight >> 16;
int field24 = file->readNumber(); //0 = White, 2 = Pink
_starColor = (StarColor) field24;
for (int idx = 0; idx < 2; ++idx)
_valArray[idx] = file->readFloat();
_isZero = file->readFloat();
_pixel1OffSetX = file->readFloat();
_pixel2OffSetX = file->readFloat();
_orientation.load(file, param);
_poseUpToDate = false;
}
void CViewport::save(SimpleFile *file, int indent) {
file->writeFloatLine(_position._x, indent);
file->writeFloatLine(_position._y, indent);
file->writeFloatLine(_position._z, indent);
file->writeFloatLine(_spin, indent);
file->writeFloatLine(_frontClip, indent);
file->writeFloatLine(_backClip, indent);
file->writeFloatLine(_centerYAngleDegrees, indent);
file->writeFloatLine(_centerZAngleDegrees, indent);
file->writeNumberLine(_width | (_height << 16), indent);
int field24 = (int)_starColor;
file->writeNumberLine(field24, indent);
for (int idx = 0; idx < 2; ++idx)
file->writeFloatLine(_valArray[idx], indent);
file->writeFloatLine(_isZero, indent);
file->writeFloatLine(_pixel1OffSetX, indent);
file->writeFloatLine(_pixel2OffSetX, indent);
_orientation.save(file, indent);
}
void CViewport::setPosition(const FVector &v) {
debugC(DEBUG_INTERMEDIATE, kDebugStarfield, "Setting starmap position to %s", v.toString().c_str());
_position = v;
_poseUpToDate = false;
}
void CViewport::setPosition(const FPose &pose) {
_position = _position.matProdRowVect(pose);
_poseUpToDate = false;
}
void CViewport::setOrientation(const FMatrix &m) {
_orientation = m;
_poseUpToDate = false;
}
void CViewport::setOrientation(const FVector &v) {
_orientation.set(v);
_poseUpToDate = false;
}
void CViewport::SetRoleAngle(double angle) {
_spin = angle;
_poseUpToDate = false;
}
void CViewport::setFrontClip(double dist) {
_frontClip = dist;
_poseUpToDate = false;
}
void CViewport::setBackClip(double dist) {
_backClip = dist;
}
void CViewport::setCenterYAngle(double angleDegrees) {
_centerYAngleDegrees = angleDegrees;
_poseUpToDate = false;
}
void CViewport::setCenterZAngle(double angleDegrees) {
_centerZAngleDegrees = angleDegrees;
_poseUpToDate = false;
}
void CViewport::randomizeOrientation() {
_orientation.identity();
double ranRotAngleX = g_vm->getRandomNumber(359);
double ranRotAngleY = g_vm->getRandomNumber(359);
double ranRotAngleZ = g_vm->getRandomNumber(359);
FPose m1(X_AXIS, ranRotAngleX);
FPose m2(Y_AXIS, ranRotAngleY);
FPose m3(Z_AXIS, ranRotAngleZ);
FPose s1(m1, m2);
FPose s2(s1, m3);
_orientation.matRProd(s2);
_poseUpToDate = false;
}
void CViewport::changeStarColorPixel(StarMode mode, double pixelOffSet) {
// pixelOffset is usually 0.0, 30.0, or 28000.0
if (mode == MODE_PHOTO) {
_valArray[0] = pixelOffSet;
_valArray[1] = -pixelOffSet;
} else {
_pixel1OffSetX = pixelOffSet;
_pixel2OffSetX = -pixelOffSet;
}
_isZero = 0.0;
_starColor = pixelOffSet ? PINK : WHITE;
}
void CViewport::reposition(double factor) {
_position._x = _orientation._row3._x * factor + _position._x;
_position._y = _orientation._row3._y * factor + _position._y;
_position._z = _orientation._row3._z * factor + _position._z;
_poseUpToDate = false;
}
void CViewport::changeOrientation(const FMatrix &matrix) {
_orientation.matLProd(matrix);
_poseUpToDate = false;
}
FPose CViewport::getPose() {
if (!_poseUpToDate)
reset();
return _currentPose;
}
FPose CViewport::getRawPose() {
if (!_poseUpToDate)
reset();
return _rawPose;
}
// TODO: should index be used here like
// getRelativePosCentering/getRelativePosCentering2?
// CCamera::getRelativePosCentering is calling this with an index of
// 2 which corresponds to _isZero which has value 0.
FVector CViewport::getRelativePosNoCentering(int index, const FVector &src) {
FPose current_pose = getPose();
FVector dest = src.matProdRowVect(current_pose);
return dest;
}
FVector CViewport::getRelativePosCentering(int index, const FVector &src) {
FVector dest;
FPose pose = getPose();
FVector tv = src.matProdRowVect(pose);
double val;
if (index <2) {
val = _valArray[index];
} else if (index == 2) {
val = _isZero;
} else if (index == 3) {
val = _pixel1OffSetX;
} else {
val = _pixel2OffSetX;
}
dest._x = (val + tv._x)
* _centerVector._x / (_centerVector._y * tv._z);
dest._y = (tv._y * _centerVector._x) / (_centerVector._z * tv._z);
dest._z = tv._z;
return dest;
}
// Similar to getRelativePosCentering, but uses the raw/transpose version of Pose
FVector CViewport::getRelativePosCenteringRaw(int index, const FVector &src) {
FVector dest;
FPose pose = getRawPose();
FVector tv = src.matProdRowVect(pose);
double val;
if (index <2) {
val = _valArray[index];
} else if (index == 2) {
val = _isZero;
} else if (index == 3) {
val = _pixel1OffSetX;
} else {
val = _pixel2OffSetX;
}
dest._x = (val + tv._x)
* _centerVector._x / (_centerVector._y * tv._z);
dest._y = (tv._y * _centerVector._x) / (_centerVector._z * tv._z);
dest._z = tv._z;
return dest;
}
void CViewport::getRelativeXCenterPixels(double *v1, double *v2, double *v3, double *v4) {
*v1 = _centerVector._x / _centerVector._y;
*v2 = _centerVector._x / _centerVector._z;
*v3 = _pixel1OffSetX;
*v4 = _pixel2OffSetX;
}
void CViewport::reset() {
_rawPose.copyFrom(_orientation);
_rawPose._vector = _position;
_currentPose = _rawPose.inverseTransform();
_poseUpToDate = true;
_center = FPoint((double)_width * 0.5, (double)_height * 0.5);
_centerVector._x = MIN(_center._x, _center._y);
_centerVector._y = tan(Math::deg2rad<double>(_centerYAngleDegrees));
_centerVector._z = tan(Math::deg2rad<double>(_centerZAngleDegrees));
}
const FMatrix &CViewport::getOrientation() const {
return _orientation;
}
} // End of namespace Titanic

View File

@@ -0,0 +1,175 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TITANIC_VIEWPORT_H
#define TITANIC_VIEWPORT_H
#include "titanic/star_control/base_stars.h"
#include "titanic/star_control/fpose.h"
class SimpleFile;
namespace Titanic {
/**
* The color of the stars when drawn (CBaseStars::draw)
* For starview it should be white
* For skyview it should be pink
*/
enum StarColor { WHITE = 0, PINK = 2 };
/**
* Implements the viewport functionality for viewing the star field in
* a given position and orientation.
* CCamera is a big user of this class
*/
class CViewport {
private:
double _spin;
double _centerYAngleDegrees;
double _centerZAngleDegrees;
int _width;
int _height;
FMatrix _orientation;
FPose _currentPose;
FPose _rawPose;
FPoint _center;
bool _poseUpToDate;
private:
void reset();
public:
FVector _position;
double _frontClip;
double _backClip;
StarColor _starColor; // Used in CBaseStars::draw
double _valArray[2]; // has value 0.0 or 30.0
double _isZero;
double _pixel1OffSetX; // Used in CBaseStars::draw3 and CBaseStars::draw4 has value 0.0 or 28000.0
double _pixel2OffSetX; // Used in CBaseStars::draw3 and CBaseStars::draw4 has value 0.0 or -28000.0
FVector _centerVector;
public:
CViewport();
CViewport(CViewport *src);
/**
* Copys the data from another instance
*/
void copyFrom(const CViewport *src);
/**
* Load the data for the class from file
*/
void load(SimpleFile *file, int param);
/**
* Save the data for the class to file
*/
void save(SimpleFile *file, int indent);
/**
* Sets the position
*/
void setPosition(const FVector &v);
/**
* Sets the position
*/
void setPosition(const FPose &pose);
/**
* Sets the orientation from a passed matrix
*/
void setOrientation(const FMatrix &m);
/**
* Sets the orientation from a passed vector
*/
void setOrientation(const FVector &v);
void randomizeOrientation();
/**
* The view has changed between starview and skyview
* Change the enum that tracks the color of the stars
* Also change the X coordinate pixel offset used for star drawing
*/
void changeStarColorPixel(StarMode mode, double pixelOffSet);
void reposition(double factor);
/**
* Applys a rotation matrix to the current
* orientation
*/
void changeOrientation(const FMatrix &matrix);
FPose getPose();
FPose getRawPose();
FVector getRelativePosNoCentering(int index, const FVector &src);
FVector getRelativePosCentering(int index, const FVector &src);
FVector getRelativePosCenteringRaw(int index, const FVector &src);
/**
* All arguments are return values
* First is the x center coordinate relative to y
* Second is the x center coordinate relative to z
* Third is the first x center pixel offset
* Fourth is the second x center pixel offset
*/
void getRelativeXCenterPixels(double *v1, double *v2, double *v3, double *v4);
/**
* Returns the viewport's orientation
*/
const FMatrix &getOrientation() const;
/**
* Assigns a roll angle about the view direction
*/
void SetRoleAngle(double angle);
/**
* Assign a near clip plane distance
*/
void setFrontClip(double dist);
/**
* Assign a far clipping plane distance
*/
void setBackClip(double dist);
/**
* Sets the center vector y angle
* The actual center y value doesn't
* change until reset is called
*/
void setCenterYAngle(double angleDegrees);
/**
* Sets the center vector z angle
* The actual center z value doesn't
* change until reset is called
*/
void setCenterZAngle(double angleDegrees);
};
} // End of namespace Titanic
#endif /* TITANIC_VIEWPORT_H */