STARK: Add incomplete support for scrolling the scene

This commit is contained in:
Bastien Bouclet 2015-02-08 09:17:51 +01:00
parent d9217d1fe9
commit 00f63c0ce0
18 changed files with 146 additions and 32 deletions

View File

@ -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();

View File

@ -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>();
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";
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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();

View File

@ -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;

View File

@ -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());

View File

@ -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;
};
/**

View File

@ -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<int16>(position.x, 0, _maxScroll.x);
_scroll.y = CLIP<int16>(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() {
}

View File

@ -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<Layer *> _layers;
bool _canScroll;
Common::Point _scroll;
Common::Point _maxScroll;
};
} // End of namespace Stark

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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:
};

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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"