diff --git a/engines/stark/gfx/opengl.cpp b/engines/stark/gfx/opengl.cpp index 8ee276ce3d1..59f48a83e6f 100644 --- a/engines/stark/gfx/opengl.cpp +++ b/engines/stark/gfx/opengl.cpp @@ -101,13 +101,14 @@ void OpenGLGfxDriver::drawSurface(const Graphics::Surface *surface, Common::Poin if (rect.isEmpty()) rect = Common::Rect(surface->w, surface->h); - dest.y += 36; // 36px is the height of the top black border + dest += Common::Point(0, 36); // Top border start2DMode(); - float rasterX = (2 * (float)dest.x / (float)_screenWidth); - float rasterY = (2 * (float)dest.y / (float)_screenHeight); - glRasterPos2f(-1.0f + rasterX, 1.0f - rasterY); + glDisable(GL_TEXTURE_2D); + + glRasterPos2f(-1.0, 1.0); + glBitmap(0, 0, 0, 0, dest.x, -dest.y, nullptr); glDrawPixels(surface->w, surface->h, GL_RGBA, GL_UNSIGNED_BYTE, surface->getPixels()); //glBegin(GL_QUADS); glVertex3i(-1, -1, -1); glVertex3i(1, -1, -1); glVertex3i(1, 1, -1); glVertex3i(-1, 1, -1); glEnd(); diff --git a/engines/stark/resources/camera.cpp b/engines/stark/resources/camera.cpp index e06706ea763..bdc78fa4dcb 100644 --- a/engines/stark/resources/camera.cpp +++ b/engines/stark/resources/camera.cpp @@ -24,6 +24,7 @@ #include "engines/stark/debug.h" #include "engines/stark/formats/xrc.h" +#include "engines/stark/resources/location.h" #include "engines/stark/scene.h" #include "engines/stark/services/services.h" @@ -51,15 +52,27 @@ void Camera::readData(XRCReadStream *stream) { _lookDirection = stream->readVector3(); _f1 = stream->readFloat(); _fov = stream->readFloat(); - _viewport = stream->readRect(); + _viewSize = stream->readRect(); _v4 = stream->readVector3(); } +void Camera::onAllLoaded() { + Resource::onAllLoaded(); + + // Compute scroll coordinates bounds + Common::Point maxScroll; + maxScroll.x = _viewSize.width() - 640; + maxScroll.y = _viewSize.height() - 365; + + Location *location = findParent(); + location->initScroll(maxScroll); +} + void Camera::onEnterLocation() { Resource::onEnterLocation(); Scene *scene = StarkServices::instance().scene; - scene->initCamera(_position, _lookDirection, _fov, _viewport, _nearClipPlane, _farClipPlane); + scene->initCamera(_position, _lookDirection, _fov, _viewSize, _nearClipPlane, _farClipPlane); } void Camera::printData() { @@ -68,7 +81,7 @@ void Camera::printData() { debug << "lookDirection: " << _lookDirection << "\n"; debug << "f1: " << _f1 << "\n"; debug << "fov: " << _fov << "\n"; - debug << "viewport:" << _viewport.left << _viewport.top << _viewport.right << _viewport.bottom << "\n"; + debug << "viewSize:" << _viewSize.left << _viewSize.top << _viewSize.right << _viewSize.bottom << "\n"; debug << "v4: " << _v4 << "\n"; } diff --git a/engines/stark/resources/camera.h b/engines/stark/resources/camera.h index ac229f20aaa..b0de6219f95 100644 --- a/engines/stark/resources/camera.h +++ b/engines/stark/resources/camera.h @@ -48,6 +48,7 @@ public: virtual ~Camera(); // Resource API + void onAllLoaded() override; void onEnterLocation() override; /** Define the near and far clip planes distances */ @@ -61,7 +62,7 @@ protected: Math::Vector3d _lookDirection; float _f1; float _fov; - Common::Rect _viewport; + Common::Rect _viewSize; Math::Vector3d _v4; float _nearClipPlane; diff --git a/engines/stark/resources/image.cpp b/engines/stark/resources/image.cpp index 452f50d0027..0d38f37e048 100644 --- a/engines/stark/resources/image.cpp +++ b/engines/stark/resources/image.cpp @@ -145,7 +145,10 @@ void ImageSub23::initVisual() { Common::ReadStream *stream = archiveLoader->getFile(_filename, _archiveName); - _visual = VisualImageXMG::load(stream); + VisualImageXMG *xmg = VisualImageXMG::load(stream); + xmg->setHotSpot(_hotspot); + + _visual = xmg; delete stream; } diff --git a/engines/stark/resources/item.cpp b/engines/stark/resources/item.cpp index faa07cab4a7..acd3837d58e 100644 --- a/engines/stark/resources/item.cpp +++ b/engines/stark/resources/item.cpp @@ -81,7 +81,7 @@ void Item::setEnabled(bool enabled) { _enabled = enabled; } -RenderEntry *Item::getRenderEntry() { +RenderEntry *Item::getRenderEntry(const Common::Point &positionOffset) { return nullptr; } @@ -374,12 +374,12 @@ void ItemSub56::readData(XRCReadStream *stream) { _position = stream->readPoint(); } -RenderEntry *ItemSub56::getRenderEntry() { +RenderEntry *ItemSub56::getRenderEntry(const Common::Point &positionOffset) { if (_enabled) { Visual *visual = getVisual(); _renderEntry->setVisual(visual); - _renderEntry->setPosition(_position); + _renderEntry->setPosition(_position - positionOffset); _renderEntry->setSortKey(getSortKey()); } else { _renderEntry->setVisual(nullptr); @@ -409,12 +409,12 @@ void ItemSub78::readData(XRCReadStream *stream) { _reference = stream->readResourceReference(); } -RenderEntry *ItemSub78::getRenderEntry() { +RenderEntry *ItemSub78::getRenderEntry(const Common::Point &positionOffset) { if (_enabled) { Visual *visual = getVisual(); _renderEntry->setVisual(visual); - _renderEntry->setPosition(_position); + _renderEntry->setPosition(_position - positionOffset); } else { _renderEntry->setVisual(nullptr); } @@ -522,7 +522,7 @@ TextureSet *ItemSub10::findTextureSet(uint32 textureType) { return textureSet; } -RenderEntry *ItemSub10::getRenderEntry() { +RenderEntry *ItemSub10::getRenderEntry(const Common::Point &positionOffset) { if (_enabled) { Visual *visual = getVisual(); diff --git a/engines/stark/resources/item.h b/engines/stark/resources/item.h index 3d93f03efda..692af4a4fca 100644 --- a/engines/stark/resources/item.h +++ b/engines/stark/resources/item.h @@ -78,7 +78,7 @@ public: virtual void setEnabled(bool enabled); /** Obtain the render entry to use to display the item */ - virtual RenderEntry *getRenderEntry(); + virtual RenderEntry *getRenderEntry(const Common::Point &positionOffset); /** Obtain the concrete instance of an item template */ virtual Item *getSceneInstance(); @@ -246,7 +246,7 @@ public: virtual void readData(XRCReadStream *stream) override; // Item API - RenderEntry *getRenderEntry() override; + RenderEntry *getRenderEntry(const Common::Point &positionOffset) override; protected: void printData() override; @@ -270,7 +270,7 @@ public: void onEnterLocation() override; // Item API - RenderEntry *getRenderEntry(); + RenderEntry *getRenderEntry(const Common::Point &positionOffset) override; BonesMesh *findBonesMesh(); TextureSet *findTextureSet(uint32 textureType); @@ -300,7 +300,7 @@ public: virtual void readData(XRCReadStream *stream) override; // Item API - RenderEntry *getRenderEntry() override; + RenderEntry *getRenderEntry(const Common::Point &positionOffset) override; protected: void printData() override; diff --git a/engines/stark/resources/layer.cpp b/engines/stark/resources/layer.cpp index 5f2cc2ed97e..8b92951d493 100644 --- a/engines/stark/resources/layer.cpp +++ b/engines/stark/resources/layer.cpp @@ -47,7 +47,7 @@ Layer::~Layer() { Layer::Layer(Resource *parent, byte subType, uint16 index, const Common::String &name) : Resource(parent, subType, index, name), _scrollScale(1.0), - _field_50(1) { + _enabled(true) { _type = TYPE; } @@ -59,7 +59,13 @@ void Layer::readData(XRCReadStream *stream) { void Layer::printData() { debug("scrollScale: %f", _scrollScale); - debug("field_50: %d", _field_50); + debug("enabled: %d", _enabled); +} + +void Layer::setScrollPosition(const Common::Point &position) { + // The location scroll position is scaled to create a parallax effect + _scroll.x = (_scrollScale + 1.0) * (float) position.x; + _scroll.y = (_scrollScale + 1.0) * (float) position.y; } Layer2D::~Layer2D() { @@ -78,7 +84,7 @@ void Layer2D::readData(XRCReadStream *stream) { _itemIndices.push_back(itemIndex); } - _field_50 = stream->readUint32LE(); + _enabled = stream->readBool(); } void Layer2D::onEnterLocation() { @@ -114,7 +120,7 @@ RenderEntryArray Layer2D::listRenderEntries() { for (uint i = 0; i < _items.size(); i++) { Item *item = _items[i]; - RenderEntry *renderEntry = item->getRenderEntry(); + RenderEntry *renderEntry = item->getRenderEntry(_scroll); if (!renderEntry) { // warning("No render entry for item '%s'", item->getName().c_str()); @@ -169,7 +175,7 @@ RenderEntry *Layer3D::getBackgroundRenderEntry() { return nullptr; } - return _backgroundItem->getRenderEntry(); + return _backgroundItem->getRenderEntry(_scroll); } RenderEntryArray Layer3D::listRenderEntries() { @@ -179,7 +185,7 @@ RenderEntryArray Layer3D::listRenderEntries() { Item *item = _items[i]; if (item->getSubType() != Item::kItemSub8) { - RenderEntry *renderEntry = item->getRenderEntry(); + RenderEntry *renderEntry = item->getRenderEntry(_scroll); if (!renderEntry) { // warning("No render entry for item '%s'", item->getName().c_str()); diff --git a/engines/stark/resources/layer.h b/engines/stark/resources/layer.h index 2f2a733681b..1439c6b378e 100644 --- a/engines/stark/resources/layer.h +++ b/engines/stark/resources/layer.h @@ -63,11 +63,15 @@ public: /** Obtain the render entries for all items, including the background */ virtual RenderEntryArray listRenderEntries() = 0; + /** Scroll the layer to the specified position */ + void setScrollPosition(const Common::Point &position); + protected: void printData() override; + Common::Point _scroll; float _scrollScale; // Used for the parallax effect - uint _field_50; + bool _enabled; }; /** diff --git a/engines/stark/resources/location.cpp b/engines/stark/resources/location.cpp index 41515eb46df..413a13ec57f 100644 --- a/engines/stark/resources/location.cpp +++ b/engines/stark/resources/location.cpp @@ -24,6 +24,8 @@ #include "engines/stark/formats/xrc.h" #include "engines/stark/resources/layer.h" +#include "engines/stark/scene.h" +#include "engines/stark/services/services.h" namespace Stark { @@ -31,7 +33,8 @@ Location::~Location() { } Location::Location(Resource *parent, byte subType, uint16 index, const Common::String &name) : - Resource(parent, subType, index, name) { + Resource(parent, subType, index, name), + _canScroll(false) { _type = TYPE; } @@ -56,6 +59,33 @@ RenderEntryArray Location::listRenderEntries() { return renderEntries; } +void Location::initScroll(const Common::Point &maxScroll) { + _maxScroll = maxScroll; + _canScroll = _maxScroll.x != 0 || _maxScroll.y != 0; +} + +Common::Point Location::getScrollPosition() const { + return _scroll; +} + +void Location::setScrollPosition(const Common::Point &position) { + Scene *scene = StarkServices::instance().scene; + + _scroll.x = CLIP(position.x, 0, _maxScroll.x); + _scroll.y = CLIP(position.y, 0, _maxScroll.y); + + + // Setup the layers scroll position + for (uint i = 0; i < _layers.size(); i++) { + _layers[i]->setScrollPosition(_scroll); + } + + // Reconfigure the camera + Common::Rect viewport(640, 365); + viewport.translate(_scroll.x, _scroll.y); + scene->scrollCamera(viewport); +} + void Location::printData() { } diff --git a/engines/stark/resources/location.h b/engines/stark/resources/location.h index fb6655cb0a0..d36d51d04ae 100644 --- a/engines/stark/resources/location.h +++ b/engines/stark/resources/location.h @@ -23,6 +23,7 @@ #ifndef STARK_RESOURCES_LOCATION_H #define STARK_RESOURCES_LOCATION_H +#include "common/rect.h" #include "common/str.h" #include "engines/stark/gfx/renderentry.h" @@ -55,11 +56,24 @@ public: /** Obtain a list of render entries for all the items in the location */ RenderEntryArray listRenderEntries(); + /** Initialize scrolling from Camera data */ + void initScroll(const Common::Point &maxScroll); + + /** Obtain the current scroll position */ + Common::Point getScrollPosition() const; + + /** Scroll the location to the specified position if possible */ + void setScrollPosition(const Common::Point &position); + protected: void printData() override; private: Common::Array _layers; + + bool _canScroll; + Common::Point _scroll; + Common::Point _maxScroll; }; } // End of namespace Stark diff --git a/engines/stark/scene.cpp b/engines/stark/scene.cpp index a43dde2e1a7..37cf6785adf 100644 --- a/engines/stark/scene.cpp +++ b/engines/stark/scene.cpp @@ -38,15 +38,19 @@ Scene::~Scene() { } void Scene::initCamera(const Math::Vector3d &position, const Math::Vector3d &lookDirection, - float fov, Common::Rect viewport, float nearClipPlane, float farClipPlane) { + float fov, Common::Rect viewSize, float nearClipPlane, float farClipPlane) { _cameraPosition = position; _cameraLookDirection = lookDirection; _fov = fov; - _viewport = viewport; + _viewSize = viewSize; _nearClipPlane = nearClipPlane; _farClipPlane = farClipPlane; } +void Scene::scrollCamera(const Common::Rect &viewport) { + _viewport = viewport; +} + void Scene::render(RenderEntryArray renderEntries) { // setup cam _gfx->setupPerspective(_fov, _nearClipPlane, _farClipPlane); diff --git a/engines/stark/scene.h b/engines/stark/scene.h index 2103fac84f2..cc26b874907 100644 --- a/engines/stark/scene.h +++ b/engines/stark/scene.h @@ -50,7 +50,10 @@ public: void render(RenderEntryArray renderEntries); void initCamera(const Math::Vector3d &position, const Math::Vector3d &lookAt, - float fov, Common::Rect viewport, float nearClipPlane, float farClipPlane); + float fov, Common::Rect viewSize, float nearClipPlane, float farClipPlane); + + /** Configure rendering so that only the specified rect can be seen */ + void scrollCamera(const Common::Rect &viewport); private: GfxDriver *_gfx; @@ -58,6 +61,7 @@ private: Math::Vector3d _cameraPosition; Math::Vector3d _cameraLookDirection; float _fov; + Common::Rect _viewSize; Common::Rect _viewport; float _nearClipPlane; float _farClipPlane; diff --git a/engines/stark/services/userinterface.cpp b/engines/stark/services/userinterface.cpp index 88b837876ca..68b230808fd 100644 --- a/engines/stark/services/userinterface.cpp +++ b/engines/stark/services/userinterface.cpp @@ -59,4 +59,20 @@ void UserInterface::skipCurrentSpeeches() { } } +void UserInterface::scrollLocation(int32 dX, int32 dY) { + Global *global = StarkServices::instance().global; + Current *current = global->getCurrent(); + + if (!current) { + return; // No current location, nothing to do + } + + Location *location = current->getLocation(); + + Common::Point scroll = location->getScrollPosition(); + scroll.x += dX; + scroll.y += dY; + location->setScrollPosition(scroll); +} + } // End of namespace Stark diff --git a/engines/stark/services/userinterface.h b/engines/stark/services/userinterface.h index 03fa00d9d0e..13453b29d6f 100644 --- a/engines/stark/services/userinterface.h +++ b/engines/stark/services/userinterface.h @@ -23,6 +23,8 @@ #ifndef STARK_SERVICES_USER_INTERFACE_H #define STARK_SERVICES_USER_INTERFACE_H +#include "common/scummsys.h" + namespace Stark { /** @@ -36,6 +38,9 @@ public: /** Skip currently playing speeches */ void skipCurrentSpeeches(); + /** Scroll the current location by an offset */ + void scrollLocation(int32 dX, int32 dY); + private: }; diff --git a/engines/stark/stark.cpp b/engines/stark/stark.cpp index a0beb3214cb..d029fb623b9 100644 --- a/engines/stark/stark.cpp +++ b/engines/stark/stark.cpp @@ -146,6 +146,8 @@ void StarkEngine::mainLoop() { } else if (e.type == Common::EVENT_LBUTTONUP) { _userInterface->skipCurrentSpeeches(); + } else if (e.type == Common::EVENT_MOUSEMOVE) { + _userInterface->scrollLocation(e.relMouse.x, e.relMouse.y); } /*if (event.type == Common::EVENT_KEYDOWN || event.type == Common::EVENT_KEYUP) { handleControls(event.type, event.kbd.keycode, event.kbd.flags, event.kbd.ascii); diff --git a/engines/stark/visual/image.cpp b/engines/stark/visual/image.cpp index f9d5be90c57..5e1bc5fb1f8 100644 --- a/engines/stark/visual/image.cpp +++ b/engines/stark/visual/image.cpp @@ -30,6 +30,8 @@ #include "engines/stark/debug.h" #include "engines/stark/formats/xmg.h" #include "engines/stark/gfx/driver.h" +#include "engines/stark/scene.h" +#include "engines/stark/services/services.h" namespace Stark { @@ -45,6 +47,10 @@ VisualImageXMG::~VisualImageXMG() { delete _surface; } +void VisualImageXMG::setHotSpot(const Common::Point &hotspot) { + _hotspot = hotspot; +} + VisualImageXMG *VisualImageXMG::load(Common::ReadStream *stream) { // Create the element to return VisualImageXMG *element = new VisualImageXMG(); @@ -56,8 +62,7 @@ VisualImageXMG *VisualImageXMG::load(Common::ReadStream *stream) { } void VisualImageXMG::render(GfxDriver *gfx, const Common::Point &position) { - // Draw the current element - gfx->drawSurface(_surface, position); + gfx->drawSurface(_surface, position - _hotspot); } } // End of namespace Stark diff --git a/engines/stark/visual/image.h b/engines/stark/visual/image.h index 29db5701ed7..8c0afa5d70c 100644 --- a/engines/stark/visual/image.h +++ b/engines/stark/visual/image.h @@ -47,8 +47,12 @@ public: static VisualImageXMG *load(Common::ReadStream *stream); void render(GfxDriver *gfx, const Common::Point &position); + /** Set an offset used when rendering */ + void setHotSpot(const Common::Point &hotspot); + private: Graphics::Surface *_surface; + Common::Point _hotspot; }; } // End of namespace Stark diff --git a/engines/stark/visual/smacker.cpp b/engines/stark/visual/smacker.cpp index 12131d017a1..56934fd8b81 100644 --- a/engines/stark/visual/smacker.cpp +++ b/engines/stark/visual/smacker.cpp @@ -23,6 +23,8 @@ #include "engines/stark/visual/smacker.h" #include "engines/stark/gfx/driver.h" +#include "engines/stark/scene.h" +#include "engines/stark/services/services.h" #include "common/str.h" #include "common/archive.h"