aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mohawk/graphics.cpp28
-rw-r--r--engines/mohawk/graphics.h6
-rw-r--r--engines/mohawk/myst.cpp21
-rw-r--r--engines/mohawk/myst.h1
-rw-r--r--engines/mohawk/myst_scripts.cpp18
5 files changed, 61 insertions, 13 deletions
diff --git a/engines/mohawk/graphics.cpp b/engines/mohawk/graphics.cpp
index e4f9a009fd..e0dce6369a 100644
--- a/engines/mohawk/graphics.cpp
+++ b/engines/mohawk/graphics.cpp
@@ -86,6 +86,11 @@ MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : _vm(vm) {
}
_pictureFile.entries = NULL;
+
+ // Initialize our buffer
+ _mainScreen = new Graphics::Surface();
+ _mainScreen->create(_vm->_system->getWidth(), _vm->_system->getHeight(), _pixelFormat.bytesPerPixel);
+ _dirtyScreen = false;
}
MystGraphics::~MystGraphics() {
@@ -93,6 +98,9 @@ MystGraphics::~MystGraphics() {
delete _jpegDecoder;
delete _pictDecoder;
delete[] _pictureFile.entries;
+
+ _mainScreen->free();
+ delete _mainScreen;
}
static const char* picFileNames[] = {
@@ -144,7 +152,6 @@ void MystGraphics::copyImageSectionToScreen(uint16 image, Common::Rect src, Comm
Graphics::Surface *surface = NULL;
-
// Myst ME uses JPEG/PICT images instead of compressed Windows Bitmaps for room images,
// though there are a few weird ones that use that format. For further nonsense with images,
// the Macintosh version stores images in external "picture files." We check them before
@@ -210,19 +217,30 @@ void MystGraphics::copyImageSectionToScreen(uint16 image, Common::Rect src, Comm
// Convert from bitmap coordinates to surface coordinates
uint16 top = surface->h - src.top - height;
- _vm->_system->copyRectToScreen((byte *)surface->getBasePtr(src.left, top), surface->pitch, dest.left, dest.top, width, height);
+ for (uint16 i = 0; i < height; i++)
+ memcpy(_mainScreen->getBasePtr(dest.left, i + dest.top), surface->getBasePtr(src.left, top + i), width * surface->bytesPerPixel);
+
surface->free();
delete surface;
- }
- // FIXME: Remove this and update only at certain points
- _vm->_system->updateScreen();
+ // Mark the screen as dirty
+ _dirtyScreen = true;
+ }
}
void MystGraphics::copyImageToScreen(uint16 image, Common::Rect dest) {
copyImageSectionToScreen(image, Common::Rect(0, 0, 544, 333), dest);
}
+void MystGraphics::updateScreen() {
+ if (_dirtyScreen) {
+ // Only copy the buffer to the screen if it's dirty
+ _vm->_system->copyRectToScreen((byte *)_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
+ _vm->_system->updateScreen();
+ _dirtyScreen = false;
+ }
+}
+
void MystGraphics::showCursor(void) {
CursorMan.showMouse(true);
_vm->_needsUpdate = true;
diff --git a/engines/mohawk/graphics.h b/engines/mohawk/graphics.h
index 9419aad277..e44bba213b 100644
--- a/engines/mohawk/graphics.h
+++ b/engines/mohawk/graphics.h
@@ -101,6 +101,7 @@ public:
void showCursor();
void hideCursor();
void changeCursor(uint16);
+ void updateScreen();
void drawRect(Common::Rect rect, bool active);
private:
@@ -108,7 +109,6 @@ private:
MystBitmap *_bmpDecoder;
Graphics::PictDecoder *_pictDecoder;
Graphics::JPEGDecoder *_jpegDecoder;
- Graphics::PixelFormat _pixelFormat;
struct PictureFile {
uint32 pictureCount;
@@ -123,6 +123,10 @@ private:
Common::File picFile;
} _pictureFile;
+
+ Graphics::Surface *_mainScreen;
+ bool _dirtyScreen;
+ Graphics::PixelFormat _pixelFormat;
};
struct SFXERecord {
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 39c460edd5..bed917165c 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -299,9 +299,7 @@ Common::Error MohawkEngine_Myst::run() {
_resources[_curResource]->handleMouseUp();
}
- for (uint16 i = 0; i < _resources.size(); i++)
- if (_resources[i]->isEnabled())
- _resources[i]->drawDataToScreen();
+ drawResourceImages();
break;
case Common::EVENT_LBUTTONDOWN:
if (_curResource >= 0) {
@@ -450,6 +448,9 @@ void MohawkEngine_Myst::changeToCard(uint16 card) {
error("Unknown sound action %d", soundAction);
}
+ // Update the images of each area too
+ drawResourceImages();
+
// TODO: Handle Script Resources
// Run the entrance script (if present)
@@ -739,6 +740,8 @@ void MohawkEngine_Myst::runInitScript() {
for (uint16 i = 0; i < scriptCount; i++)
delete[] scripts[i].values;
delete[] scripts;
+
+ _gfx->updateScreen();
}
void MohawkEngine_Myst::runExitScript() {
@@ -792,6 +795,8 @@ void MohawkEngine_Myst::runExitScript() {
for (uint16 i = 0; i < scriptCount; i++)
delete[] scripts[i].values;
delete[] scripts;
+
+ _gfx->updateScreen();
}
void MohawkEngine_Myst::loadHelp(uint16 id) {
@@ -930,6 +935,15 @@ void MohawkEngine_Myst::setResourceEnabled(uint16 resourceId, bool enable) {
warning("Attempt to change unknown resource enable state");
}
+void MohawkEngine_Myst::drawResourceImages() {
+ for (uint16 i = 0; i < _resources.size(); i++)
+ if (_resources[i]->isEnabled())
+ _resources[i]->drawDataToScreen();
+
+ // Make sure the screen is updated
+ _gfx->updateScreen();
+}
+
static MystResource *loadResource(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent) {
uint16 type = rlstStream->readUint16LE();
@@ -1605,6 +1619,7 @@ void MystResourceType12::handleAnimation() {
// TODO: Probably not final version. Variable/Type 11 Controlled?
if (_doAnimation) {
_vm->_gfx->copyImageToScreen(_currentFrame++, _frameRect);
+ _vm->_gfx->updateScreen();
if ((_currentFrame - _firstFrame) >= _numFrames)
_doAnimation = false;
}
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index a66456e1c8..29f26704f9 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -413,6 +413,7 @@ private:
void drawResourceRects();
void checkCurrentResource();
int16 _curResource;
+ void drawResourceImages();
uint16 _cursorHintCount;
MystCursorHint *_cursorHints;
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index e397d30df3..a4b493eab4 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -381,9 +381,10 @@ void MystScriptParser::opcode_4(uint16 op, uint16 var, uint16 argc, uint16 *argv
// the general case, rather than this image blit...
uint16 var_value = _vm->_varStore->getVar(var);
if (var_value < _vm->_view.scriptResCount) {
- if (_vm->_view.scriptResources[var_value].type == 1) // TODO: Add Symbols for Types
+ if (_vm->_view.scriptResources[var_value].type == 1) { // TODO: Add Symbols for Types
_vm->_gfx->copyImageToScreen(_vm->_view.scriptResources[var_value].id, Common::Rect(0, 0, 544, 333));
- else
+ _vm->_gfx->updateScreen();
+ } else
warning("Opcode %d: Script Resource %d Type Not Image", op, var_value);
} else
warning("Opcode %d: var %d value %d outside Script Resource Range %d", op, var, var_value, _vm->_view.scriptResCount);
@@ -952,7 +953,7 @@ void MystScriptParser::opcode_35(uint16 op, uint16 var, uint16 argc, uint16 *arg
debugC(kDebugScript, "\tdelay: %d", delay);
_vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333));
- _vm->_system->updateScreen();
+ _vm->_gfx->updateScreen();
_vm->_system->delayMillis(delay * 100);
_vm->changeToCard(cardId);
} else
@@ -1685,6 +1686,7 @@ void MystScriptParser::opcode_104(uint16 op, uint16 var, uint16 argc, uint16 *ar
// TODO: Need to load the image ids from Script Resources structure of VIEW
for (uint16 imageId = 3595; imageId <= 3601; imageId++) {
_vm->_gfx->copyImageToScreen(imageId, rect);
+ _vm->_gfx->updateScreen();
_vm->_system->delayMillis(50);
}
@@ -2515,6 +2517,7 @@ void MystScriptParser::opcode_122(uint16 op, uint16 var, uint16 argc, uint16 *ar
// TODO: Need to load the image ids from Script Resources structure of VIEW
for (uint16 imageId = 3601; imageId >= 3595; imageId--) {
_vm->_gfx->copyImageToScreen(imageId, rect);
+ _vm->_gfx->updateScreen();
_vm->_system->delayMillis(50);
}
@@ -3142,8 +3145,10 @@ void MystScriptParser::opcode_200_run() {
else
rect = Common::Rect(0, 0, 544, 333);
- if (curImageIndex != lastImageIndex)
+ if (curImageIndex != lastImageIndex) {
_vm->_gfx->copyImageToScreen(g_opcode200Parameters.imageBaseId + curImageIndex, rect);
+ _vm->_gfx->updateScreen();
+ }
// TODO: Comparison with original engine shows that this simple solution
// may not be the correct one and the choice of which sound
@@ -3165,6 +3170,7 @@ void MystScriptParser::opcode_200_run() {
// Note: The modulus by 6 is because the 6th image is the one at imageBaseId
_vm->_gfx->copyImageToScreen(g_opcode200Parameters.imageBaseId + curImageIndex % 6, Common::Rect(0, 0, 544, 333));
+ _vm->_gfx->updateScreen();
_vm->_varStore->setVar(g_opcode200Parameters.var, curImageIndex + 1);
g_opcode200Parameters.lastCardTime = _vm->_system->getMillis();
@@ -3379,6 +3385,7 @@ void MystScriptParser::opcode_201(uint16 op, uint16 var, uint16 argc, uint16 *ar
case kIntroStack:
_vm->_system->delayMillis(4 * 1000);
_vm->_gfx->copyImageToScreen(4, Common::Rect(0, 0, 544, 333));
+ _vm->_gfx->updateScreen();
// TODO : Wait until video ends, then change to card 5
break;
case kSeleniticStack:
@@ -4327,6 +4334,8 @@ void MystScriptParser::opcode_211_run(void) {
lastGridState[i] = gridState[i];
}
+ _vm->_gfx->updateScreen();
+
// Var 23 contains boolean for whether pattern matches correct book pattern i.e. Pattern 158
if (gridState[0] == 0xc3 && gridState[1] == 0x6b && gridState[2] == 0xa3 &&
gridState[3] == 0x93 && gridState[4] == 0xcc && gridState[5] == 0xfa)
@@ -4656,6 +4665,7 @@ void MystScriptParser::opcode_298(uint16 op, uint16 var, uint16 argc, uint16 *ar
_vm->_system->delayMillis(20 * 1000);
for (uint16 imageId = 3001; imageId <= 3012; imageId++) {
_vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333));
+ _vm->_gfx->updateScreen();
_vm->_system->delayMillis(5 * 1000);
}
break;