Initial commit
This commit is contained in:
45
engines/freescape/objects/connections.h
Normal file
45
engines/freescape/objects/connections.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* 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 FREESCAPE_CONNECTIONS_H
|
||||
#define FREESCAPE_CONNECTIONS_H
|
||||
|
||||
#include "freescape/objects/object.h"
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
class AreaConnections : public Object {
|
||||
public:
|
||||
Common::Array<byte> _connections;
|
||||
AreaConnections(const Common::Array<byte> connections_) {
|
||||
_objectID = 254;
|
||||
_connections = connections_;
|
||||
}
|
||||
|
||||
ObjectType getType() override { return ObjectType::kEntranceType; };
|
||||
void draw(Freescape::Renderer *gfx, float offset = 0.0) override { error("cannot render AreaConnections"); };
|
||||
void scale(int factor) override { /* Nothing */ };
|
||||
Object *duplicate() override { error("cannot duplicate AreaConnections"); };
|
||||
};
|
||||
|
||||
} // End of namespace Freescape
|
||||
|
||||
#endif // FREESCAPE_CONNECTIONS_H
|
||||
74
engines/freescape/objects/entrance.h
Normal file
74
engines/freescape/objects/entrance.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Based on Phantasma code by Thomas Harte (2013),
|
||||
// available at https://github.com/TomHarte/Phantasma/ (MIT)
|
||||
|
||||
#ifndef FREESCAPE_ENTRANCE_H
|
||||
#define FREESCAPE_ENTRANCE_H
|
||||
|
||||
#include "freescape/objects/object.h"
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
extern FCLInstructionVector *duplicateCondition(FCLInstructionVector *condition);
|
||||
|
||||
class Entrance : public Object {
|
||||
public:
|
||||
Entrance(
|
||||
uint16 objectID_,
|
||||
const Math::Vector3d &origin_,
|
||||
const Math::Vector3d &rotation_,
|
||||
FCLInstructionVector conditionInstructions_,
|
||||
Common::String conditionSource_) {
|
||||
_objectID = objectID_;
|
||||
_origin = origin_;
|
||||
_rotation = rotation_;
|
||||
|
||||
_condition = conditionInstructions_;
|
||||
_conditionSource = conditionSource_;
|
||||
_flags = 0;
|
||||
}
|
||||
virtual ~Entrance() {}
|
||||
|
||||
bool isDrawable() override { return false; }
|
||||
bool isPlanar() override { return true; }
|
||||
void scale(int factor) override { _origin = _origin / factor; };
|
||||
Object *duplicate() override {
|
||||
FCLInstructionVector *conditionCopy = duplicateCondition(&_condition);
|
||||
assert(conditionCopy);
|
||||
Entrance *entrance = new Entrance(_objectID, _origin, _rotation, *conditionCopy, _conditionSource);
|
||||
delete conditionCopy;
|
||||
return entrance;
|
||||
};
|
||||
|
||||
ObjectType getType() override { return ObjectType::kEntranceType; };
|
||||
Math::Vector3d getRotation() { return _rotation; }
|
||||
|
||||
Common::String _conditionSource;
|
||||
FCLInstructionVector _condition;
|
||||
|
||||
void draw(Freescape::Renderer *gfx, float offset = 0.0) override { error("cannot render Entrance"); };
|
||||
};
|
||||
|
||||
} // End of namespace Freescape
|
||||
|
||||
#endif // FREESCAPE_ENTRANCE_H
|
||||
481
engines/freescape/objects/geometricobject.cpp
Normal file
481
engines/freescape/objects/geometricobject.cpp
Normal file
@@ -0,0 +1,481 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Based on Phantasma code by Thomas Harte (2013),
|
||||
// available at https://github.com/TomHarte/Phantasma/ (MIT)
|
||||
|
||||
#include "common/system.h"
|
||||
|
||||
#include "freescape/objects/geometricobject.h"
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
extern FCLInstructionVector *duplicateCondition(FCLInstructionVector *condition);
|
||||
|
||||
int GeometricObject::numberOfColoursForObjectOfType(ObjectType type) {
|
||||
switch (type) {
|
||||
default:
|
||||
case kEntranceType:
|
||||
case kGroupType:
|
||||
case kSensorType:
|
||||
return 0;
|
||||
|
||||
case kLineType:
|
||||
return 2;
|
||||
|
||||
case kRectangleType:
|
||||
case kTriangleType:
|
||||
case kQuadrilateralType:
|
||||
case kPentagonType:
|
||||
case kHexagonType:
|
||||
return 2;
|
||||
|
||||
case kCubeType:
|
||||
case kEastPyramidType:
|
||||
case kWestPyramidType:
|
||||
case kUpPyramidType:
|
||||
case kDownPyramidType:
|
||||
case kNorthPyramidType:
|
||||
case kSouthPyramidType:
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
int GeometricObject::numberOfOrdinatesForType(ObjectType type) {
|
||||
switch (type) {
|
||||
default:
|
||||
case kEntranceType:
|
||||
case kGroupType:
|
||||
case kRectangleType:
|
||||
case kSensorType:
|
||||
return 0;
|
||||
|
||||
case kEastPyramidType:
|
||||
case kWestPyramidType:
|
||||
case kUpPyramidType:
|
||||
case kDownPyramidType:
|
||||
case kNorthPyramidType:
|
||||
case kSouthPyramidType:
|
||||
return 4;
|
||||
|
||||
case kLineType:
|
||||
case kTriangleType:
|
||||
case kQuadrilateralType:
|
||||
case kPentagonType:
|
||||
case kHexagonType:
|
||||
return 3 * (2 + type - kLineType);
|
||||
}
|
||||
}
|
||||
|
||||
bool GeometricObject::isPyramid(ObjectType type) {
|
||||
switch (type) {
|
||||
default:
|
||||
return false;
|
||||
|
||||
case kEastPyramidType:
|
||||
case kWestPyramidType:
|
||||
case kUpPyramidType:
|
||||
case kDownPyramidType:
|
||||
case kNorthPyramidType:
|
||||
case kSouthPyramidType:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool GeometricObject::isPolygon(ObjectType type) {
|
||||
switch (type) {
|
||||
default:
|
||||
return false;
|
||||
|
||||
case kLineType:
|
||||
case kTriangleType:
|
||||
case kQuadrilateralType:
|
||||
case kPentagonType:
|
||||
case kHexagonType:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
GeometricObject::GeometricObject(
|
||||
ObjectType type_,
|
||||
uint16 objectID_,
|
||||
uint16 flags_,
|
||||
const Math::Vector3d &origin_,
|
||||
const Math::Vector3d &size_,
|
||||
Common::Array<uint8> *colours_,
|
||||
Common::Array<uint8> *ecolours_,
|
||||
Common::Array<float> *ordinates_,
|
||||
FCLInstructionVector conditionInstructions_,
|
||||
Common::String conditionSource_) {
|
||||
_type = type_;
|
||||
assert(_type != kGroupType);
|
||||
_flags = flags_;
|
||||
|
||||
if (isDestroyed()) // If the object is destroyed, restore it
|
||||
restore();
|
||||
|
||||
if (isInitiallyInvisible())
|
||||
makeInvisible();
|
||||
else
|
||||
makeVisible();
|
||||
|
||||
_objectID = objectID_;
|
||||
_origin = origin_;
|
||||
_size = size_;
|
||||
|
||||
_colours = nullptr;
|
||||
|
||||
if (colours_)
|
||||
_colours = colours_;
|
||||
|
||||
_ecolours = nullptr;
|
||||
|
||||
if (ecolours_)
|
||||
_ecolours = ecolours_;
|
||||
|
||||
_cyclingColors = false; // This needs to be set manually
|
||||
_ordinates = nullptr;
|
||||
_initialOrdinates = nullptr;
|
||||
|
||||
if (ordinates_) {
|
||||
_ordinates = ordinates_;
|
||||
_initialOrdinates = new Common::Array<float>(*_ordinates);
|
||||
}
|
||||
_condition = conditionInstructions_;
|
||||
_conditionSource = conditionSource_;
|
||||
|
||||
if (_type == kRectangleType) {
|
||||
if ((_size.x() == 0 && _size.y() == 0) ||
|
||||
(_size.y() == 0 && _size.z() == 0) ||
|
||||
(_size.x() == 0 && _size.z() == 0)) {
|
||||
|
||||
_type = kLineType;
|
||||
assert(!_ordinates);
|
||||
_ordinates = new Common::Array<float>();
|
||||
_ordinates->push_back(_origin.x());
|
||||
_ordinates->push_back(_origin.y());
|
||||
_ordinates->push_back(_origin.z());
|
||||
|
||||
_ordinates->push_back(_origin.x() + _size.x());
|
||||
_ordinates->push_back(_origin.y() + _size.y());
|
||||
_ordinates->push_back(_origin.z() + _size.z());
|
||||
}
|
||||
} else if (isPyramid(_type))
|
||||
assert(_size.x() > 0 && _size.y() > 0 && _size.z() > 0);
|
||||
|
||||
computeBoundingBox();
|
||||
}
|
||||
|
||||
void GeometricObject::setOrigin(Math::Vector3d origin_) {
|
||||
_origin = origin_;
|
||||
computeBoundingBox();
|
||||
}
|
||||
|
||||
void GeometricObject::offsetOrigin(Math::Vector3d origin_) {
|
||||
if (isPolygon(_type)) {
|
||||
Math::Vector3d offset = origin_ - _origin;
|
||||
for (int i = 0; i < int(_ordinates->size()); i = i + 3) {
|
||||
float ordinate = 0;
|
||||
ordinate = (*_ordinates)[i];
|
||||
ordinate += offset.x();
|
||||
assert(ordinate >= 0);
|
||||
(*_ordinates)[i] = ordinate;
|
||||
|
||||
ordinate = (*_ordinates)[i + 1];
|
||||
ordinate += offset.y();
|
||||
assert(ordinate >= 0);
|
||||
(*_ordinates)[i + 1] = ordinate;
|
||||
|
||||
ordinate = (*_ordinates)[i + 2];
|
||||
ordinate += offset.z();
|
||||
assert(ordinate >= 0);
|
||||
(*_ordinates)[i + 2] = ordinate;
|
||||
}
|
||||
}
|
||||
setOrigin(origin_);
|
||||
}
|
||||
|
||||
void GeometricObject::scale(int factor) {
|
||||
_origin = _origin / factor;
|
||||
_size = _size / factor;
|
||||
if (_ordinates) {
|
||||
for (uint i = 0; i < _ordinates->size(); i++) {
|
||||
(*_ordinates)[i] = (*_ordinates)[i] / factor;
|
||||
if (_initialOrdinates)
|
||||
(*_initialOrdinates)[i] = (*_initialOrdinates)[i] / factor;
|
||||
}
|
||||
}
|
||||
computeBoundingBox();
|
||||
}
|
||||
|
||||
void GeometricObject::restoreOrdinates() {
|
||||
if (!isPolygon(_type))
|
||||
return;
|
||||
|
||||
for (uint i = 0; i < _ordinates->size(); i++)
|
||||
(*_ordinates)[i] = (*_initialOrdinates)[i];
|
||||
|
||||
computeBoundingBox();
|
||||
}
|
||||
|
||||
Object *GeometricObject::duplicate() {
|
||||
Common::Array<uint8> *coloursCopy = nullptr;
|
||||
Common::Array<uint8> *ecoloursCopy = nullptr;
|
||||
Common::Array<float> *ordinatesCopy = nullptr;
|
||||
FCLInstructionVector *conditionCopy = nullptr;
|
||||
|
||||
if (_colours)
|
||||
coloursCopy = new Common::Array<uint8>(*_colours);
|
||||
|
||||
if (_ecolours)
|
||||
ecoloursCopy = new Common::Array<uint8>(*_ecolours);
|
||||
|
||||
if (_ordinates)
|
||||
ordinatesCopy = new Common::Array<float>(*_ordinates);
|
||||
|
||||
conditionCopy = duplicateCondition(&_condition);
|
||||
assert(conditionCopy);
|
||||
|
||||
GeometricObject *copy = new GeometricObject(
|
||||
_type,
|
||||
_objectID,
|
||||
_flags,
|
||||
_origin,
|
||||
_size,
|
||||
coloursCopy,
|
||||
ecoloursCopy,
|
||||
ordinatesCopy,
|
||||
*conditionCopy,
|
||||
_conditionSource
|
||||
);
|
||||
|
||||
copy->_cyclingColors = _cyclingColors;
|
||||
return copy;
|
||||
}
|
||||
|
||||
void GeometricObject::computeBoundingBox() {
|
||||
_boundingBox = Math::AABB();
|
||||
Math::Vector3d v;
|
||||
switch (_type) {
|
||||
default:
|
||||
break;
|
||||
case kCubeType:
|
||||
_boundingBox.expand(_origin);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
v = _origin;
|
||||
v.setValue(i, v.getValue(i) + _size.getValue(i));
|
||||
_boundingBox.expand(v);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
v = _origin + _size;
|
||||
v.setValue(i, v.getValue(i) - _size.getValue(i));
|
||||
_boundingBox.expand(v);
|
||||
}
|
||||
_boundingBox.expand(_origin + _size);
|
||||
assert(_boundingBox.isValid());
|
||||
break;
|
||||
case kRectangleType:
|
||||
_boundingBox.expand(_origin);
|
||||
_boundingBox.expand(_origin + _size);
|
||||
break;
|
||||
case kLineType:
|
||||
if (!_ordinates)
|
||||
error("Ordinates needed to compute bounding box!");
|
||||
for (uint i = 0; i < _ordinates->size(); i = i + 3) {
|
||||
_boundingBox.expand(Math::Vector3d((*_ordinates)[i], (*_ordinates)[i + 1], (*_ordinates)[i + 2]));
|
||||
}
|
||||
int dx, dy, dz;
|
||||
dx = dy = dz = 0;
|
||||
if (_size.x() == 0 && _size.y() == 0) {
|
||||
dx = 2;
|
||||
dy = 2;
|
||||
} else if (_size.x() == 0 && _size.z() == 0) {
|
||||
dx = 2;
|
||||
dz = 2;
|
||||
} else if (_size.y() == 0 && _size.z() == 0) {
|
||||
dy = 2;
|
||||
dz = 2;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < _ordinates->size(); i = i + 3) {
|
||||
_boundingBox.expand(Math::Vector3d((*_ordinates)[i] + dx, (*_ordinates)[i + 1] + dy, (*_ordinates)[i + 2] + dz));
|
||||
}
|
||||
|
||||
break;
|
||||
case kTriangleType:
|
||||
case kQuadrilateralType:
|
||||
case kPentagonType:
|
||||
case kHexagonType:
|
||||
if (!_ordinates)
|
||||
error("Ordinates needed to compute bounding box!");
|
||||
for (uint i = 0; i < _ordinates->size(); i = i + 3) {
|
||||
_boundingBox.expand(Math::Vector3d((*_ordinates)[i], (*_ordinates)[i + 1], (*_ordinates)[i + 2]));
|
||||
}
|
||||
break;
|
||||
|
||||
case kEastPyramidType:
|
||||
if (!_ordinates)
|
||||
error("Ordinates needed to compute bounding box!");
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, 0, _size.z()));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), _size.z()));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), 0));
|
||||
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), (*_ordinates)[0], (*_ordinates)[3]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), (*_ordinates)[2], (*_ordinates)[3]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), (*_ordinates)[2], (*_ordinates)[1]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), (*_ordinates)[0], (*_ordinates)[1]));
|
||||
break;
|
||||
case kWestPyramidType:
|
||||
if (!_ordinates)
|
||||
error("Ordinates needed to compute bounding box!");
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, 0));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), 0));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), _size.z()));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, _size.z()));
|
||||
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, (*_ordinates)[0], (*_ordinates)[1]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, (*_ordinates)[2], (*_ordinates)[1]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, (*_ordinates)[2], (*_ordinates)[3]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, (*_ordinates)[0], (*_ordinates)[3]));
|
||||
break;
|
||||
case kUpPyramidType:
|
||||
if (!_ordinates)
|
||||
error("Ordinates needed to compute bounding box!");
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, 0));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, _size.z()));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, 0, _size.z()));
|
||||
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], _size.y(), (*_ordinates)[1]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], _size.y(), (*_ordinates)[1]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], _size.y(), (*_ordinates)[3]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], _size.y(), (*_ordinates)[3]));
|
||||
break;
|
||||
case kDownPyramidType:
|
||||
if (!_ordinates)
|
||||
error("Ordinates needed to compute bounding box!");
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), 0));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), 0));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), _size.z()));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), _size.z()));
|
||||
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], 0, (*_ordinates)[1]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], 0, (*_ordinates)[1]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], 0, (*_ordinates)[3]));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], 0, (*_ordinates)[3]));
|
||||
break;
|
||||
case kNorthPyramidType:
|
||||
if (!_ordinates)
|
||||
error("Ordinates needed to compute bounding box!");
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), 0));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), 0));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, 0));
|
||||
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], (*_ordinates)[3], _size.z()));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], (*_ordinates)[3], _size.z()));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], (*_ordinates)[1], _size.z()));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], (*_ordinates)[1], _size.z()));
|
||||
break;
|
||||
case kSouthPyramidType:
|
||||
if (!_ordinates)
|
||||
error("Ordinates needed to compute bounding box!");
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, 0, _size.z()));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), 0, _size.z()));
|
||||
_boundingBox.expand(_origin + Math::Vector3d(_size.x(), _size.y(), _size.z()));
|
||||
|
||||
_boundingBox.expand(_origin + Math::Vector3d(0, _size.y(), _size.z()));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], (*_ordinates)[1], 0));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], (*_ordinates)[1], 0));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[2], (*_ordinates)[3], 0));
|
||||
_boundingBox.expand(_origin + Math::Vector3d((*_ordinates)[0], (*_ordinates)[3], 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GeometricObject::~GeometricObject() {
|
||||
delete _colours;
|
||||
delete _ordinates;
|
||||
delete _initialOrdinates;
|
||||
}
|
||||
|
||||
// This function returns when the object is a line, but it is not a straight line
|
||||
bool GeometricObject::isLineButNotStraight() {
|
||||
if (_type != kLineType)
|
||||
return false;
|
||||
|
||||
if (!_ordinates)
|
||||
return false;
|
||||
|
||||
if (_ordinates->size() != 6)
|
||||
return false;
|
||||
|
||||
// At least two coordinates should be the same to be a straight line
|
||||
if ((*_ordinates)[0] == (*_ordinates)[3] && (*_ordinates)[1] == (*_ordinates)[4])
|
||||
return false;
|
||||
|
||||
if ((*_ordinates)[0] == (*_ordinates)[3] && (*_ordinates)[2] == (*_ordinates)[5])
|
||||
return false;
|
||||
|
||||
if ((*_ordinates)[1] == (*_ordinates)[4] && (*_ordinates)[2] == (*_ordinates)[5])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GeometricObject::isDrawable() { return true; }
|
||||
bool GeometricObject::isPlanar() {
|
||||
ObjectType t = this->getType();
|
||||
return (t >= kLineType) || t == kRectangleType || !_size.x() || !_size.y() || !_size.z();
|
||||
}
|
||||
|
||||
bool GeometricObject::collides(const Math::AABB &boundingBox_) {
|
||||
if (isDestroyed() || isInvisible() || !_boundingBox.isValid() || !boundingBox_.isValid())
|
||||
return false;
|
||||
|
||||
return _boundingBox.collides(boundingBox_);
|
||||
}
|
||||
|
||||
void GeometricObject::draw(Renderer *gfx, float offset) {
|
||||
if (_cyclingColors) {
|
||||
assert(_colours);
|
||||
if (g_system->getMillis() % 10 == 0)
|
||||
for (uint i = 0; i < _colours->size(); i++) {
|
||||
(*_colours)[i] = ((*_colours)[i] + 1) % 0xf;
|
||||
if (_ecolours)
|
||||
(*_ecolours)[i] = ((*_ecolours)[i] + 1) % 0xf;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->getType() == kCubeType) {
|
||||
gfx->renderCube(_origin, _size, _colours, _ecolours, offset);
|
||||
} else if (this->getType() == kRectangleType) {
|
||||
gfx->renderRectangle(_origin, _size, _colours, _ecolours, offset);
|
||||
} else if (isPyramid(this->getType())) {
|
||||
gfx->renderPyramid(_origin, _size, _ordinates, _colours, _ecolours, this->getType());
|
||||
} else if (this->isPlanar() && _type <= 14) {
|
||||
if (this->getType() == kTriangleType)
|
||||
assert(_ordinates->size() == 9);
|
||||
|
||||
gfx->renderPolygon(_origin, _size, _ordinates, _colours, _ecolours, offset);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Freescape
|
||||
80
engines/freescape/objects/geometricobject.h
Normal file
80
engines/freescape/objects/geometricobject.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Based on Phantasma code by Thomas Harte (2013),
|
||||
// available at https://github.com/TomHarte/Phantasma/ (MIT)
|
||||
|
||||
#ifndef FREESCAPE_GEOMETRICOBJECT_H
|
||||
#define FREESCAPE_GEOMETRICOBJECT_H
|
||||
|
||||
#include "freescape/language/instruction.h"
|
||||
#include "freescape/objects/group.h"
|
||||
#include "freescape/objects/object.h"
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
class GeometricObject : public Object {
|
||||
public:
|
||||
static int numberOfColoursForObjectOfType(ObjectType type);
|
||||
static int numberOfOrdinatesForType(ObjectType type);
|
||||
static bool isPyramid(ObjectType type);
|
||||
static bool isPolygon(ObjectType type);
|
||||
|
||||
GeometricObject(
|
||||
ObjectType type,
|
||||
uint16 objectID,
|
||||
uint16 flags,
|
||||
const Math::Vector3d &origin,
|
||||
const Math::Vector3d &size,
|
||||
Common::Array<uint8> *colours,
|
||||
Common::Array<uint8> *ecolours,
|
||||
Common::Array<float> *ordinates,
|
||||
FCLInstructionVector conditionInstructions,
|
||||
Common::String conditionSource = "");
|
||||
virtual ~GeometricObject();
|
||||
void setOrigin(Math::Vector3d origin) override;
|
||||
void offsetOrigin(Math::Vector3d origin_);
|
||||
void restoreOrdinates();
|
||||
|
||||
Object *duplicate() override;
|
||||
void scale(int factor) override;
|
||||
void computeBoundingBox();
|
||||
bool collides(const Math::AABB &boundingBox);
|
||||
void draw(Freescape::Renderer *gfx, float offset = 0.0) override;
|
||||
bool isDrawable() override;
|
||||
bool isPlanar() override;
|
||||
bool _cyclingColors;
|
||||
|
||||
bool isLineButNotStraight();
|
||||
|
||||
Common::String _conditionSource;
|
||||
FCLInstructionVector _condition;
|
||||
|
||||
private:
|
||||
Common::Array<uint8> *_colours;
|
||||
Common::Array<uint8> *_ecolours;
|
||||
Common::Array<float> *_ordinates;
|
||||
Common::Array<float> *_initialOrdinates;
|
||||
};
|
||||
|
||||
} // End of namespace Freescape
|
||||
|
||||
#endif // FREESCAPE_GEOMETRICOBJECT_H
|
||||
45
engines/freescape/objects/global.h
Normal file
45
engines/freescape/objects/global.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* 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 FREESCAPE_GLOBAL_H
|
||||
#define FREESCAPE_GLOBAL_H
|
||||
|
||||
#include "freescape/objects/object.h"
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
class GlobalStructure : public Object {
|
||||
public:
|
||||
Common::Array<byte> _structure;
|
||||
GlobalStructure(const Common::Array<byte> structure_) {
|
||||
_objectID = 255;
|
||||
_structure = structure_;
|
||||
}
|
||||
|
||||
ObjectType getType() override { return ObjectType::kEntranceType; };
|
||||
void draw(Freescape::Renderer *gfx, float offset = 0.0) override { error("cannot render GlobalStructure"); };
|
||||
void scale(int factor) override { /* Nothing */ };
|
||||
Object *duplicate() override { error("cannot duplicate GlobalStructure"); };
|
||||
};
|
||||
|
||||
} // End of namespace Freescape
|
||||
|
||||
#endif // FREESCAPE_GLOBAL_H
|
||||
226
engines/freescape/objects/group.cpp
Normal file
226
engines/freescape/objects/group.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
/* 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 "freescape/freescape.h"
|
||||
#include "freescape/objects/group.h"
|
||||
#include "freescape/objects/geometricobject.h"
|
||||
#include "freescape/language/8bitDetokeniser.h"
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
Group::Group(uint16 objectID_, uint16 flags_,
|
||||
const Common::Array<uint16> objectIds_,
|
||||
const Math::Vector3d offset1_,
|
||||
const Math::Vector3d offset2_,
|
||||
const Common::Array<AnimationOpcode *> operations_) {
|
||||
_type = kGroupType;
|
||||
_objectID = objectID_;
|
||||
_flags = flags_;
|
||||
_scale = 0;
|
||||
_active = true;
|
||||
_step = 0;
|
||||
_offset1 = offset1_;
|
||||
_offset2 = offset2_;
|
||||
|
||||
for (int i = 0; i < 3; i++) { // three is the maximum number of objects in a group
|
||||
if (objectIds_[i] == 0 || objectIds_[i] == 0xffff)
|
||||
break;
|
||||
_objectIds.push_back(objectIds_[i]);
|
||||
}
|
||||
|
||||
_operations = operations_;
|
||||
|
||||
if (isDestroyed()) // If the object is destroyed, restore it
|
||||
restore();
|
||||
|
||||
makeInitiallyVisible();
|
||||
makeVisible();
|
||||
}
|
||||
|
||||
Group::~Group() {
|
||||
for (int i = 0; i < int(_operations.size()); i++)
|
||||
delete _operations[i];
|
||||
}
|
||||
|
||||
Object *Group::duplicate() {
|
||||
return new Group(
|
||||
_objectID,
|
||||
_flags,
|
||||
_objectIds,
|
||||
_offset1,
|
||||
_offset2,
|
||||
_operations
|
||||
);
|
||||
}
|
||||
|
||||
void Group::linkObject(Object *obj) {
|
||||
int objectIndex = -1;
|
||||
for (int i = 0; i < int(_objectIds.size()) ; i++) {
|
||||
if (_objectIds[i] == obj->getObjectID()) {
|
||||
objectIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (objectIndex == -1)
|
||||
return;
|
||||
|
||||
debugC(1, kFreescapeDebugParser, "Linking object: %d to group %d", obj->getObjectID(), this->getObjectID());
|
||||
_origins.push_back(obj->getOrigin());
|
||||
debugC(1, kFreescapeDebugParser, "Origin %f, %f %f", obj->getOrigin().x(), obj->getOrigin().y(), obj->getOrigin().z());
|
||||
|
||||
obj->_partOfGroup = this;
|
||||
_objects.push_back(obj);
|
||||
}
|
||||
|
||||
void Group::assemble(int index) {
|
||||
GeometricObject *gobj = (GeometricObject *)_objects[index];
|
||||
Math::Vector3d position = _operations[_step]->position;
|
||||
Math::Vector3d offset = _origins[index] - _origins[0];
|
||||
/*if (index == 0)
|
||||
; // offset is always zero
|
||||
else if (index == 1)
|
||||
offset = _offset1;
|
||||
else if (index == 2)
|
||||
offset = _offset1 + _offset2;
|
||||
else
|
||||
error("Invalid index: %d", index);
|
||||
|
||||
offset = 32 * offset / _scale;*/
|
||||
position = 32 * position / _scale;
|
||||
|
||||
debugC(1, kFreescapeDebugGroup, "Group %d: Assembling object %d originally at %f, %f, %f", _objectID, gobj->getObjectID(), gobj->getOrigin().x(), gobj->getOrigin().y(), gobj->getOrigin().z());
|
||||
gobj->offsetOrigin(position + offset);
|
||||
debugC(1, kFreescapeDebugGroup, "Group %d: Assembling object %d moved to %f, %f, %f", _objectID, gobj->getObjectID(), gobj->getOrigin().x(), gobj->getOrigin().y(), gobj->getOrigin().z());
|
||||
}
|
||||
|
||||
void Group::run() {
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
int opcode = _operations[_step]->opcode;
|
||||
debugC(1, kFreescapeDebugGroup, "Executing opcode 0x%x at step %d", opcode, _step);
|
||||
if (opcode == 0x80 || opcode == 0xff) {
|
||||
debugC(1, kFreescapeDebugGroup, "Executing group rewind");
|
||||
_active = true;
|
||||
_step = -1;
|
||||
if (opcode == 0xff)
|
||||
return;
|
||||
//reset();
|
||||
}
|
||||
|
||||
if (opcode & 0x01) {
|
||||
debugC(1, kFreescapeDebugGroup, "Executing group condition %s", _operations[_step]->conditionSource.c_str());
|
||||
g_freescape->executeCode(_operations[_step]->condition, false, true, false, false);
|
||||
}
|
||||
|
||||
if (opcode & 0x10) {
|
||||
uint32 groupSize = _objects.size();
|
||||
for (uint32 i = 0; i < groupSize ; i++)
|
||||
assemble(i);
|
||||
_active = false;
|
||||
_step++;
|
||||
}
|
||||
|
||||
if (opcode == 0x0) {
|
||||
debugC(1, kFreescapeDebugGroup, "Executing group assemble");
|
||||
uint32 groupSize = _objects.size();
|
||||
for (uint32 i = 0; i < groupSize ; i++)
|
||||
assemble(i);
|
||||
}
|
||||
|
||||
if (opcode & 0x08) {
|
||||
uint32 groupSize = _objects.size();
|
||||
for (uint32 i = 0; i < groupSize ; i++)
|
||||
_objects[i]->makeVisible();
|
||||
|
||||
if (opcode & 0x20) {
|
||||
for (uint32 i = 0; i < groupSize ; i++)
|
||||
_objects[i]->destroy();
|
||||
}
|
||||
|
||||
if (opcode & 0x40) {
|
||||
for (uint32 i = 0; i < groupSize ; i++)
|
||||
_objects[i]->makeInvisible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Group::start() {
|
||||
makeVisible();
|
||||
_active = true;
|
||||
}
|
||||
|
||||
void Group::reset() {
|
||||
uint32 groupSize = _objects.size();
|
||||
for (uint32 i = 0; i < groupSize ; i++) {
|
||||
GeometricObject *gobj = (GeometricObject *)_objects[i];
|
||||
if (GeometricObject::isPolygon(_objects[i]->getType())) {
|
||||
gobj->setOrigin(_origins[i]);
|
||||
gobj->restoreOrdinates();
|
||||
//gobj->makeInvisible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Group::draw(Renderer *gfx, float offset) {
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
uint32 groupSize = _objects.size();
|
||||
for (uint32 i = 0; i < groupSize ; i++) {
|
||||
if (!_objects[i]->isDestroyed() && !_objects[i]->isInvisible())
|
||||
_objects[i]->draw(gfx);
|
||||
}
|
||||
}
|
||||
|
||||
void Group::step() {
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
debugC(1, kFreescapeDebugGroup, "Stepping group %d", _objectID);
|
||||
if (_step < int(_operations.size() - 1))
|
||||
_step++;
|
||||
else {
|
||||
_active = false;
|
||||
_step = -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool Group::collides(const Math::AABB &aabb) {
|
||||
uint32 groupSize = _objects.size();
|
||||
for (uint32 i = 0; i < groupSize ; i++) {
|
||||
if (!_objects[i]->isInvisible() && !_objects[i]->isDestroyed() && _objects[i]->isDrawable()) {
|
||||
GeometricObject *gobj = (GeometricObject *)_objects[i];
|
||||
if (gobj->collides(aabb))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Group::makePartsInvisible() {
|
||||
uint32 groupSize = _objects.size();
|
||||
for (uint32 i = 0; i < groupSize ; i++) {
|
||||
_objects[i]->makeInvisible();
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Freescape
|
||||
78
engines/freescape/objects/group.h
Normal file
78
engines/freescape/objects/group.h
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FREESCAPE_GROUP_H
|
||||
#define FREESCAPE_GROUP_H
|
||||
|
||||
#include "freescape/gfx.h"
|
||||
#include "freescape/objects/object.h"
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
struct AnimationOpcode {
|
||||
AnimationOpcode(uint16 opcode_) {
|
||||
opcode = opcode_;
|
||||
}
|
||||
uint16 opcode;
|
||||
Math::Vector3d position;
|
||||
Common::String conditionSource;
|
||||
FCLInstructionVector condition;
|
||||
};
|
||||
|
||||
class Group : public Object {
|
||||
public:
|
||||
Group(uint16 objectID_, uint16 flags_,
|
||||
const Common::Array<uint16> objectIds_,
|
||||
const Math::Vector3d offset1_,
|
||||
const Math::Vector3d offset2_,
|
||||
const Common::Array<AnimationOpcode *> operations);
|
||||
~Group();
|
||||
void linkObject(Object *obj);
|
||||
void assemble(int index);
|
||||
void step();
|
||||
void run();
|
||||
void run(int index);
|
||||
void reset();
|
||||
void start();
|
||||
bool collides(const Math::AABB &aabb);
|
||||
void makePartsInvisible();
|
||||
|
||||
Common::Array<Object *> _objects;
|
||||
Common::Array<Math::Vector3d> _origins;
|
||||
Math::Vector3d _offset1;
|
||||
Math::Vector3d _offset2;
|
||||
Common::Array<AnimationOpcode *> _operations;
|
||||
Common::Array<uint16> _objectIds;
|
||||
int _scale;
|
||||
int _step;
|
||||
bool _active;
|
||||
|
||||
ObjectType getType() override { return ObjectType::kGroupType; };
|
||||
bool isDrawable() override { return true; }
|
||||
void draw(Renderer *gfx, float offset = 0.0) override;
|
||||
void scale(int scale_) override { _scale = scale_; };
|
||||
bool isActive() { return !isDestroyed() && !isInvisible() && _step > 0 && _active; };
|
||||
Object *duplicate() override;
|
||||
};
|
||||
|
||||
} // End of namespace Freescape
|
||||
|
||||
#endif // FREESCAPE_GLOBAL_H
|
||||
99
engines/freescape/objects/object.h
Normal file
99
engines/freescape/objects/object.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Based on Phantasma code by Thomas Harte (2013),
|
||||
// available at https://github.com/TomHarte/Phantasma/ (MIT)
|
||||
|
||||
#ifndef FREESCAPE_OBJECT_H
|
||||
#define FREESCAPE_OBJECT_H
|
||||
|
||||
#include "math/aabb.h"
|
||||
|
||||
#include "freescape/gfx.h"
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
enum ObjectType {
|
||||
kEntranceType = 0,
|
||||
kCubeType = 1,
|
||||
kSensorType = 2,
|
||||
kRectangleType = 3,
|
||||
|
||||
kEastPyramidType = 4,
|
||||
kWestPyramidType = 5,
|
||||
kUpPyramidType = 6,
|
||||
kDownPyramidType = 7,
|
||||
kNorthPyramidType = 8,
|
||||
kSouthPyramidType = 9,
|
||||
|
||||
kLineType = 10,
|
||||
kTriangleType = 11,
|
||||
kQuadrilateralType = 12,
|
||||
kPentagonType = 13,
|
||||
kHexagonType = 14,
|
||||
|
||||
kGroupType = 15
|
||||
};
|
||||
|
||||
class Object {
|
||||
public:
|
||||
virtual ObjectType getType() { return _type; }
|
||||
uint16 getObjectID() { return _objectID; }
|
||||
uint16 getObjectFlags() { return _flags; }
|
||||
bool isGeometric() {
|
||||
return _type != kEntranceType && _type != kGroupType && _type != kSensorType;
|
||||
}
|
||||
void setObjectFlags(uint32 flags_) { _flags = flags_; }
|
||||
Math::Vector3d getOrigin() { return _origin; }
|
||||
virtual void setOrigin(Math::Vector3d origin_) { _origin = origin_; };
|
||||
Math::Vector3d getSize() { return _size; }
|
||||
|
||||
virtual bool isDrawable() { return false; }
|
||||
virtual bool isPlanar() { return false; }
|
||||
virtual void scale(int factor) = 0;
|
||||
|
||||
bool isInvisible() { return _flags & 0x40; }
|
||||
void makeInvisible() { _flags = _flags | 0x40; }
|
||||
void makeVisible() { _flags = _flags & ~0x40; }
|
||||
bool isInitiallyInvisible() { return _flags & 0x80; }
|
||||
void makeInitiallyInvisible() { _flags = _flags | 0x80; }
|
||||
void makeInitiallyVisible() { _flags = _flags & ~0x80; }
|
||||
bool isDestroyed() { return _flags & 0x20; }
|
||||
void destroy() { _flags = _flags | 0x20; }
|
||||
void restore() { _flags = _flags & ~0x20; }
|
||||
void toggleVisibility() { _flags = _flags ^ 0x40; }
|
||||
|
||||
virtual ~Object() {}
|
||||
virtual Object *duplicate() = 0;
|
||||
|
||||
virtual void draw(Freescape::Renderer *gfx, float offset = 0.0) = 0;
|
||||
|
||||
uint16 _flags;
|
||||
ObjectType _type;
|
||||
uint16 _objectID;
|
||||
Math::Vector3d _origin, _size, _rotation;
|
||||
Math::AABB _boundingBox;
|
||||
Object *_partOfGroup = nullptr;
|
||||
};
|
||||
|
||||
} // End of namespace Freescape
|
||||
|
||||
#endif // FREESCAPE_OBJECT_H
|
||||
114
engines/freescape/objects/sensor.cpp
Normal file
114
engines/freescape/objects/sensor.cpp
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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "freescape/objects/sensor.h"
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
Sensor::Sensor(
|
||||
uint16 objectID_,
|
||||
const Math::Vector3d &origin_,
|
||||
const Math::Vector3d &rotation_,
|
||||
byte color_,
|
||||
byte firingInterval_,
|
||||
uint16 firingRange_,
|
||||
uint16 axis_,
|
||||
uint8 flags_,
|
||||
FCLInstructionVector condition_,
|
||||
Common::String conditionSource_) {
|
||||
_type = kSensorType;
|
||||
_objectID = objectID_;
|
||||
_origin = origin_;
|
||||
_rotation = rotation_;
|
||||
|
||||
if (axis_ == 0x01 || axis_ == 0x02)
|
||||
_size = Math::Vector3d(0, 3, 3);
|
||||
else if (axis_ == 0x04 || axis_ == 0x08)
|
||||
_size = Math::Vector3d(3, 0, 3);
|
||||
else if (axis_ == 0x10 || axis_ == 0x20)
|
||||
_size = Math::Vector3d(3, 3, 0);
|
||||
else
|
||||
_size = Math::Vector3d(3, 3, 3);
|
||||
_colours = new Common::Array<uint8>;
|
||||
for (int i = 0; i < 6; i++)
|
||||
_colours->push_back(color_);
|
||||
_firingInterval = firingInterval_;
|
||||
_firingRange = firingRange_;
|
||||
_axis = axis_;
|
||||
_flags = flags_;
|
||||
|
||||
if (isInitiallyInvisible())
|
||||
makeInvisible();
|
||||
else
|
||||
makeVisible();
|
||||
|
||||
_conditionSource = conditionSource_;
|
||||
_condition = condition_;
|
||||
_isShooting = false;
|
||||
}
|
||||
|
||||
void Sensor::scale(int factor) {
|
||||
_origin = _origin / factor;
|
||||
_size = _size / factor;
|
||||
}
|
||||
|
||||
Object *Sensor::duplicate() {
|
||||
Sensor *sensor = new Sensor(_objectID, _origin, _rotation, (*_colours)[0], _firingInterval, _firingRange, _axis, _flags, _condition, _conditionSource);
|
||||
return sensor;
|
||||
}
|
||||
|
||||
void Sensor::draw(Freescape::Renderer *gfx, float offset) {
|
||||
gfx->renderCube(_origin, _size, _colours, nullptr, offset);
|
||||
}
|
||||
|
||||
bool Sensor::playerDetected(const Math::Vector3d &position, Area *area) {
|
||||
if (isDestroyed() || isInvisible())
|
||||
return false;
|
||||
|
||||
Math::Vector3d diff = _origin - position;
|
||||
bool detected = false;
|
||||
|
||||
if (_axis == 0x01 && diff.x() >= 0)
|
||||
detected = true;
|
||||
else if (_axis == 0x02 && diff.x() <= 0)
|
||||
detected = true;
|
||||
else if (_axis == 0x04 && diff.y() >= 0)
|
||||
detected = true;
|
||||
else if (_axis == 0x08 && diff.y() <= 0)
|
||||
detected = true;
|
||||
else if (_axis == 0x10 && diff.z() >= 0)
|
||||
detected = true;
|
||||
else if (_axis == 0x20 && diff.z() <= 0)
|
||||
detected = true;
|
||||
|
||||
if (detected) {
|
||||
Math::Ray sight(_origin, -diff);
|
||||
detected = area->checkInSight(sight, diff.length());
|
||||
}
|
||||
|
||||
if (detected) {
|
||||
detected = ABS(diff.x() + ABS(diff.y())) + ABS(diff.z()) <= _firingRange;
|
||||
}
|
||||
|
||||
return detected;
|
||||
}
|
||||
|
||||
} // End of namespace Freescape
|
||||
77
engines/freescape/objects/sensor.h
Normal file
77
engines/freescape/objects/sensor.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Based on Phantasma code by Thomas Harte (2013),
|
||||
// available at https://github.com/TomHarte/Phantasma/ (MIT)
|
||||
|
||||
#ifndef FREESCAPE_SENSOR_H
|
||||
#define FREESCAPE_SENSOR_H
|
||||
|
||||
#include "freescape/area.h"
|
||||
#include "freescape/objects/object.h"
|
||||
#include "freescape/language/instruction.h"
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
class Sensor : public Object {
|
||||
public:
|
||||
Sensor(
|
||||
uint16 objectID_,
|
||||
const Math::Vector3d &origin_,
|
||||
const Math::Vector3d &rotation_,
|
||||
byte color_,
|
||||
byte firingInterval_,
|
||||
uint16 firingRange_,
|
||||
uint16 axis_,
|
||||
uint8 flags_,
|
||||
FCLInstructionVector condition_,
|
||||
Common::String conditionSource_);
|
||||
|
||||
byte _firingInterval;
|
||||
uint16 _firingRange;
|
||||
uint16 _axis;
|
||||
bool _isShooting;
|
||||
|
||||
Common::String _conditionSource;
|
||||
FCLInstructionVector _condition;
|
||||
|
||||
virtual ~Sensor() { delete _colours; }
|
||||
bool isDrawable() override { return true; }
|
||||
bool isPlanar() override { return true; }
|
||||
bool isShooting() { return _isShooting; }
|
||||
void scale(int factor) override;
|
||||
Object *duplicate() override;
|
||||
|
||||
ObjectType getType() override { return kSensorType; };
|
||||
Math::Vector3d getRotation() { return _rotation; }
|
||||
void shouldShoot(bool shooting) { _isShooting = shooting; }
|
||||
|
||||
void draw(Freescape::Renderer *gfx, float offset = 0.0) override;
|
||||
|
||||
bool playerDetected(const Math::Vector3d &position, Area *area);
|
||||
|
||||
private:
|
||||
Common::Array<uint8> *_colours;
|
||||
};
|
||||
|
||||
} // End of namespace Freescape
|
||||
|
||||
#endif // FREESCAPE_SENSOR_H
|
||||
Reference in New Issue
Block a user