MYST3: Fix loading the left page of Saavedro's journal

And assorted jpeg loading cleanups
This commit is contained in:
Bastien Bouclet 2012-12-12 16:33:24 +01:00
parent 9face90575
commit 4ea0e2a0d9
7 changed files with 85 additions and 75 deletions

View File

@ -50,6 +50,7 @@
#include "graphics/decoders/jpeg.h"
#include "graphics/conversion.h"
#include "graphics/pixelbuffer.h"
#include "graphics/yuv_to_rgb.h"
#include "math/vector2d.h"
@ -955,10 +956,15 @@ void Myst3Engine::addSpotItem(uint16 id, uint16 condition, bool fade) {
_node->loadSpotItem(id, condition, fade);
}
void Myst3Engine::addMenuSpotItem(uint16 id, uint16 condition, const Common::Rect &rect) {
SpotItemFace *Myst3Engine::addMenuSpotItem(uint16 id, uint16 condition, const Common::Rect &rect) {
assert(_node);
_node->loadMenuSpotItem(id, condition, rect);
SpotItemFace *face = _node->loadMenuSpotItem(condition, rect);
if (id == 1)
_menu->setSaveLoadSpotItem(face);
return face;
}
void Myst3Engine::loadNodeSubtitles(uint32 id) {
@ -1020,6 +1026,27 @@ Graphics::Surface *Myst3Engine::loadTexture(uint16 id) {
return s;
}
Graphics::Surface *Myst3Engine::decodeJpeg(const DirectorySubEntry *jpegDesc) {
Common::MemoryReadStream *jpegStream = jpegDesc->getData();
Graphics::JPEGDecoder jpeg;
if (!jpeg.loadStream(*jpegStream))
error("Could not decode Myst III JPEG");
delete jpegStream;
Graphics::Surface *bitmap = new Graphics::Surface();
bitmap->create(jpeg.getComponent(1)->w, jpeg.getComponent(1)->h, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
const byte *y = (const byte *)jpeg.getComponent(1)->getBasePtr(0, 0);
const byte *u = (const byte *)jpeg.getComponent(2)->getBasePtr(0, 0);
const byte *v = (const byte *)jpeg.getComponent(3)->getBasePtr(0, 0);
YUVToRGBMan.convert444(bitmap, Graphics::YUVToRGBManager::kScaleFull, y, u, v,
bitmap->w, bitmap->h, jpeg.getComponent(1)->pitch, jpeg.getComponent(2)->pitch);
return bitmap;
}
int16 Myst3Engine::openDialog(uint16 id) {
Dialog dialog(this, id);

View File

@ -117,6 +117,7 @@ public:
const DirectorySubEntry *getFileDescription(const char* room, uint32 index, uint16 face, DirectorySubEntry::ResourceType type);
Graphics::Surface *loadTexture(uint16 id);
static Graphics::Surface *decodeJpeg(const DirectorySubEntry *jpegDesc);
void goToNode(uint16 nodeID, uint transition);
void loadNode(uint16 nodeID, uint32 roomID = 0, uint32 ageID = 0);
@ -143,7 +144,7 @@ public:
void setMovieLooping(uint16 id, bool loop);
void addSpotItem(uint16 id, uint16 condition, bool fade);
void addMenuSpotItem(uint16 id, uint16 condition, const Common::Rect &rect);
SpotItemFace *addMenuSpotItem(uint16 id, uint16 condition, const Common::Rect &rect);
void loadNodeSubtitles(uint32 id);
void addSunSpot(uint16 pitch, uint16 heading, uint16 intensity,

View File

@ -21,7 +21,6 @@
*/
#include "engines/myst3/node.h"
#include "engines/myst3/menu.h"
#include "engines/myst3/myst3.h"
#include "engines/myst3/state.h"
#include "engines/myst3/subtitles.h"
@ -29,21 +28,10 @@
#include "common/debug.h"
#include "common/rect.h"
#include "graphics/yuv_to_rgb.h"
namespace Myst3 {
void Face::setTextureFromJPEG(Graphics::JPEGDecoder *jpeg) {
_bitmap = new Graphics::Surface();
_bitmap->create(jpeg->getComponent(1)->w, jpeg->getComponent(1)->h, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
const byte *y = (const byte *)jpeg->getComponent(1)->getBasePtr(0, 0);
const byte *u = (const byte *)jpeg->getComponent(2)->getBasePtr(0, 0);
const byte *v = (const byte *)jpeg->getComponent(3)->getBasePtr(0, 0);
YUVToRGBMan.convert444(_bitmap, Graphics::YUVToRGBManager::kScaleFull, y, u, v,
_bitmap->w, _bitmap->h, jpeg->getComponent(1)->pitch, jpeg->getComponent(2)->pitch);
void Face::setTextureFromJPEG(const DirectorySubEntry *jpegDesc) {
_bitmap = Myst3Engine::decodeJpeg(jpegDesc);
_texture = _vm->_gfx->createTexture(_bitmap);
}
@ -160,15 +148,7 @@ void Node::loadSpotItem(uint16 id, uint16 condition, bool fade) {
jpegDesc->getSpotItemData().u,
jpegDesc->getSpotItemData().v);
Common::MemoryReadStream *jpegStream = jpegDesc->getData();
Graphics::JPEGDecoder jpeg;
if (!jpeg.loadStream(*jpegStream))
error("Could not decode Myst III JPEG");
spotItemFace->loadData(&jpeg);
delete jpegStream;
spotItemFace->loadData(jpegDesc);
spotItem->addFace(spotItemFace);
}
@ -176,7 +156,7 @@ void Node::loadSpotItem(uint16 id, uint16 condition, bool fade) {
_spotItems.push_back(spotItem);
}
void Node::loadMenuSpotItem(uint16 id, uint16 condition, const Common::Rect &rect) {
SpotItemFace *Node::loadMenuSpotItem(uint16 condition, const Common::Rect &rect) {
SpotItem *spotItem = new SpotItem(_vm);
spotItem->setCondition(condition);
@ -186,12 +166,11 @@ void Node::loadMenuSpotItem(uint16 id, uint16 condition, const Common::Rect &rec
SpotItemFace *spotItemFace = new SpotItemFace(_faces[0], rect.left, rect.top);
spotItemFace->initBlack(rect.width(), rect.height());
if (id == 1)
_vm->_menu->setSaveLoadSpotItem(spotItemFace);
spotItem->addFace(spotItemFace);
_spotItems.push_back(spotItem);
return spotItemFace;
}
void Node::loadSubtitles(uint32 id) {
@ -295,17 +274,9 @@ void SpotItemFace::initBlack(uint16 width, uint16 height) {
initNotDrawn(width, height);
}
void SpotItemFace::loadData(Graphics::JPEGDecoder *jpeg) {
void SpotItemFace::loadData(const DirectorySubEntry *jpegDesc) {
// Convert active SpotItem image to raw data
_bitmap = new Graphics::Surface();
_bitmap->create(jpeg->getComponent(1)->w, jpeg->getComponent(1)->h, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
const byte *y = (const byte *)jpeg->getComponent(1)->getBasePtr(0, 0);
const byte *u = (const byte *)jpeg->getComponent(2)->getBasePtr(0, 0);
const byte *v = (const byte *)jpeg->getComponent(3)->getBasePtr(0, 0);
YUVToRGBMan.convert444(_bitmap, Graphics::YUVToRGBManager::kScaleFull, y, u, v,
_bitmap->w, _bitmap->h, jpeg->getComponent(1)->pitch, jpeg->getComponent(2)->pitch);
_bitmap = Myst3Engine::decodeJpeg(jpegDesc);
initNotDrawn(_bitmap->w, _bitmap->h);
}

View File

@ -29,13 +29,13 @@
#include "common/rect.h"
#include "graphics/surface.h"
#include "graphics/decoders/jpeg.h"
namespace Myst3 {
class Texture;
class Myst3Engine;
class Subtitles;
class DirectorySubEntry;
class Face {
public:
@ -45,7 +45,7 @@ class Face {
Face(Myst3Engine *vm);
~Face();
void setTextureFromJPEG(Graphics::JPEGDecoder *jpeg);
void setTextureFromJPEG(const DirectorySubEntry *jpegDesc);
void markTextureDirty() { _textureDirty = true; }
void uploadTexture();
@ -61,7 +61,7 @@ class SpotItemFace {
~SpotItemFace();
void initBlack(uint16 width, uint16 height);
void loadData(Graphics::JPEGDecoder *jpeg);
void loadData(const DirectorySubEntry *jpegDesc);
void updateData(const Graphics::Surface *surface);
void clear();
@ -136,7 +136,7 @@ class Node : Drawable {
void drawOverlay();
void loadSpotItem(uint16 id, uint16 condition, bool fade);
void loadMenuSpotItem(uint16 id, uint16 condition, const Common::Rect &rect);
SpotItemFace *loadMenuSpotItem(uint16 condition, const Common::Rect &rect);
void loadSubtitles(uint32 id);
bool hasSubtitlesToDraw();

View File

@ -36,19 +36,9 @@ NodeCube::NodeCube(Myst3Engine *vm, uint16 id) :
if (!jpegDesc)
error("Face %d does not exist", id);
Common::MemoryReadStream *jpegStream = jpegDesc->getData();
if (jpegStream) {
Graphics::JPEGDecoder jpeg;
if (!jpeg.loadStream(*jpegStream))
error("Could not decode Myst III JPEG");
_faces[i] = new Face(_vm);
_faces[i]->setTextureFromJPEG(&jpeg);
_faces[i]->markTextureDirty();
delete jpegStream;
}
_faces[i] = new Face(_vm);
_faces[i]->setTextureFromJPEG(jpegDesc);
_faces[i]->markTextureDirty();
}
}

View File

@ -41,19 +41,9 @@ NodeFrame::NodeFrame(Myst3Engine *vm, uint16 id) :
if (!jpegDesc)
error("Frame %d does not exist", id);
Common::MemoryReadStream *jpegStream = jpegDesc->getData();
if (jpegStream) {
Graphics::JPEGDecoder jpeg;
if (!jpeg.loadStream(*jpegStream))
error("Could not decoder Myst III JPEG");
_faces[0] = new Face(_vm);
_faces[0]->setTextureFromJPEG(&jpeg);
_faces[0]->markTextureDirty();
delete jpegStream;
}
_faces[0] = new Face(_vm);
_faces[0]->setTextureFromJPEG(jpegDesc);
_faces[0]->markTextureDirty();
}
NodeFrame::~NodeFrame() {

View File

@ -1108,25 +1108,56 @@ void Puzzles::journalSaavedro(int16 move) {
}
uint16 nodeRight;
//uint16 nodeLeft;
uint16 nodeLeft;
if (page || !chapter) {
nodeRight = chapterStartNode + page;
//nodeLeft = chapterStartNode + page;
nodeLeft = chapterStartNode + page;
} else {
nodeRight = chapterStartNode + page;
/*uint16 chapterLeft = _journalSaavedroNextChapter(chapter, false);
uint16 chapterLeft = _journalSaavedroNextChapter(chapter, false);
if (chapterLeft > 0)
nodeLeft = _journalSaavedroGetNode(chapterLeft + 1);
else
nodeLeft = 2;*/
nodeLeft = 201;
}
_vm->_state->setJournalSaavedroClosed(closed);
_vm->_state->setJournalSaavedroOpen(opened);
_vm->_state->setJournalSaavedroLastPage(lastPage);
// TODO: Draw nodeLeft on the left part of the screen
_vm->loadNodeFrame(nodeRight);
// Does the left page need to be loaded from a different node?
if (nodeLeft != nodeRight) {
const DirectorySubEntry *jpegDesc = _vm->getFileDescription(0, nodeLeft, 0, DirectorySubEntry::kFrame);
if (!jpegDesc)
error("Frame %d does not exist", nodeLeft);
Graphics::Surface *bitmap = Myst3Engine::decodeJpeg(jpegDesc);
// Copy the left half of the node to a new surface
Graphics::Surface *leftBitmap = new Graphics::Surface();
leftBitmap->create(bitmap->w / 2, bitmap->h, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
for (uint i = 0; i < bitmap->h; i++) {
memcpy(leftBitmap->getBasePtr(0, i),
bitmap->getBasePtr(0, i),
leftBitmap->w * 4);
}
bitmap->free();
delete bitmap;
// Create a spotitem covering the left half of the screen
// to display the left page
SpotItemFace *leftPage = _vm->addMenuSpotItem(999, 1, Common::Rect(0, 0, bitmap->w, bitmap->h));
leftPage->updateData(leftBitmap);
leftBitmap->free();
delete leftBitmap;
}
}
}