mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 21:59:17 +00:00
MYST3: Implement puzzle #14, and WIP for drawing J'nanin's projectors
The zoom and blur effects are missing
This commit is contained in:
parent
81b7cff635
commit
d0de43cb1e
@ -24,6 +24,8 @@
|
||||
#include "engines/myst3/myst3.h"
|
||||
#include "engines/myst3/state.h"
|
||||
|
||||
#include "graphics/colormasks.h"
|
||||
|
||||
namespace Myst3 {
|
||||
|
||||
Movie::Movie(Myst3Engine *vm, uint16 id) :
|
||||
@ -294,4 +296,57 @@ bool SimpleMovie::update() {
|
||||
SimpleMovie::~SimpleMovie() {
|
||||
}
|
||||
|
||||
ProjectorMovie::ProjectorMovie(Myst3Engine *vm, uint16 id, Graphics::Surface *background) :
|
||||
ScriptedMovie(vm, id),
|
||||
_background(background),
|
||||
_frame(0) {
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
ProjectorMovie::~ProjectorMovie() {
|
||||
if (_frame) {
|
||||
_frame->free();
|
||||
delete _frame;
|
||||
}
|
||||
|
||||
if (_background) {
|
||||
_background->free();
|
||||
delete _background;
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectorMovie::update() {
|
||||
if (!_frame) {
|
||||
// First call, get the alpha channel from the bink file
|
||||
const Graphics::Surface *frame = _bink.decodeNextFrame();
|
||||
_frame = new Graphics::Surface();
|
||||
_frame->copyFrom(*frame);
|
||||
}
|
||||
|
||||
uint16 _backgroundX = _vm->_state->getProjectorX() / 10 - _frame->w / 2;
|
||||
uint16 _backgroundY = _vm->_state->getProjectorY() / 10 - _frame->h / 2;
|
||||
|
||||
for (uint i = 0; i < _frame->h; i++) {
|
||||
uint32 *src = (uint32 *)_background->getBasePtr(_backgroundX, _backgroundY + i);
|
||||
uint32 *dst = (uint32 *)_frame->getBasePtr(0, i);
|
||||
for (uint j = 0; j < _frame->w; j++) {
|
||||
uint8 a, r, g, b;
|
||||
|
||||
// Keep the alpha channel from the previous frame
|
||||
Graphics::colorToARGB< Graphics::ColorMasks<8888> >(*dst, a, r, g, b);
|
||||
|
||||
// Get the colors from the background
|
||||
Graphics::colorToRGB< Graphics::ColorMasks<8888> >(*src++, r, g, b);
|
||||
|
||||
// Draw the new frame
|
||||
*dst++ = Graphics::ARGBToColor< Graphics::ColorMasks<8888> >(a, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
if (_texture)
|
||||
_texture->update(_frame);
|
||||
else
|
||||
_texture = _vm->_gfx->createTexture(_frame);
|
||||
}
|
||||
|
||||
} /* namespace Myst3 */
|
||||
|
@ -79,7 +79,7 @@ public:
|
||||
virtual ~ScriptedMovie();
|
||||
|
||||
void draw();
|
||||
void update();
|
||||
virtual void update();
|
||||
|
||||
void setEndFrameVar(uint16 v) { _endFrameVar = v; }
|
||||
void setNextFrameReadVar(uint16 v) { _nextFrameReadVar = v; }
|
||||
@ -97,7 +97,7 @@ public:
|
||||
void setScriptDriven(bool b) { _scriptDriven = b; }
|
||||
void setForce2d(bool b) { _force2d = b; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
bool _enabled;
|
||||
bool _loop;
|
||||
bool _disableWhenComplete;
|
||||
@ -130,5 +130,18 @@ private:
|
||||
bool _synchronized;
|
||||
};
|
||||
|
||||
// Used by the projectors on J'nanin, see puzzle #14
|
||||
class ProjectorMovie : public ScriptedMovie {
|
||||
public:
|
||||
ProjectorMovie(Myst3Engine *vm, uint16 id, Graphics::Surface *background);
|
||||
virtual ~ProjectorMovie();
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
Graphics::Surface *_background;
|
||||
Graphics::Surface *_frame;
|
||||
};
|
||||
|
||||
} /* namespace Myst3 */
|
||||
#endif /* MOVIE_H_ */
|
||||
|
@ -54,7 +54,7 @@ Myst3Engine::Myst3Engine(OSystem *syst, int gameFlags) :
|
||||
_state(0), _node(0), _scene(0), _archiveNode(0),
|
||||
_cursor(0), _inventory(0), _gfx(0), _menu(0),
|
||||
_rnd(0), _shouldQuit(false),
|
||||
_menuAction(0) {
|
||||
_menuAction(0), _projectorBackground(0) {
|
||||
DebugMan.addDebugChannel(kDebugVariable, "Variable", "Track Variable Accesses");
|
||||
DebugMan.addDebugChannel(kDebugSaveLoad, "SaveLoad", "Track Save/Load Function");
|
||||
DebugMan.addDebugChannel(kDebugScript, "Script", "Track Script Execution");
|
||||
@ -498,7 +498,16 @@ void Myst3Engine::runScriptsFromNode(uint16 nodeID, uint32 roomID, uint32 ageID)
|
||||
}
|
||||
|
||||
void Myst3Engine::loadMovie(uint16 id, uint16 condition, bool resetCond, bool loop) {
|
||||
ScriptedMovie *movie = new ScriptedMovie(this, id);
|
||||
ScriptedMovie *movie;
|
||||
|
||||
if (!_state->getMovieUseBackground()) {
|
||||
movie = new ScriptedMovie(this, id);
|
||||
} else {
|
||||
movie = new ProjectorMovie(this, id, _projectorBackground);
|
||||
_projectorBackground = 0;
|
||||
_state->setMovieUseBackground(0);
|
||||
}
|
||||
|
||||
movie->setCondition(condition);
|
||||
movie->setDisableWhenComplete(resetCond);
|
||||
movie->setLoop(loop);
|
||||
|
@ -77,6 +77,9 @@ public:
|
||||
|
||||
Common::RandomSource *_rnd;
|
||||
|
||||
// Used by the projectors on J'nanin, see puzzle #14
|
||||
Graphics::Surface *_projectorBackground;
|
||||
|
||||
Myst3Engine(OSystem *syst, int gameFlags);
|
||||
virtual ~Myst3Engine();
|
||||
|
||||
|
@ -42,8 +42,11 @@ void Puzzles::run(uint16 id, uint16 arg0, uint16 arg1, uint16 arg3) {
|
||||
case 9:
|
||||
journalAtrus(arg0, arg1);
|
||||
break;
|
||||
case 14:
|
||||
projectorLoadBitmap(arg0);
|
||||
break;
|
||||
case 16:
|
||||
projector();
|
||||
projectorUpdateCoordinates();
|
||||
break;
|
||||
case 20:
|
||||
saveLoadMenu(arg0, arg1);
|
||||
@ -206,7 +209,36 @@ void Puzzles::saveLoadMenu(uint16 action, uint16 item) {
|
||||
}
|
||||
}
|
||||
|
||||
void Puzzles::projector() {
|
||||
static void copySurfaceRect(Graphics::Surface *dest, const Common::Point &destPoint, const Graphics::Surface *src) {
|
||||
for (uint16 i = 0; i < src->h; i++)
|
||||
memcpy(dest->getBasePtr(destPoint.x, i + destPoint.y), src->getBasePtr(0, i), src->pitch);
|
||||
}
|
||||
|
||||
void Puzzles::projectorLoadBitmap(uint16 bitmap) {
|
||||
assert(_vm->_projectorBackground == 0 && "Previous background not yet used.");
|
||||
|
||||
// This surface is freed by the destructor of the movie that uses it
|
||||
_vm->_projectorBackground = new Graphics::Surface();
|
||||
_vm->_projectorBackground->create(1024, 1024, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
||||
|
||||
const DirectorySubEntry *movieDesc = _vm->getFileDescription(0, bitmap, 0, DirectorySubEntry::kStillMovie);
|
||||
|
||||
if (!movieDesc)
|
||||
error("Movie %d does not exist", bitmap);
|
||||
|
||||
// Rebuild the complete background image from the frames of the bink movie
|
||||
Common::MemoryReadStream *movieStream = movieDesc->getData();
|
||||
Video::SeekableBinkDecoder bink;
|
||||
bink.loadStream(movieStream, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
||||
|
||||
for (uint i = 0; i < 1024; i += 256)
|
||||
for (uint j = 0; j < 1024; j += 256) {
|
||||
const Graphics::Surface *frame = bink.decodeNextFrame();
|
||||
copySurfaceRect(_vm->_projectorBackground, Common::Point(j, i), frame);
|
||||
}
|
||||
}
|
||||
|
||||
void Puzzles::projectorUpdateCoordinates() {
|
||||
int16 x = CLIP<int16>(_vm->_state->getProjectorX(), 840, 9400);
|
||||
int16 y = CLIP<int16>(_vm->_state->getProjectorY(), 840, 9400);
|
||||
int16 zoom = CLIP<int16>(_vm->_state->getProjectorZoom(), 1280, 5120);
|
||||
|
@ -1,23 +1,23 @@
|
||||
/* ResidualVM - A 3D game interpreter
|
||||
*
|
||||
* ResidualVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the AUTHORS
|
||||
* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
/* ResidualVM - A 3D game interpreter
|
||||
*
|
||||
* ResidualVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the AUTHORS
|
||||
* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PUZZLES_H_
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
#include "graphics/surface.h"
|
||||
|
||||
namespace Myst3 {
|
||||
|
||||
class Myst3Engine;
|
||||
@ -45,10 +47,11 @@ private:
|
||||
bool _journalSaavedroHasChapter(uint16 chapter);
|
||||
uint16 _journalSaavedroNextChapter(uint16 chapter, bool forward);
|
||||
|
||||
void journalAtrus(uint16 node, uint16 var);
|
||||
void mainMenu(uint16 action);
|
||||
void saveLoadMenu(uint16 action, uint16 item);
|
||||
void projector();
|
||||
void journalAtrus(uint16 node, uint16 var);
|
||||
void mainMenu(uint16 action);
|
||||
void saveLoadMenu(uint16 action, uint16 item);
|
||||
void projectorLoadBitmap(uint16 bitmap);
|
||||
void projectorUpdateCoordinates();
|
||||
};
|
||||
|
||||
} /* namespace Myst3 */
|
||||
|
@ -95,7 +95,7 @@ GameState::GameState(Myst3Engine *vm):
|
||||
VAR(172, MovieUnk172, true)
|
||||
VAR(173, MoviePlayingVar, true)
|
||||
|
||||
VAR(178, MovieUnk178, true)
|
||||
VAR(178, MovieUseBackground, false)
|
||||
|
||||
VAR(189, LocationNextNode, false)
|
||||
VAR(190, LocationNextRoom, false)
|
||||
|
@ -109,6 +109,8 @@ public:
|
||||
DECLARE_VAR(168, MovieOverridePosV)
|
||||
DECLARE_VAR(173, MoviePlayingVar)
|
||||
|
||||
DECLARE_VAR(178, MovieUseBackground)
|
||||
|
||||
DECLARE_VAR(189, LocationNextNode)
|
||||
DECLARE_VAR(190, LocationNextRoom)
|
||||
DECLARE_VAR(191, LocationNextAge)
|
||||
|
Loading…
Reference in New Issue
Block a user