aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2014-09-03 22:09:50 -0400
committerPaul Gilbert2014-09-03 22:09:50 -0400
commit82b2b2d65d0398cb1f3a17f421cbf78f52286faa (patch)
tree6926e98ede2ef29bdf89b3ccc08755da8a0a7fd7
parent4be8aa8906d1fd72826efcf138f62de5b8cd39b1 (diff)
downloadscummvm-rg350-82b2b2d65d0398cb1f3a17f421cbf78f52286faa.tar.gz
scummvm-rg350-82b2b2d65d0398cb1f3a17f421cbf78f52286faa.tar.bz2
scummvm-rg350-82b2b2d65d0398cb1f3a17f421cbf78f52286faa.zip
MADS: Properly implement drawing to a subset of the screen
-rw-r--r--engines/mads/messages.cpp3
-rw-r--r--engines/mads/msurface.h3
-rw-r--r--engines/mads/nebular/dialogs_nebular.cpp30
-rw-r--r--engines/mads/nebular/dialogs_nebular.h2
-rw-r--r--engines/mads/nebular/menu_nebular.cpp8
-rw-r--r--engines/mads/scene.cpp10
-rw-r--r--engines/mads/scene.h2
-rw-r--r--engines/mads/screen.cpp50
-rw-r--r--engines/mads/screen.h24
-rw-r--r--engines/mads/sprites.cpp2
10 files changed, 82 insertions, 52 deletions
diff --git a/engines/mads/messages.cpp b/engines/mads/messages.cpp
index d41696044b..e83b69d210 100644
--- a/engines/mads/messages.cpp
+++ b/engines/mads/messages.cpp
@@ -546,8 +546,7 @@ void TextDisplayList::draw(MSurface *s) {
for (uint idx = 0; idx < size(); ++idx) {
TextDisplay &td = (*this)[idx];
if (td._active && (td._expire >= 0)) {
- Common::Point destPos(td._bounds.left + _vm->_screen._offset.x,
- td._bounds.top + _vm->_screen._offset.y);
+ Common::Point destPos(td._bounds.left, td._bounds.top);
td._font->setColors(0xFF, td._color1, td._color2, 0);
td._font->writeString(s, td._msg, destPos, td._spacing, td._bounds.width());
}
diff --git a/engines/mads/msurface.h b/engines/mads/msurface.h
index cd6bde1271..3a5bf22eed 100644
--- a/engines/mads/msurface.h
+++ b/engines/mads/msurface.h
@@ -51,10 +51,9 @@ struct SpriteInfo {
* MADS graphics surface
*/
class MSurface : public Graphics::Surface {
-private:
- bool _freeFlag;
protected:
static MADSEngine *_vm;
+ bool _freeFlag;
public:
/**
* Sets the engine refrence used all surfaces
diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp
index 5b0fb7b538..ff119536ec 100644
--- a/engines/mads/nebular/dialogs_nebular.cpp
+++ b/engines/mads/nebular/dialogs_nebular.cpp
@@ -346,7 +346,6 @@ void DialogsNebular::showScummVMSaveDialog() {
}
scene->_spriteSlots.reset();
- _vm->_screen._offset.y = 0;
scene->loadScene(scene->_currentSceneId, game._aaName, true);
scene->_userInterface.noInventoryAnim();
game._scene.drawElements(kTransitionFadeIn, false);
@@ -560,7 +559,8 @@ FullScreenDialog::FullScreenDialog(MADSEngine *vm) : _vm(vm) {
}
FullScreenDialog::~FullScreenDialog() {
- _vm->_screen._offset.y = 0;
+ _vm->_screen.resetClipBounds();
+ _vm->_game->_scene.restrictScene();
}
void FullScreenDialog::display() {
@@ -577,7 +577,6 @@ void FullScreenDialog::display() {
scene._currentSceneId = currentSceneId;
scene._nextSceneId = nextSceneId;
- _vm->_screen._offset.y = 22;
_vm->_events->initVars();
game._kernelMode = KERNEL_ROOM_INIT;
@@ -590,11 +589,7 @@ void FullScreenDialog::display() {
_vm->_palette->fadeOut(pal, nullptr, 0, PALETTE_COUNT, 0, 1, 1, 16);
}
- _vm->_screen.empty();
- _vm->_screen.hLine(0, 20, MADS_SCREEN_WIDTH, 2);
- _vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2);
- game._scene._spriteSlots.fullRefresh();
-
+ // Set Fx state and palette entries
game._fx = _vm->_screenFade == SCREEN_FADE_SMOOTH ? kTransitionFadeIn : kCenterVertTransition;
game._trigger = 0;
@@ -604,6 +599,18 @@ void FullScreenDialog::display() {
_vm->_palette->setEntry(13, 45, 45, 0);
_vm->_palette->setEntry(14, 63, 63, 63);
_vm->_palette->setEntry(15, 45, 45, 45);
+
+
+ // Clear the screen and draw the upper and lower horizontal lines
+ _vm->_screen.empty();
+ _vm->_screen.hLine(0, 20, MADS_SCREEN_WIDTH, 2);
+ _vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2);
+ _vm->_screen.copyRectToScreen(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
+
+ // Restrict the screen to the area between the two lines
+ _vm->_screen.setClipBounds(Common::Rect(0, DIALOG_TOP, MADS_SCREEN_WIDTH,
+ DIALOG_TOP + MADS_SCENE_HEIGHT));
+ _vm->_game->_scene.restrictScene();
}
/*------------------------------------------------------------------------*/
@@ -667,7 +674,7 @@ void GameDialog::display() {
}
GameDialog::~GameDialog() {
- _vm->_screen._offset.y = 0;
+ _vm->_screen.resetClipBounds();
}
void GameDialog::clearLines() {
@@ -868,10 +875,11 @@ void GameDialog::handleEvents() {
_vm->_events->pollEvents();
// Scan for objects in the dialog
- int objIndex = screenObjects.scan(events.currentPos() - _vm->_screen._offset, LAYER_GUI);
+ Common::Point mousePos = events.currentPos() - Common::Point(0, DIALOG_TOP);
+ int objIndex = screenObjects.scan(mousePos, LAYER_GUI);
if (_movedFlag) {
- int yp = events.currentPos().y - _vm->_screen._offset.y;
+ int yp = mousePos.y;
if (yp < screenObjects[1]._bounds.top) {
if (!events._mouseReleased)
_lines[1]._state = DLGSTATE_SELECTED;
diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h
index 1468db38c8..f64f992611 100644
--- a/engines/mads/nebular/dialogs_nebular.h
+++ b/engines/mads/nebular/dialogs_nebular.h
@@ -31,6 +31,8 @@ namespace MADS {
namespace Nebular {
+#define DIALOG_TOP 22
+
enum CapitalizationMode { kUppercase = 0, kLowercase = 1, kUpperAndLower = 2 };
class DialogsNebular : public Dialogs {
diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp
index b0b0c5e003..d5a1d8538d 100644
--- a/engines/mads/nebular/menu_nebular.cpp
+++ b/engines/mads/nebular/menu_nebular.cpp
@@ -35,7 +35,6 @@ namespace Nebular {
#define NEBULAR_MENUSCREEN 990
#define MADS_MENU_Y ((MADS_SCREEN_HEIGHT - MADS_SCENE_HEIGHT) / 2)
#define MADS_MENU_ANIM_DELAY 70
-#define DIALOG_TOP 22
MenuView::MenuView(MADSEngine *vm) : FullScreenDialog(vm) {
_breakFlag = false;
@@ -57,7 +56,6 @@ void MenuView::show() {
while (!_breakFlag && !_vm->shouldQuit()) {
if (_redrawFlag) {
_vm->_game->_scene.drawElements(_vm->_game->_fx, _vm->_game->_fx);
- _vm->_screen.copyRectToScreen(Common::Rect(0, 0, 320, 200));
_redrawFlag = false;
}
@@ -111,10 +109,10 @@ void MainMenu::display() {
// Register the menu item area in the screen objects
MSprite *frame0 = _menuItems[i]->getFrame(0);
Common::Point pt(frame0->_offset.x - (frame0->w / 2),
- frame0->_offset.y - frame0->h + _vm->_screen._offset.y);
+ frame0->_offset.y - frame0->h);
screenObjects.add(
- Common::Rect(pt.x, pt.y, pt.x + frame0->w, pt.y + frame0->h),
- LAYER_GUI, CAT_COMMAND, i);
+ Common::Rect(pt.x, pt.y + DIALOG_TOP, pt.x + frame0->w,
+ pt.y + frame0->h + DIALOG_TOP), LAYER_GUI, CAT_COMMAND, i);
}
// Set the cursor for when it's shown
diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp
index cb68d38eec..ad24dd4f60 100644
--- a/engines/mads/scene.cpp
+++ b/engines/mads/scene.cpp
@@ -63,8 +63,7 @@ Scene::Scene(MADSEngine *vm)
_paletteUsageF.push_back(PaletteUsage::UsageEntry(0xF));
// Set up a scene surface that maps to our physical screen drawing surface
- _sceneSurface.init(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT, MADS_SCREEN_WIDTH,
- _vm->_screen.getPixels(), Graphics::PixelFormat::createFormatCLUT8());
+ restrictScene();
// Set up the verb list
_verbList.push_back(VerbInit(VERB_LOOK, VERB_THAT, PREP_NONE));
@@ -85,6 +84,11 @@ Scene::~Scene() {
delete _animationData;
}
+void Scene::restrictScene() {
+ _sceneSurface.init(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT, MADS_SCREEN_WIDTH,
+ _vm->_screen.getPixels(), Graphics::PixelFormat::createFormatCLUT8());
+}
+
void Scene::clearVocab() {
_activeVocabs.clear();
}
@@ -511,7 +515,7 @@ void Scene::drawElements(ScreenTransition transitionType, bool surfaceFlag) {
_vm->_sound->startQueuedCommands();
} else {
// Copy dirty areas to the screen
- _dirtyAreas.copyToScreen(_vm->_screen._offset);
+ _dirtyAreas.copyToScreen();
}
_spriteSlots.cleanUp();
diff --git a/engines/mads/scene.h b/engines/mads/scene.h
index 407d70dc85..ee7864cfee 100644
--- a/engines/mads/scene.h
+++ b/engines/mads/scene.h
@@ -142,6 +142,8 @@ public:
*/
~Scene();
+ void restrictScene();
+
/**
* Clear the vocabulary list
*/
diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp
index ab5dff56ff..590e63ac9e 100644
--- a/engines/mads/screen.cpp
+++ b/engines/mads/screen.cpp
@@ -212,8 +212,7 @@ void DirtyAreas::copy(MSurface *srcSurface, MSurface *destSurface, const Common:
Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
- Common::Point destPos(bounds.left + _vm->_screen._offset.x,
- bounds.top + _vm->_screen._offset.y);
+ Common::Point destPos(bounds.left, bounds.top);
if ((*this)[i]._active && bounds.isValidRect()) {
srcSurface->copyTo(destSurface, bounds, destPos);
@@ -221,17 +220,14 @@ void DirtyAreas::copy(MSurface *srcSurface, MSurface *destSurface, const Common:
}
}
-void DirtyAreas::copyToScreen(const Common::Point &posAdjust) {
+void DirtyAreas::copyToScreen() {
for (uint i = 0; i < size(); ++i) {
- const Common::Rect &srcBounds = (*this)[i]._bounds;
+ const Common::Rect &bounds = (*this)[i]._bounds;
// Check if this is a sane rectangle before attempting to create it
- if (srcBounds.left >= srcBounds.right || srcBounds.top >= srcBounds.bottom)
+ if (bounds.left >= bounds.right || bounds.top >= bounds.bottom)
continue;
- Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
- srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
-
if ((*this)[i]._active && (*this)[i]._bounds.isValidRect()) {
_vm->_screen.copyRectToScreen(bounds);
}
@@ -561,23 +557,32 @@ void ScreenObjects::synchronize(Common::Serializer &s) {
ScreenSurface::ScreenSurface() {
_shakeCountdown = -1;
_random = 0x4D2;
+ _surfacePixels = nullptr;
}
void ScreenSurface::init() {
- setSize(g_system->getWidth(), g_system->getHeight());
-}
+ // Set the size for the screen
+ setSize(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT);
-void ScreenSurface::copyRectToScreen(const Common::Point &destPos,
- const Common::Rect &bounds) {
- const byte *buf = getBasePtr(destPos.x, destPos.y);
+ // Store a copy of the raw pixels pointer for the screen, since the surface
+ // itself may be later changed to only a subset of the screen
+ _surfacePixels = (byte *)getPixels();
+ _freeFlag = false;
+}
- if (bounds.width() != 0 && bounds.height() != 0)
- g_system->copyRectToScreen(buf, this->pitch, bounds.left, bounds.top,
- bounds.width(), bounds.height());
+ScreenSurface::~ScreenSurface() {
+ delete[] _surfacePixels;
}
void ScreenSurface::copyRectToScreen(const Common::Rect &bounds) {
- copyRectToScreen(Common::Point(bounds.left, bounds.top), bounds);
+ const byte *buf = getBasePtr(bounds.left, bounds.top);
+
+ Common::Rect destBounds = bounds;
+ destBounds.translate(_clipBounds.left, _clipBounds.top);
+
+ if (bounds.width() != 0 && bounds.height() != 0)
+ g_system->copyRectToScreen(buf, this->pitch, destBounds.left, destBounds.top,
+ destBounds.width(), destBounds.height());
}
void ScreenSurface::updateScreen() {
@@ -659,4 +664,15 @@ void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag
}
}
+void ScreenSurface::setClipBounds(const Common::Rect &r) {
+ _clipBounds = r;
+ setPixels(_surfacePixels + pitch * r.top + r.left, r.width(), r.height());
+ this->pitch = MADS_SCREEN_WIDTH;
+}
+
+void ScreenSurface::resetClipBounds() {
+ setClipBounds(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
+}
+
+
} // End of namespace MADS
diff --git a/engines/mads/screen.h b/engines/mads/screen.h
index 7937e15456..9d01ca82e3 100644
--- a/engines/mads/screen.h
+++ b/engines/mads/screen.h
@@ -117,8 +117,8 @@ public:
/**
* Use the lsit of dirty areas to copy areas of the screen surface to
* the physical screen
- * @param posAdjust Position adjustment */
- void copyToScreen(const Common::Point &posAdjust);
+ */
+ void copyToScreen();
void reset();
};
@@ -205,8 +205,9 @@ public:
class ScreenSurface : public MSurface {
private:
uint16 _random;
+ byte *_surfacePixels;
+ Common::Rect _clipBounds;
public:
- Common::Point _offset;
int _shakeCountdown;
public:
/**
@@ -215,17 +216,14 @@ public:
ScreenSurface();
/**
- * Initialize the surface
+ * Destructor
*/
- void init();
+ ~ScreenSurface();
/**
- * Copys an area of the screen surface to a given destination position on
- * the ScummVM physical screen buffer
- * @param destPos Destination position
- * @param bounds Area of screen surface to copy
+ * Initialize the surface
*/
- void copyRectToScreen(const Common::Point &destPos, const Common::Rect &bounds);
+ void init();
/**
* Copys an area of the screen surface to the ScmmVM physical screen buffer
@@ -239,6 +237,12 @@ public:
void updateScreen();
void transition(ScreenTransition transitionType, bool surfaceFlag);
+
+ void setClipBounds(const Common::Rect &r);
+
+ void resetClipBounds();
+
+ const Common::Rect &getClipBounds() { return _clipBounds; }
};
} // End of namespace MADS
diff --git a/engines/mads/sprites.cpp b/engines/mads/sprites.cpp
index 2bf13eeb5a..cd358077b5 100644
--- a/engines/mads/sprites.cpp
+++ b/engines/mads/sprites.cpp
@@ -331,8 +331,6 @@ void SpriteSlots::drawSprites(MSurface *s) {
xp = slot._position.x - (sprite->w / 2) - scene._posAdjust.x;
yp = slot._position.y - sprite->h - scene._posAdjust.y + 1;
}
- xp += _vm->_screen._offset.x;
- yp += _vm->_screen._offset.y;
if (slot._depth > 1) {
// Draw the frame with depth processing