Initial commit
This commit is contained in:
562
engines/titanic/star_control/base_stars.cpp
Normal file
562
engines/titanic/star_control/base_stars.cpp
Normal 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
|
||||
164
engines/titanic/star_control/base_stars.h
Normal file
164
engines/titanic/star_control/base_stars.h
Normal 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 */
|
||||
642
engines/titanic/star_control/camera.cpp
Normal file
642
engines/titanic/star_control/camera.cpp
Normal 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
|
||||
277
engines/titanic/star_control/camera.h
Normal file
277
engines/titanic/star_control/camera.h
Normal 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 */
|
||||
123
engines/titanic/star_control/const_boundaries.cpp
Normal file
123
engines/titanic/star_control/const_boundaries.cpp
Normal 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
|
||||
56
engines/titanic/star_control/const_boundaries.h
Normal file
56
engines/titanic/star_control/const_boundaries.h
Normal 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 */
|
||||
122
engines/titanic/star_control/constellations.cpp
Normal file
122
engines/titanic/star_control/constellations.cpp
Normal 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
|
||||
54
engines/titanic/star_control/constellations.h
Normal file
54
engines/titanic/star_control/constellations.h
Normal 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 */
|
||||
50
engines/titanic/star_control/error_code.h
Normal file
50
engines/titanic/star_control/error_code.h
Normal 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 */
|
||||
95
engines/titanic/star_control/flight_manager_base.cpp
Normal file
95
engines/titanic/star_control/flight_manager_base.cpp
Normal 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
|
||||
86
engines/titanic/star_control/flight_manager_base.h
Normal file
86
engines/titanic/star_control/flight_manager_base.h
Normal 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 */
|
||||
102
engines/titanic/star_control/flight_manager_marked.cpp
Normal file
102
engines/titanic/star_control/flight_manager_marked.cpp
Normal 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
|
||||
54
engines/titanic/star_control/flight_manager_marked.h
Normal file
54
engines/titanic/star_control/flight_manager_marked.h
Normal 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 */
|
||||
167
engines/titanic/star_control/flight_manager_unmarked.cpp
Normal file
167
engines/titanic/star_control/flight_manager_unmarked.cpp
Normal 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
|
||||
48
engines/titanic/star_control/flight_manager_unmarked.h
Normal file
48
engines/titanic/star_control/flight_manager_unmarked.h
Normal 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 */
|
||||
136
engines/titanic/star_control/fmatrix.cpp
Normal file
136
engines/titanic/star_control/fmatrix.cpp
Normal 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
|
||||
124
engines/titanic/star_control/fmatrix.h
Normal file
124
engines/titanic/star_control/fmatrix.h
Normal 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 */
|
||||
36
engines/titanic/star_control/fpoint.cpp
Normal file
36
engines/titanic/star_control/fpoint.cpp
Normal 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
|
||||
64
engines/titanic/star_control/fpoint.h
Normal file
64
engines/titanic/star_control/fpoint.h
Normal 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 */
|
||||
237
engines/titanic/star_control/fpose.cpp
Normal file
237
engines/titanic/star_control/fpose.cpp
Normal 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
|
||||
106
engines/titanic/star_control/fpose.h
Normal file
106
engines/titanic/star_control/fpose.h
Normal 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 */
|
||||
44
engines/titanic/star_control/frange.cpp
Normal file
44
engines/titanic/star_control/frange.cpp
Normal 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
|
||||
49
engines/titanic/star_control/frange.h
Normal file
49
engines/titanic/star_control/frange.h
Normal 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 */
|
||||
38
engines/titanic/star_control/frect.cpp
Normal file
38
engines/titanic/star_control/frect.cpp
Normal 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
|
||||
57
engines/titanic/star_control/frect.h
Normal file
57
engines/titanic/star_control/frect.h
Normal 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 */
|
||||
140
engines/titanic/star_control/fvector.cpp
Normal file
140
engines/titanic/star_control/fvector.cpp
Normal 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
|
||||
176
engines/titanic/star_control/fvector.h
Normal file
176
engines/titanic/star_control/fvector.h
Normal 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 */
|
||||
189
engines/titanic/star_control/matrix_inv.h
Normal file
189
engines/titanic/star_control/matrix_inv.h
Normal 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 */
|
||||
146
engines/titanic/star_control/matrix_transform.cpp
Normal file
146
engines/titanic/star_control/matrix_transform.cpp
Normal 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
|
||||
58
engines/titanic/star_control/matrix_transform.h
Normal file
58
engines/titanic/star_control/matrix_transform.h
Normal 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 */
|
||||
157
engines/titanic/star_control/motion_control.cpp
Normal file
157
engines/titanic/star_control/motion_control.cpp
Normal 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
|
||||
167
engines/titanic/star_control/motion_control.h
Normal file
167
engines/titanic/star_control/motion_control.h
Normal 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 */
|
||||
61
engines/titanic/star_control/motion_control_marked.cpp
Normal file
61
engines/titanic/star_control/motion_control_marked.cpp
Normal 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
|
||||
55
engines/titanic/star_control/motion_control_marked.h
Normal file
55
engines/titanic/star_control/motion_control_marked.h
Normal 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 */
|
||||
78
engines/titanic/star_control/motion_control_unmarked.cpp
Normal file
78
engines/titanic/star_control/motion_control_unmarked.cpp
Normal 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
|
||||
55
engines/titanic/star_control/motion_control_unmarked.h
Normal file
55
engines/titanic/star_control/motion_control_unmarked.h
Normal 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 */
|
||||
50
engines/titanic/star_control/orientation_changer.cpp
Normal file
50
engines/titanic/star_control/orientation_changer.cpp
Normal 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
|
||||
53
engines/titanic/star_control/orientation_changer.h
Normal file
53
engines/titanic/star_control/orientation_changer.h
Normal 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 */
|
||||
560
engines/titanic/star_control/star_closeup.cpp
Normal file
560
engines/titanic/star_control/star_closeup.cpp
Normal 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
|
||||
139
engines/titanic/star_control/star_closeup.h
Normal file
139
engines/titanic/star_control/star_closeup.h
Normal 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 */
|
||||
296
engines/titanic/star_control/star_control.cpp
Normal file
296
engines/titanic/star_control/star_control.cpp
Normal 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
|
||||
114
engines/titanic/star_control/star_control.h
Normal file
114
engines/titanic/star_control/star_control.h
Normal 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 */
|
||||
266
engines/titanic/star_control/star_crosshairs.cpp
Normal file
266
engines/titanic/star_control/star_crosshairs.cpp
Normal 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
|
||||
136
engines/titanic/star_control/star_crosshairs.h
Normal file
136
engines/titanic/star_control/star_crosshairs.h
Normal 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 */
|
||||
267
engines/titanic/star_control/star_field.cpp
Normal file
267
engines/titanic/star_control/star_field.cpp
Normal 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
|
||||
190
engines/titanic/star_control/star_field.h
Normal file
190
engines/titanic/star_control/star_field.h
Normal 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 */
|
||||
58
engines/titanic/star_control/star_field_base.cpp
Normal file
58
engines/titanic/star_control/star_field_base.cpp
Normal 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
|
||||
51
engines/titanic/star_control/star_field_base.h
Normal file
51
engines/titanic/star_control/star_field_base.h
Normal 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 */
|
||||
93
engines/titanic/star_control/star_markers.cpp
Normal file
93
engines/titanic/star_control/star_markers.cpp
Normal 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
|
||||
46
engines/titanic/star_control/star_markers.h
Normal file
46
engines/titanic/star_control/star_markers.h
Normal 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 */
|
||||
116
engines/titanic/star_control/star_ref.cpp
Normal file
116
engines/titanic/star_control/star_ref.cpp
Normal 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
|
||||
84
engines/titanic/star_control/star_ref.h
Normal file
84
engines/titanic/star_control/star_ref.h
Normal 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 */
|
||||
537
engines/titanic/star_control/star_view.cpp
Normal file
537
engines/titanic/star_control/star_view.cpp
Normal 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
|
||||
224
engines/titanic/star_control/star_view.h
Normal file
224
engines/titanic/star_control/star_view.h
Normal 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 */
|
||||
233
engines/titanic/star_control/surface_area.cpp
Normal file
233
engines/titanic/star_control/surface_area.cpp
Normal 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
|
||||
100
engines/titanic/star_control/surface_area.h
Normal file
100
engines/titanic/star_control/surface_area.h
Normal 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 */
|
||||
121
engines/titanic/star_control/surface_fader.cpp
Normal file
121
engines/titanic/star_control/surface_fader.cpp
Normal 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
|
||||
79
engines/titanic/star_control/surface_fader.h
Normal file
79
engines/titanic/star_control/surface_fader.h
Normal 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 */
|
||||
308
engines/titanic/star_control/viewport.cpp
Normal file
308
engines/titanic/star_control/viewport.cpp
Normal 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
|
||||
175
engines/titanic/star_control/viewport.h
Normal file
175
engines/titanic/star_control/viewport.h
Normal 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 */
|
||||
Reference in New Issue
Block a user