FREESCAPE: initial parsing and rendering of group objects
This commit is contained in:
parent
e96d2199c3
commit
d0f9025cb9
9 changed files with 153 additions and 11 deletions
|
@ -226,11 +226,20 @@ void Area::draw(Freescape::Renderer *gfx) {
|
|||
assert(_drawableObjects.size() > 0);
|
||||
for (auto &obj : _drawableObjects) {
|
||||
if (!obj->isDestroyed() && !obj->isInvisible()) {
|
||||
obj->draw(gfx);
|
||||
if (obj->getType() != ObjectType::kGroupType)
|
||||
obj->draw(gfx);
|
||||
else
|
||||
drawGroup(gfx, (Group *)obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Area::drawGroup(Freescape::Renderer *gfx, Group* group) {
|
||||
for (auto &obj : group->_objects) {
|
||||
obj->draw(gfx);
|
||||
}
|
||||
}
|
||||
|
||||
Object *Area::shootRay(const Math::Ray &ray) {
|
||||
float size = 16.0 * 8192.0; // TODO: check if this is max size
|
||||
Object *collided = nullptr;
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "freescape/language/instruction.h"
|
||||
#include "freescape/objects/object.h"
|
||||
#include "freescape/objects/group.h"
|
||||
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
|
@ -50,6 +52,7 @@ public:
|
|||
void remapColor(int index, int color);
|
||||
void unremapColor(int index);
|
||||
void draw(Renderer *gfx);
|
||||
void drawGroup(Renderer *gfx, Group *group);
|
||||
void show();
|
||||
|
||||
Object *shootRay(const Math::Ray &ray);
|
||||
|
|
|
@ -286,6 +286,7 @@ public:
|
|||
// Instructions
|
||||
bool checkConditional(FCLInstruction &instruction, bool shot, bool collided, bool timer, bool activated);
|
||||
bool checkIfGreaterOrEqual(FCLInstruction &instruction);
|
||||
void executeExecute(FCLInstruction &instruction);
|
||||
void executeIncrementVariable(FCLInstruction &instruction);
|
||||
void executeDecrementVariable(FCLInstruction &instruction);
|
||||
void executeSetVariable(FCLInstruction &instruction);
|
||||
|
|
|
@ -203,6 +203,9 @@ void FreescapeEngine::executeCode(FCLInstructionVector &code, bool shot, bool co
|
|||
case Token::REDRAW:
|
||||
executeRedraw(instruction);
|
||||
break;
|
||||
case Token::EXECUTE:
|
||||
executeExecute(instruction);
|
||||
break;
|
||||
case Token::DELAY:
|
||||
executeDelay(instruction);
|
||||
break;
|
||||
|
@ -250,6 +253,12 @@ void FreescapeEngine::executeRedraw(FCLInstruction &instruction) {
|
|||
waitForSounds();
|
||||
}
|
||||
|
||||
void FreescapeEngine::executeExecute(FCLInstruction &instruction) {
|
||||
// TODO
|
||||
uint16 objId = instruction._source;
|
||||
debugC(1, kFreescapeDebugCode, "Executing instructions from object %d", objId);
|
||||
}
|
||||
|
||||
void FreescapeEngine::executeSound(FCLInstruction &instruction) {
|
||||
if (_firstSound)
|
||||
stopAllSounds();
|
||||
|
|
|
@ -277,11 +277,23 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
|
|||
|
||||
case kGroupType:
|
||||
debugC(1, kFreescapeDebugParser, "Object of type 'group'");
|
||||
file->seek(byteSizeOfObject, SEEK_CUR);
|
||||
Common::Array<uint8> groupDataArray;
|
||||
groupDataArray.push_back(uint8(position.x()));
|
||||
groupDataArray.push_back(uint8(position.y()));
|
||||
groupDataArray.push_back(uint8(position.z()));
|
||||
|
||||
groupDataArray.push_back(uint8(v.x()));
|
||||
groupDataArray.push_back(uint8(v.y()));
|
||||
groupDataArray.push_back(uint8(v.z()));
|
||||
|
||||
byteSizeOfObject++;
|
||||
while(--byteSizeOfObject > 0)
|
||||
groupDataArray.push_back(file->readByte());
|
||||
|
||||
return new Group(
|
||||
objectID,
|
||||
position,
|
||||
v);
|
||||
rawFlagsAndType,
|
||||
groupDataArray);
|
||||
break;
|
||||
}
|
||||
// Unreachable
|
||||
|
@ -486,6 +498,12 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
|
|||
debugC(1, kFreescapeDebugParser, "Reading object: %d", object);
|
||||
Object *newObject = load8bitObject(file);
|
||||
|
||||
if (newObject->getType() == ObjectType::kGroupType) {
|
||||
Group *group = (Group *)newObject;
|
||||
for (ObjectMap::iterator it = objectsByID->begin(); it != objectsByID->end(); ++it)
|
||||
group->assemble(it->_value);
|
||||
}
|
||||
|
||||
if (newObject) {
|
||||
newObject->scale(scale);
|
||||
if (newObject->getType() == kEntranceType) {
|
||||
|
|
|
@ -26,6 +26,7 @@ MODULE_OBJS := \
|
|||
movement.o \
|
||||
neo.o \
|
||||
objects/geometricobject.o \
|
||||
objects/group.o \
|
||||
objects/sensor.o \
|
||||
scr.o \
|
||||
sound.o \
|
||||
|
|
|
@ -171,6 +171,16 @@ GeometricObject::GeometricObject(
|
|||
}
|
||||
|
||||
void GeometricObject::setOrigin(Math::Vector3d origin_) {
|
||||
if (isPolygon(_type)) {
|
||||
Math::Vector3d offset = origin_ - _origin;
|
||||
offset = 32 * offset;
|
||||
for (int i = 0; i < int(_ordinates->size()); i = i + 3) {
|
||||
(*_ordinates)[i ] += uint16(offset.x());
|
||||
(*_ordinates)[i + 1] += uint16(offset.y());
|
||||
(*_ordinates)[i + 2] += uint16(offset.z());
|
||||
}
|
||||
}
|
||||
|
||||
_origin = origin_;
|
||||
computeBoundingBox();
|
||||
}
|
||||
|
|
90
engines/freescape/objects/group.cpp
Normal file
90
engines/freescape/objects/group.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* 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"
|
||||
|
||||
namespace Freescape {
|
||||
|
||||
Group::Group(uint16 objectID_, uint16 flags_, const Common::Array<byte> data_) {
|
||||
_objectID = objectID_;
|
||||
_flags = flags_;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 9; i++) {
|
||||
debugC(1, kFreescapeDebugParser, "group data[%d] = %d", i, data_[i]);
|
||||
if (data_[i] > 0)
|
||||
_objectIds.push_back(data_[i]);
|
||||
/*else
|
||||
break;*/
|
||||
}
|
||||
i = 9;
|
||||
while (i < int(data_.size())) {
|
||||
debugC(1, kFreescapeDebugParser, "group data[%d] = %d", i, data_[i]);
|
||||
|
||||
if (data_[i] >= _objectIds.size())
|
||||
break;
|
||||
|
||||
_objects.push_back(nullptr);
|
||||
//assert(data_[i] < _objectIds.size());
|
||||
_objectIndices.push_back(data_[i]);
|
||||
|
||||
debug("data[%d] = %d", i + 1, data_[i + 1]);
|
||||
debug("data[%d] = %d", i + 2, data_[i + 2]);
|
||||
debug("data[%d] = %d", i + 3, data_[i + 3]);
|
||||
Math::Vector3d position(data_[i + 1], data_[i + 2], data_[i + 3]);
|
||||
_objectPositions.push_back(position);
|
||||
|
||||
i = i + 4;
|
||||
}
|
||||
|
||||
if (isDestroyed()) // If the object is destroyed, restore it
|
||||
restore();
|
||||
|
||||
_flags = _flags & ~0x80;
|
||||
assert(!isInitiallyInvisible());
|
||||
makeVisible();
|
||||
}
|
||||
|
||||
void Group::assemble(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;
|
||||
|
||||
for (int i = 0; i < int(_objectIndices.size()) ; i++) {
|
||||
int index = _objectIndices[i];
|
||||
if (index == objectIndex) {
|
||||
Object *duplicate = obj->duplicate();
|
||||
Math::Vector3d position = _objectPositions[i];
|
||||
duplicate->setOrigin(position);
|
||||
_objects[i] = duplicate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Freescape
|
|
@ -28,15 +28,16 @@ namespace Freescape {
|
|||
|
||||
class Group : public Object {
|
||||
public:
|
||||
Group(uint16 objectID_,
|
||||
const Math::Vector3d &origin_,
|
||||
const Math::Vector3d &rotation_) {
|
||||
_objectID = objectID_;
|
||||
_origin = origin_;
|
||||
_rotation = rotation_;
|
||||
}
|
||||
Group(uint16 objectID_, uint16 flags_, const Common::Array<byte> data_);
|
||||
void assemble(Object *obj);
|
||||
|
||||
Common::Array<Object *> _objects;
|
||||
Common::Array<Math::Vector3d> _objectPositions;
|
||||
Common::Array<int16> _objectIndices;
|
||||
Common::Array<int16> _objectIds;
|
||||
|
||||
ObjectType getType() override { return ObjectType::kGroupType; };
|
||||
bool isDrawable() override { return true; }
|
||||
void draw(Freescape::Renderer *gfx) override { error("cannot render Group"); };
|
||||
void scale(int factor) override { warning("cannot scale Group"); };
|
||||
Object *duplicate() override { error("cannot duplicate Group"); };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue