[Scummvm-git-logs] scummvm master -> 9f1b8658295963017520a74dfc2c7202a22b747e
neuromancer
noreply at scummvm.org
Wed May 17 08:11:12 UTC 2023
This automated email contains information about 11 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
2e45130a70 MATH: added function to obtain size of AABBs
9ac9b0b6a4 FREESCAPE: new collision code
1fc9f7f300 FREESCAPE: remove spaces from area name when displaying info menu in driller
406ea4c395 FREESCAPE: make sure end game area is properly renderer in driller
04b70217b1 FREESCAPE: palette fixes for driller cpc
3961413046 FREESCAPE: color remap fixes for driller cpc/amiga/atari
334339c0c1 FREESCAPE: info menu fixes for driller zx/amiga/atari
783e057538 FREESCAPE: added missing items for driller cga palettes
2c33d94aca FREESCAPE: improved handling of entrance usage
3f44942adc FREESCAPE: improved handling of rise/fall
9f1b865829 FREESCAPE: initial parsing and rendering of group objects
Commit: 2e45130a70611fde552e28ba2378e5b15eff845d
https://github.com/scummvm/scummvm/commit/2e45130a70611fde552e28ba2378e5b15eff845d
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-17T10:11:20+02:00
Commit Message:
MATH: added function to obtain size of AABBs
Changed paths:
math/aabb.h
diff --git a/math/aabb.h b/math/aabb.h
index 8c80e12ef72..e49411693fe 100644
--- a/math/aabb.h
+++ b/math/aabb.h
@@ -38,6 +38,7 @@ public:
void transform(const Math::Matrix4 &matrix);
Math::Vector3d getMin() const { return _min; }
Math::Vector3d getMax() const { return _max; }
+ Math::Vector3d getSize() const { return _max - _min; }
bool isValid() const { return _valid; }
bool collides(const AABB &aabb);
Commit: 9ac9b0b6a4ff1bb00ae28e498394c38f234868c2
https://github.com/scummvm/scummvm/commit/9ac9b0b6a4ff1bb00ae28e498394c38f234868c2
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-17T10:11:20+02:00
Commit Message:
FREESCAPE: new collision code
Changed paths:
engines/freescape/area.cpp
engines/freescape/area.h
engines/freescape/freescape.h
engines/freescape/movement.cpp
diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index ac168712e88..df1339e9db4 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -258,6 +258,121 @@ ObjectArray Area::checkCollisions(const Math::AABB &boundingBox) {
return collided;
}
+float lineToPlane(Math::Vector3d const &p, Math::Vector3d const &u, Math::Vector3d const &v, Math::Vector3d const &n) {
+ float NdotU = n.dotProduct(u);
+ if (NdotU == 0)
+ return INFINITY;
+
+ return n.dotProduct(v - p) / NdotU;
+}
+
+bool between(float x, float a, float b) {
+ return x >= a && x <= b;
+}
+
+float sweepAABB(Math::AABB const &a, Math::AABB const &b, Math::Vector3d const &direction, Math::Vector3d &normal) {
+ Math::Vector3d m = b.getMin() - a.getMax();
+ Math::Vector3d mh = a.getSize() + b.getSize();
+
+ float h = 1.0;
+ float s = 0.0;
+ Math::Vector3d zero;
+
+ // X min
+ s = lineToPlane(zero, direction, m, Math::Vector3d(-1, 0, 0));
+ if (s >= 0 && direction.x() > 0 && s < h && between(s * direction.y(), m.y(), m.y()+mh.y()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
+ h = s;
+ normal = Math::Vector3d(-1, 0, 0);
+ }
+
+ // X max
+ m.x() = m.x() + mh.x();
+ s = lineToPlane(zero, direction, m, Math::Vector3d(1, 0, 0));
+ if (s >= 0 && direction.x() < 0 && s < h && between(s * direction.y(), m.y(), m.y() + mh.y()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
+ h = s;
+ normal = Math::Vector3d(1, 0, 0);
+ }
+
+ m.x() = m.x() - mh.x();
+ // Y min
+ s = lineToPlane(zero, direction, m, Math::Vector3d(0, -1, 0));
+ if (s >= 0 && direction.y() > 0 && s < h && between(s * direction.x(), m.x(), m.x() + mh.x()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
+ h = s;
+ normal = Math::Vector3d(0, -1, 0);
+ }
+
+ // Y max
+ m.y() = m.y() + mh.y();
+ s = lineToPlane(zero, direction, m, Math::Vector3d(0, 1, 0));
+ if (s >= 0 && direction.y() < 0 && s < h && between(s * direction.x(), m.x(), m.x() + mh.x()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
+ h = s;
+ normal = Math::Vector3d(0, 1, 0);
+ }
+
+ m.y() = m.y() - mh.y();
+
+ // Z min
+ s = lineToPlane(zero, direction, m, Math::Vector3d(0, 0, -1));
+ if (s >= 0 && direction.z() > 0 && s < h && between(s * direction.x(), m.x() , m.x() + mh.x()) && between(s * direction.y(), m.y(), m.y() + mh.y())) {
+ h = s;
+ normal = Math::Vector3d(0, 0, -1);
+ }
+
+ // Z max
+ m.z() = m.z() + mh.z();
+ s = lineToPlane(zero, direction, m, Math::Vector3d(0, 0, 1));
+ if (s >= 0 && direction.z() < 0 && s < h && between(s * direction.x(), m.x(), m.x() + mh.x()) && between(s * direction.y(), m.y(), m.y() + mh.y())) {
+ h = s;
+ normal = Math::Vector3d(0, 0, 1);
+ }
+
+ //debug("%f", h);
+ return h;
+}
+
+Math::AABB createPlayerAABB(Math::Vector3d const position, int playerHeight) {
+ Math::AABB boundingBox(position, position);
+
+ Math::Vector3d v1(position.x() + 1, position.y() + 1, position.z() + 1);
+ Math::Vector3d v2(position.x() - 1, position.y() - playerHeight, position.z() - 1);
+
+ boundingBox.expand(v1);
+ boundingBox.expand(v2);
+ return boundingBox;
+}
+
+Math::Vector3d Area::resolveCollisions(const Math::Vector3d &lastPosition_, const Math::Vector3d &newPosition_, int playerHeight) {
+ Math::Vector3d position = newPosition_;
+ Math::Vector3d lastPosition = lastPosition_;
+
+ float epsilon = 1.5;
+ int i = 0;
+ while (true) {
+ float distance = 1.0;
+ Math::Vector3d normal;
+ Math::Vector3d direction = position - lastPosition;
+
+ Math::AABB boundingBox = createPlayerAABB(lastPosition, playerHeight);
+ for (auto &obj : _drawableObjects) {
+ if (!obj->isDestroyed() && !obj->isInvisible()) {
+ GeometricObject *gobj = (GeometricObject *)obj;
+ Math::Vector3d collidedNormal;
+ float collidedDistance = sweepAABB(boundingBox, gobj->_boundingBox, direction, collidedNormal);
+ if (collidedDistance < distance) {
+ distance = collidedDistance;
+ normal = collidedNormal;
+ }
+ }
+ }
+ position = lastPosition + distance * direction + epsilon * normal;
+ if (distance >= 1.0)
+ break;
+ i++;
+ assert(i <= 5);
+ }
+ return position;
+}
+
bool Area::checkInSight(const Math::Ray &ray, float maxDistance) {
Math::Vector3d direction = ray.getDirection();
direction.normalize();
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 294b73a5c88..a6fa1e2fdc7 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -55,6 +55,7 @@ public:
Object *shootRay(const Math::Ray &ray);
bool checkInSight(const Math::Ray &ray, float maxDistance);
ObjectArray checkCollisions(const Math::AABB &boundingBox);
+ Math::Vector3d resolveCollisions(Math::Vector3d const &lastPosition, Math::Vector3d const &newPosition, int playerHeight);
void addObjectFromArea(int16 id, Area *global);
void addObject(Object *obj);
void addFloor();
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 97b00b2d94e..6e3d666dec9 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -225,6 +225,7 @@ public:
virtual void pressedKey(const int keycode);
virtual bool onScreenControls(Common::Point mouse);
void move(CameraMovement direction, uint8 scale, float deltaTime);
+ void resolveCollisions(Math::Vector3d newPosition);
virtual void checkIfStillInArea();
void changePlayerHeight(int index);
void increaseStepSize();
@@ -275,7 +276,7 @@ public:
Common::Array<Common::String> _conditionSources;
Common::Array<FCLInstructionVector> _conditions;
- bool checkCollisions(bool executeCode);
+ void runCollisionConditions(Math::Vector3d const lastPosition, Math::Vector3d const newPosition);
Math::Vector3d _objExecutingCodeSize;
virtual void executeMovementConditions();
void executeObjectConditions(GeometricObject *obj, bool shot, bool collided, bool activated);
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 7d89bafe446..e5245723426 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -158,7 +158,7 @@ void FreescapeEngine::rise() {
changePlayerHeight(_playerHeightNumber);
}
- bool collided = checkCollisions(true) || _position.y() >= 2016;
+ bool collided = /*checkCollisions(true) ||*/ _position.y() >= 2016;
if (collided) {
if (_currentArea->getAreaID() == previousAreaID) {
if (_flyMode)
@@ -181,7 +181,7 @@ void FreescapeEngine::lower() {
if (_flyMode) {
_position.setValue(1, _position.y() - (_playerSteps[_playerStepIndex] * 0.5));
- bool collided = checkCollisions(true);
+ bool collided = false; //checkCollisions(true);
if (collided) {
if (_currentArea->getAreaID() == previousAreaID) {
_position = _lastPosition;
@@ -222,21 +222,26 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
stepFront.z() = floor(stepFront.z()) + 0.5;
float positionY = _position.y();
+ Math::Vector3d destination;
switch (direction) {
case kForwardMovement:
- _position = _position + stepFront;
+ destination = _position + stepFront;
break;
case kBackwardMovement:
- _position = _position - stepFront;
+ destination = _position - stepFront;
break;
case kRightMovement:
- _position = _position - stepRight;
+ destination = _position - stepRight;
break;
case kLeftMovement:
- _position = _position + stepRight;
+ destination = _position + stepRight;
break;
}
+ if (!_flyMode)
+ destination.y() = positionY;
+ resolveCollisions(destination);
+ /*
// restore y coordinate
if (!_flyMode)
_position.set(_position.x(), positionY, _position.z());
@@ -306,6 +311,7 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
}
}
}
+ */
_lastPosition = _position;
debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
@@ -315,66 +321,64 @@ void FreescapeEngine::move(CameraMovement direction, uint8 scale, float deltaTim
clearGameBit(31);
}
-bool FreescapeEngine::checkFloor(Math::Vector3d currentPosition) {
- debugC(1, kFreescapeDebugMove, "Checking floor under the player");
- bool collided = checkCollisions(false);
- assert(!collided);
+void FreescapeEngine::resolveCollisions(Math::Vector3d const position) {
+ Math::Vector3d newPosition = position;
+ Math::Vector3d lastPosition = _lastPosition;
- _position.set(_position.x(), _position.y() - 2, _position.z());
- collided = checkCollisions(false);
- _position = currentPosition;
- return collided;
-}
+ int previousAreaID = _currentArea->getAreaID();
+ runCollisionConditions(lastPosition, newPosition);
+ if (_currentArea->getAreaID() != previousAreaID) {
+ return;
+ }
-bool FreescapeEngine::tryStepUp(Math::Vector3d currentPosition) {
- debugC(1, kFreescapeDebugMove, "Try to step up!");
- _position.set(_position.x(), _position.y() + 64, _position.z());
- bool collided = checkCollisions(false);
- if (collided) {
- _position = currentPosition;
- return false;
- } else {
- // Try to step down
- return true;
+ newPosition = _currentArea->resolveCollisions(lastPosition, newPosition, _playerHeight);
+
+ if (_flyMode) {
+ _position = newPosition;
+ return;
}
-}
-bool FreescapeEngine::tryStepDown(Math::Vector3d currentPosition) {
- debugC(1, kFreescapeDebugMove, "Try to step down!");
- _position.set(_position.x(), _position.y() - 1, _position.z());
- if (checkFloor(_position)) {
- return true;
- } else {
- _position = currentPosition;
- return false;
+ if ((lastPosition - newPosition).length() < 1) { // If the player has not moved
+ // Try to step up
+ newPosition = position;
+ newPosition.y() = newPosition.y() + 64;
+
+ lastPosition = _lastPosition;
+ lastPosition.y() = lastPosition.y() + 64;
+
+ newPosition = _currentArea->resolveCollisions(lastPosition, newPosition, _playerHeight);
}
-}
-bool FreescapeEngine::checkCollisions(bool executeCode) {
- if (_noClipMode)
- return false;
- Math::AABB boundingBox(_lastPosition, _lastPosition);
+ /*if ((lastPosition - newPosition).length() >= 1) { // Step up
+ playSound(4, false);
+ }*/
- Math::Vector3d v1(_position.x() + 1, _position.y() + 1, _position.z() + 1);
- Math::Vector3d v2(_position.x() - 1, _position.y() - _playerHeight, _position.z() - 1);
+ lastPosition = newPosition;
+ newPosition.y() = -8192;
+ newPosition = _currentArea->resolveCollisions(lastPosition, newPosition, _playerHeight);
+ int fallen = lastPosition.y() - newPosition.y();
- boundingBox.expand(v1);
- boundingBox.expand(v2);
- ObjectArray objs = _currentArea->checkCollisions(boundingBox);
- bool collided = !objs.empty();
+ if (fallen > 64)
+ _hasFallen = !_disableFalling;
- // If we don't need to execute code, we can finish here
- if (!executeCode) {
- return collided;
+ if (!_hasFallen && fallen > 0) {
+ // Position in Y was changed, let's re-run effects
+ runCollisionConditions(lastPosition, newPosition);
}
+ _position = newPosition;
+}
+
+void FreescapeEngine::runCollisionConditions(Math::Vector3d const lastPosition, Math::Vector3d const newPosition) {
+ if (_noClipMode)
+ return;
- // If we need to execute code, we need to make sure the bounding box touches the floor
- // so we will expand it and re-run the collision checking
- uint tolerance = 1;
- Math::Vector3d v3(_position.x() - 1, _position.y() - _playerHeight - tolerance, _position.z() - 1);
- boundingBox.expand(v3);
+ // We need to make sure the bounding box touches the floor so we will expand it and run the collision checking
+ uint tolerance = 3;
+ Math::Vector3d v(newPosition.x() - 1, newPosition.y() - _playerHeight - tolerance, newPosition.z() - 1);
+ Math::AABB boundingBox(lastPosition, lastPosition);
+ boundingBox.expand(v);
- objs = _currentArea->checkCollisions(boundingBox);
+ ObjectArray objs = _currentArea->checkCollisions(boundingBox);
// sort so the condition from those objects that are larger are executed last
struct {
@@ -393,7 +397,7 @@ bool FreescapeEngine::checkCollisions(bool executeCode) {
// The following check stops the player from going through big solid objects such as walls
// FIXME: find a better workaround of this
if (gobj->getSize().length() > 3000) {
- if (largeObjectWasBlocking)
+ if (largeObjectWasBlocking && !(isDriller() && _currentArea->getAreaID() == 14))
continue;
largeObjectWasBlocking = true;
}
@@ -403,9 +407,6 @@ bool FreescapeEngine::checkCollisions(bool executeCode) {
if (areaID != _currentArea->getAreaID())
break;
}
- // We still need to return the original result, not the collision using the expanded bounding box
- // This will avoid detecting the floor constantly
- return collided;
}
} // namespace Freescape
Commit: 1fc9f7f300b5dd4dc7c70a39ccd99c487ae1a838
https://github.com/scummvm/scummvm/commit/1fc9f7f300b5dd4dc7c70a39ccd99c487ae1a838
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-17T10:11:20+02:00
Commit Message:
FREESCAPE: remove spaces from area name when displaying info menu in driller
Changed paths:
engines/freescape/games/driller/driller.cpp
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 902354fcce9..42708de1e9f 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -245,7 +245,10 @@ void DrillerEngine::drawInfoMenu() {
_gfx->readFromPalette(color, r, g, b);
uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
- drawStringInSurface(Common::String::format("%10s : %s", "sector", _currentArea->_name.c_str()), 69, 25, front, black, surface);
+ Common::String areaName = _currentArea->_name;
+ areaName.trim();
+
+ drawStringInSurface(Common::String::format("%10s : %s", "sector", areaName.c_str()), 69, 25, front, black, surface);
Common::String rigStatus;
Common::String gasFound;
Common::String perTapped;
Commit: 406ea4c395d6893c7a63f979d27459dda06021b1
https://github.com/scummvm/scummvm/commit/406ea4c395d6893c7a63f979d27459dda06021b1
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-17T10:11:20+02:00
Commit Message:
FREESCAPE: make sure end game area is properly renderer in driller
Changed paths:
engines/freescape/games/driller/driller.cpp
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 42708de1e9f..2721262e168 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -799,9 +799,15 @@ bool DrillerEngine::checkIfGameEnded() {
insertTemporaryMessage(_messagesList[19], _countdown - 2);
_gameStateVars[32] = 0; // Avoid repeating the message
}
- drawFrame();
- _gfx->flipBuffer();
- g_system->updateScreen();
+
+ // Draw a few frames
+ for (int i = 0; i < 10; i++) {
+ drawFrame();
+ _gfx->flipBuffer();
+ g_system->updateScreen();
+ g_system->delayMillis(10);
+ }
+
g_system->delayMillis(5000);
return true;
}
Commit: 04b70217b1dc5ba4c0e97c7adbf23339eb63d7e6
https://github.com/scummvm/scummvm/commit/04b70217b1dc5ba4c0e97c7adbf23339eb63d7e6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-17T10:11:20+02:00
Commit Message:
FREESCAPE: palette fixes for driller cpc
Changed paths:
engines/freescape/games/driller/cpc.cpp
engines/freescape/games/palettes.cpp
diff --git a/engines/freescape/games/driller/cpc.cpp b/engines/freescape/games/driller/cpc.cpp
index f9d95eef943..e105189cd01 100644
--- a/engines/freescape/games/driller/cpc.cpp
+++ b/engines/freescape/games/driller/cpc.cpp
@@ -138,12 +138,12 @@ void DrillerEngine::drawCPCUI(Graphics::Surface *surface) {
_gfx->selectColorFromFourColorPalette(color, r, g, b);
uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
- color = 0;
+ color = _currentArea->_usualBackgroundColor;
if (_gfx->_colorRemaps && _gfx->_colorRemaps->contains(color)) {
color = (*_gfx->_colorRemaps)[color];
}
- _gfx->readFromPalette(color, r, g, b);
+ _gfx->selectColorFromFourColorPalette(color, r, g, b);
uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
int score = _gameStateVars[k8bitVariableScore];
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index e2fe6b8e3c8..529f8f43284 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -74,13 +74,13 @@ byte kDrillerZXPalette[9][3] = {
};
byte kDrillerCPCPalette[32][3] = {
- {0x00, 0x00, 0x00}, // 0: special case?
+ {0x80, 0x80, 0x80}, // 0: special case?
{0x11, 0x22, 0x33},
{0x80, 0xff, 0x80}, // 2
{0xff, 0xff, 0x80}, // 3
{0x11, 0x22, 0x33},
{0xff, 0x00, 0x80}, // 5
- {0x00, 0xff, 0x80}, // 6
+ {0x00, 0x80, 0x00}, // 6
{0xff, 0x80, 0x80}, // 7
{0x11, 0x22, 0x33},
{0x11, 0x22, 0x33},
Commit: 39614130466bd2a6ef939a89a498a1c937d1fb32
https://github.com/scummvm/scummvm/commit/39614130466bd2a6ef939a89a498a1c937d1fb32
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-17T10:11:20+02:00
Commit Message:
FREESCAPE: color remap fixes for driller cpc/amiga/atari
Changed paths:
engines/freescape/freescape.cpp
engines/freescape/games/driller/cpc.cpp
engines/freescape/games/driller/driller.cpp
engines/freescape/games/palettes.cpp
engines/freescape/gfx.cpp
diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index 841e33f3c00..587c9d6e500 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -278,12 +278,13 @@ void FreescapeEngine::drawFrame() {
_gfx->positionCamera(_position, _position + _cameraFront);
if (_underFireFrames > 0) {
- int underFireColor = isDriller() && isDOS() ? 1
- : _currentArea->_underFireBackgroundColor;
- if (underFireColor < 16) {
- _currentArea->remapColor(_currentArea->_usualBackgroundColor, underFireColor);
- _currentArea->remapColor(_currentArea->_skyColor, underFireColor);
- }
+ int underFireColor = _currentArea->_underFireBackgroundColor;
+
+ if (isDriller() && (isDOS() || isAmiga() || isAtariST()))
+ underFireColor = 1;
+
+ _currentArea->remapColor(_currentArea->_usualBackgroundColor, underFireColor);
+ _currentArea->remapColor(_currentArea->_skyColor, underFireColor);
}
drawBackground();
diff --git a/engines/freescape/games/driller/cpc.cpp b/engines/freescape/games/driller/cpc.cpp
index e105189cd01..79016c4c0e7 100644
--- a/engines/freescape/games/driller/cpc.cpp
+++ b/engines/freescape/games/driller/cpc.cpp
@@ -132,10 +132,10 @@ void DrillerEngine::loadAssetsCPCFullGame() {
}
void DrillerEngine::drawCPCUI(Graphics::Surface *surface) {
- uint32 color = 1;
+ uint32 color = _currentArea->_underFireBackgroundColor;
uint8 r, g, b;
- _gfx->selectColorFromFourColorPalette(color, r, g, b);
+ _gfx->readFromPalette(color, r, g, b);
uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
color = _currentArea->_usualBackgroundColor;
@@ -143,7 +143,7 @@ void DrillerEngine::drawCPCUI(Graphics::Surface *surface) {
color = (*_gfx->_colorRemaps)[color];
}
- _gfx->selectColorFromFourColorPalette(color, r, g, b);
+ _gfx->readFromPalette(color, r, g, b);
uint32 back = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
int score = _gameStateVars[k8bitVariableScore];
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 2721262e168..4eb1a81523a 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -180,8 +180,13 @@ void DrillerEngine::gotoArea(uint16 areaID, int entranceID) {
_gfx->setColorRemaps(&_currentArea->_colorRemaps);
swapPalette(areaID);
- _currentArea->_skyColor = 0;
- _currentArea->_usualBackgroundColor = 0;
+
+ if (isDOS() || isAmiga() || isAtariST()) {
+ _currentArea->_skyColor = 0;
+ _currentArea->_usualBackgroundColor = 0;
+ } else if (isCPC()) {
+ _currentArea->_skyColor = _currentArea->_usualBackgroundColor;
+ }
resetInput();
}
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 529f8f43284..0950f90e165 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -94,7 +94,7 @@ byte kDrillerCPCPalette[32][3] = {
{0x00, 0xff, 0x80}, // 17
{0x00, 0xff, 0x00}, // 18
{0x80, 0xff, 0xff}, // 19
- {0x11, 0x22, 0x33},
+ {0x00, 0x00, 0x00}, // 20
{0x00, 0x00, 0xff}, // 21
{0x00, 0x80, 0x00}, // 22
{0x00, 0x80, 0xff}, // 23
diff --git a/engines/freescape/gfx.cpp b/engines/freescape/gfx.cpp
index 5ce2d991485..530f79588d5 100644
--- a/engines/freescape/gfx.cpp
+++ b/engines/freescape/gfx.cpp
@@ -927,19 +927,12 @@ void Renderer::renderPolygon(const Math::Vector3d &origin, const Math::Vector3d
}
void Renderer::drawBackground(uint8 color) {
-
if (_colorRemaps && _colorRemaps->contains(color)) {
color = (*_colorRemaps)[color];
}
-
- byte *stipple = nullptr;
- uint8 r1, g1, b1, r2, g2, b2;
- bool render = getRGBAt(color, r1, g1, b1, r2, g2, b2, stipple);
- if (!render)
- r1 = g1 = b1 = 0;
-
- //assert(stipple == nullptr); // Unclear if this is ever used
- clear(r1, g1, b1);
+ uint8 r, g, b;
+ readFromPalette(color, r, g, b);
+ clear(r, g, b);
}
Graphics::RendererType determinateRenderType() {
Commit: 334339c0c1958976ac5f94f3ae996fd8417d4069
https://github.com/scummvm/scummvm/commit/334339c0c1958976ac5f94f3ae996fd8417d4069
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-17T10:11:20+02:00
Commit Message:
FREESCAPE: info menu fixes for driller zx/amiga/atari
Changed paths:
engines/freescape/games/driller/driller.cpp
diff --git a/engines/freescape/games/driller/driller.cpp b/engines/freescape/games/driller/driller.cpp
index 4eb1a81523a..3d4d2075e07 100644
--- a/engines/freescape/games/driller/driller.cpp
+++ b/engines/freescape/games/driller/driller.cpp
@@ -248,12 +248,18 @@ void DrillerEngine::drawInfoMenu() {
uint8 r, g, b;
_gfx->readFromPalette(color, r, g, b);
+ if (isAmiga() || isAtariST()) {
+ r = 0xFF;
+ g = 0xFF;
+ b = 0x55;
+ }
+
uint32 front = _gfx->_texturePixelFormat.ARGBToColor(0xFF, r, g, b);
Common::String areaName = _currentArea->_name;
areaName.trim();
- drawStringInSurface(Common::String::format("%10s : %s", "sector", areaName.c_str()), 69, 25, front, black, surface);
+ drawStringInSurface(Common::String::format("%10s : %s", "sector", areaName.c_str()), 59, 25, front, black, surface);
Common::String rigStatus;
Common::String gasFound;
Common::String perTapped;
@@ -284,10 +290,10 @@ void DrillerEngine::drawInfoMenu() {
break;
}
- drawStringInSurface(Common::String::format("%10s : %s", "rig status", rigStatus.c_str()), 69, 33, front, black, surface);
- drawStringInSurface(Common::String::format("%10s : %s", "gas found", gasFound.c_str()), 69, 41, front, black, surface);
- drawStringInSurface(Common::String::format("%10s : %s", "% tapped", perTapped.c_str()), 69, 49, front, black, surface);
- drawStringInSurface(Common::String::format("%10s : %s", "gas tapped", gasTapped.c_str()), 69, 57, front, black, surface);
+ drawStringInSurface(Common::String::format("%10s : %s", "rig status", rigStatus.c_str()), 59, 33, front, black, surface);
+ drawStringInSurface(Common::String::format("%10s : %s", "gas found", gasFound.c_str()), 59, 41, front, black, surface);
+ drawStringInSurface(Common::String::format("%10s : %s", "% tapped", perTapped.c_str()), 59, 49, front, black, surface);
+ drawStringInSurface(Common::String::format("%10s : %s", "gas tapped", gasTapped.c_str()), 59, 57, front, black, surface);
drawStringInSurface(Common::String::format("%13s : %d", "total sectors", 18), 84, 73, front, black, surface);
drawStringInSurface(Common::String::format("%13s : %d", "safe sectors", _gameStateVars[32]), 84, 81, front, black, surface);
@@ -298,7 +304,8 @@ void DrillerEngine::drawInfoMenu() {
} else if (isSpectrum()) {
drawStringInSurface("l-load s-save 1-abort", 76, 97, front, black, surface);
drawStringInSurface("any other key-continue", 76, 105, front, black, surface);
- }
+ } else if (isAmiga() || isAtariST())
+ drawStringInSurface("press any key to continue", 66, 97, front, black, surface);
_uiTexture->update(surface);
_gfx->setViewport(_fullscreenViewArea);
Commit: 783e05753859fc13f5088d3ff2dfc9a6c08223d3
https://github.com/scummvm/scummvm/commit/783e05753859fc13f5088d3ff2dfc9a6c08223d3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-17T10:11:21+02:00
Commit Message:
FREESCAPE: added missing items for driller cga palettes
Changed paths:
engines/freescape/games/palettes.cpp
diff --git a/engines/freescape/games/palettes.cpp b/engines/freescape/games/palettes.cpp
index 0950f90e165..f66b90ed5af 100644
--- a/engines/freescape/games/palettes.cpp
+++ b/engines/freescape/games/palettes.cpp
@@ -176,19 +176,22 @@ static const struct CGAPalettteEntry {
{10, kDrillerCGAPalettePinkBlue},
{11, kDrillerCGAPaletteRedGreen},
{12, kDrillerCGAPalettePinkBlue},
-
+ {13, kDrillerCGAPaletteRedGreen},
{14, kDrillerCGAPalettePinkBlue},
-
+ {15, kDrillerCGAPaletteRedGreen},
{16, kDrillerCGAPalettePinkBlue},
-
+ {17, kDrillerCGAPalettePinkBlue},
+ {18, kDrillerCGAPalettePinkBlue},
{19, kDrillerCGAPaletteRedGreen},
{20, kDrillerCGAPalettePinkBlue},
{21, kDrillerCGAPaletteRedGreen},
{22, kDrillerCGAPalettePinkBlue},
{23, kDrillerCGAPaletteRedGreen},
-
+ {25, kDrillerCGAPalettePinkBlue},
+ {27, kDrillerCGAPaletteRedGreen},
{28, kDrillerCGAPalettePinkBlue},
+ {31, kDrillerCGAPaletteRedGreen},
{32, kDrillerCGAPalettePinkBlue},
{127, kDrillerCGAPaletteRedGreen},
{0, 0} // This marks the end
Commit: 2c33d94acaa4c6ba0efca9395639839cc2896487
https://github.com/scummvm/scummvm/commit/2c33d94acaa4c6ba0efca9395639839cc2896487
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-17T10:11:21+02:00
Commit Message:
FREESCAPE: improved handling of entrance usage
Changed paths:
engines/freescape/language/instruction.cpp
engines/freescape/movement.cpp
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index beb817e9841..099a7744841 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -93,7 +93,7 @@ void FreescapeEngine::executeObjectConditions(GeometricObject *obj, bool shot, b
assert(obj != nullptr);
if (!obj->_conditionSource.empty()) {
_firstSound = true;
- _objExecutingCodeSize = obj->getSize();
+ _objExecutingCodeSize = collided ? obj->getSize() : Math::Vector3d();
if (collided)
debugC(1, kFreescapeDebugCode, "Executing with collision flag: %s", obj->_conditionSource.c_str());
else if (shot)
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index e5245723426..0737675a376 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -46,10 +46,10 @@ void FreescapeEngine::traverseEntrance(uint16 entranceID) {
}
_pitch = rotation.x();
- if (ABS(_objExecutingCodeSize.x()) <= ABS(_objExecutingCodeSize.z()))
- _yaw = rotation.y() - 90;
- else
+ if (_objExecutingCodeSize.length() == 0 || ABS(_objExecutingCodeSize.x()) > ABS(_objExecutingCodeSize.z()))
_yaw = rotation.y() + 90;
+ else
+ _yaw = rotation.y() - 90;
debugC(1, kFreescapeDebugMove, "entrace position: %f %f %f", _position.x(), _position.y(), _position.z());
Commit: 3f44942adc8f51e5becaab3125724708107d3cb6
https://github.com/scummvm/scummvm/commit/3f44942adc8f51e5becaab3125724708107d3cb6
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-17T10:11:21+02:00
Commit Message:
FREESCAPE: improved handling of rise/fall
Changed paths:
engines/freescape/area.cpp
engines/freescape/movement.cpp
diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index df1339e9db4..4f9605cf01f 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -330,20 +330,12 @@ float sweepAABB(Math::AABB const &a, Math::AABB const &b, Math::Vector3d const &
return h;
}
-Math::AABB createPlayerAABB(Math::Vector3d const position, int playerHeight) {
- Math::AABB boundingBox(position, position);
-
- Math::Vector3d v1(position.x() + 1, position.y() + 1, position.z() + 1);
- Math::Vector3d v2(position.x() - 1, position.y() - playerHeight, position.z() - 1);
-
- boundingBox.expand(v1);
- boundingBox.expand(v2);
- return boundingBox;
-}
+extern Math::AABB createPlayerAABB(Math::Vector3d const position, int playerHeight);
Math::Vector3d Area::resolveCollisions(const Math::Vector3d &lastPosition_, const Math::Vector3d &newPosition_, int playerHeight) {
Math::Vector3d position = newPosition_;
Math::Vector3d lastPosition = lastPosition_;
+ Math::AABB boundingBox = createPlayerAABB(lastPosition, playerHeight);
float epsilon = 1.5;
int i = 0;
@@ -352,7 +344,6 @@ Math::Vector3d Area::resolveCollisions(const Math::Vector3d &lastPosition_, cons
Math::Vector3d normal;
Math::Vector3d direction = position - lastPosition;
- Math::AABB boundingBox = createPlayerAABB(lastPosition, playerHeight);
for (auto &obj : _drawableObjects) {
if (!obj->isDestroyed() && !obj->isInvisible()) {
GeometricObject *gobj = (GeometricObject *)obj;
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 0737675a376..c297bdb8d46 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -23,6 +23,17 @@
namespace Freescape {
+Math::AABB createPlayerAABB(Math::Vector3d const position, int playerHeight) {
+ Math::AABB boundingBox(position, position);
+
+ Math::Vector3d v1(position.x() + 1, position.y() + 1, position.z() + 1);
+ Math::Vector3d v2(position.x() - 1, position.y() - playerHeight, position.z() - 1);
+
+ boundingBox.expand(v1);
+ boundingBox.expand(v2);
+ return boundingBox;
+}
+
void FreescapeEngine::gotoArea(uint16 areaID, int entranceID) {
error("Function \"%s\" not implemented", __FUNCTION__);
}
@@ -149,27 +160,26 @@ void FreescapeEngine::rise() {
debugC(1, kFreescapeDebugMove, "playerHeightNumber: %d", _playerHeightNumber);
int previousAreaID = _currentArea->getAreaID();
if (_flyMode) {
- _position.setValue(1, _position.y() + _playerSteps[_playerStepIndex]);
+ Math::Vector3d destination = _position;
+ destination.y() = destination.y() + _playerSteps[_playerStepIndex];
+ resolveCollisions(destination);
} else {
if (_playerHeightNumber == int(_playerHeights.size()) - 1)
return;
_playerHeightNumber++;
changePlayerHeight(_playerHeightNumber);
- }
- bool collided = /*checkCollisions(true) ||*/ _position.y() >= 2016;
- if (collided) {
- if (_currentArea->getAreaID() == previousAreaID) {
- if (_flyMode)
- _position = _lastPosition;
- else {
+ Math::AABB boundingBox = createPlayerAABB(_position, _playerHeight);
+ ObjectArray objs = _currentArea->checkCollisions(boundingBox);
+ bool collided = objs.size() > 0;
+ if (collided) {
+ if (_currentArea->getAreaID() == previousAreaID) {
_playerHeightNumber--;
changePlayerHeight(_playerHeightNumber);
}
}
}
-
_lastPosition = _position;
debugC(1, kFreescapeDebugMove, "new player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
executeMovementConditions();
@@ -177,16 +187,10 @@ void FreescapeEngine::rise() {
void FreescapeEngine::lower() {
debugC(1, kFreescapeDebugMove, "playerHeightNumber: %d", _playerHeightNumber);
- int previousAreaID = _currentArea->getAreaID();
-
if (_flyMode) {
- _position.setValue(1, _position.y() - (_playerSteps[_playerStepIndex] * 0.5));
- bool collided = false; //checkCollisions(true);
- if (collided) {
- if (_currentArea->getAreaID() == previousAreaID) {
- _position = _lastPosition;
- }
- }
+ Math::Vector3d destination = _position;
+ destination.y() = destination.y() - _playerSteps[_playerStepIndex];
+ resolveCollisions(destination);
} else {
if (_playerHeightNumber == 0)
return;
Commit: 9f1b8658295963017520a74dfc2c7202a22b747e
https://github.com/scummvm/scummvm/commit/9f1b8658295963017520a74dfc2c7202a22b747e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-05-17T10:11:21+02:00
Commit Message:
FREESCAPE: initial parsing and rendering of group objects
Changed paths:
A engines/freescape/objects/group.cpp
engines/freescape/area.cpp
engines/freescape/area.h
engines/freescape/freescape.h
engines/freescape/language/instruction.cpp
engines/freescape/loaders/8bitBinaryLoader.cpp
engines/freescape/module.mk
engines/freescape/objects/geometricobject.cpp
engines/freescape/objects/group.h
diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 4f9605cf01f..e1c20299fb1 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -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;
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index a6fa1e2fdc7..7b149696e2e 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -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);
diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 6e3d666dec9..299cebcfbd9 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -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);
diff --git a/engines/freescape/language/instruction.cpp b/engines/freescape/language/instruction.cpp
index 099a7744841..e040fe6492c 100644
--- a/engines/freescape/language/instruction.cpp
+++ b/engines/freescape/language/instruction.cpp
@@ -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();
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index e570d4dbb65..e5c15fc76ca 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -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) {
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index cf02372b576..3db7785ab67 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -26,6 +26,7 @@ MODULE_OBJS := \
movement.o \
neo.o \
objects/geometricobject.o \
+ objects/group.o \
objects/sensor.o \
scr.o \
sound.o \
diff --git a/engines/freescape/objects/geometricobject.cpp b/engines/freescape/objects/geometricobject.cpp
index ff74a5a3798..b754c528df3 100644
--- a/engines/freescape/objects/geometricobject.cpp
+++ b/engines/freescape/objects/geometricobject.cpp
@@ -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();
}
diff --git a/engines/freescape/objects/group.cpp b/engines/freescape/objects/group.cpp
new file mode 100644
index 00000000000..b080641418a
--- /dev/null
+++ b/engines/freescape/objects/group.cpp
@@ -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
\ No newline at end of file
diff --git a/engines/freescape/objects/group.h b/engines/freescape/objects/group.h
index 514ca33542d..270485e276b 100644
--- a/engines/freescape/objects/group.h
+++ b/engines/freescape/objects/group.h
@@ -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"); };
More information about the Scummvm-git-logs
mailing list