aboutsummaryrefslogtreecommitdiff
path: root/scumm/gfx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scumm/gfx.cpp')
-rw-r--r--scumm/gfx.cpp106
1 files changed, 51 insertions, 55 deletions
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
index 8a124e245b..583e52698a 100644
--- a/scumm/gfx.cpp
+++ b/scumm/gfx.cpp
@@ -250,9 +250,9 @@ void ScummEngine::initScreens(int a, int b, int w, int h) {
initVirtScreen(3, 0, 80, _screenWidth, 13, false, false);
}
}
- initVirtScreen(0, 0, b, _screenWidth, h - b, true, true);
- initVirtScreen(1, 0, 0, _screenWidth, b, false, false);
- initVirtScreen(2, 0, h, _screenWidth, _screenHeight - h, false, false);
+ initVirtScreen(kMainVirtScreen, 0, b, _screenWidth, h - b, true, true);
+ initVirtScreen(kTextVirtScreen, 0, 0, _screenWidth, b, false, false);
+ initVirtScreen(kVerbVirtScreen, 0, h, _screenWidth, _screenHeight - h, false, false);
_screenB = b;
_screenH = h;
@@ -371,32 +371,34 @@ void ScummEngine::updateDirtyRect(int virt, int left, int right, int top, int bo
}
}
+/**
+ * Update all dirty screen areas. This method blits all of the internal engine
+ * graphics to the actual display, as needed. In addition, the 'shaking'
+ * code in the backend is controlled from here.
+ */
void ScummEngine::drawDirtyScreenParts() {
- int i;
- VirtScreen *vs;
- byte *src;
-
- updateDirtyScreen(2);
+ // Update verbs
+ updateDirtyScreen(kVerbVirtScreen);
+
+ // In V1-V3, update the conversation area (at the top of the screen)
if (_version <= 3)
- updateDirtyScreen(1);
-
- if (camera._last.x == camera._cur.x && (camera._last.y == camera._cur.y || !(_features & GF_NEW_CAMERA))) {
- updateDirtyScreen(0);
+ updateDirtyScreen(kTextVirtScreen);
+
+ // Update game area ("stage")
+ if (camera._last.x != camera._cur.x || (_features & GF_NEW_CAMERA && (camera._cur.y != camera._last.y))) {
+ // Camera moved: redraw everything
+ // Small side note: most of our GFX code relies on this identity:
+ // gdi._numStrips * 8 == _screenWidth == vs->width
+ VirtScreen *vs = &virtscr[kMainVirtScreen];
+ gdi.drawStripToScreen(vs, 0, vs->width, 0, vs->height);
+ vs->setDirtyRange(vs->height, 0);
} else {
- vs = &virtscr[0];
-
- src = vs->screenPtr + vs->xstart + _screenTop * _screenWidth;
- _system->copy_rect(src, _screenWidth, 0, vs->topline, _screenWidth, vs->height - _screenTop);
-
- for (i = 0; i < gdi._numStrips; i++) {
- vs->tdirty[i] = vs->height;
- vs->bdirty[i] = 0;
- }
+ updateDirtyScreen(kMainVirtScreen);
}
- /* Handle shaking */
+ // Handle shaking
if (_shakeEnabled) {
- _shakeFrame = (_shakeFrame + 1) & (NUM_SHAKE_POSITIONS - 1);
+ _shakeFrame = (_shakeFrame + 1) % NUM_SHAKE_POSITIONS;
_system->set_shake_pos(shake_positions[_shakeFrame]);
} else if (!_shakeEnabled &&_shakeFrame != 0) {
_shakeFrame = 0;
@@ -409,44 +411,38 @@ void ScummEngine::updateDirtyScreen(int slot) {
}
/**
- * Blit the data from the given VirtScreen to the display. If the camera moved,
+ * Blit the dirty data from the given VirtScreen to the display. If the camera moved,
* a full blit is done, otherwise only the visible dirty areas are updated.
*/
void Gdi::updateDirtyScreen(VirtScreen *vs) {
+ // Do nothing for unused virtual screens
if (vs->height == 0)
return;
- if (_vm->_features & GF_NEW_CAMERA && (_vm->camera._cur.y != _vm->camera._last.y)) {
- drawStripToScreen(vs, 0, _numStrips * 8, 0, vs->height);
- } else {
- int i;
- int start, w, top, bottom;
-
- w = 8;
- start = 0;
-
- for (i = 0; i < _numStrips; i++) {
- bottom = vs->bdirty[i];
-
- if (bottom) {
- top = vs->tdirty[i];
- vs->tdirty[i] = vs->height;
- vs->bdirty[i] = 0;
- if (i != (_numStrips - 1) && vs->bdirty[i + 1] == bottom && vs->tdirty[i + 1] == top) {
- // Simple optimizations: if two or more neighbouring strips form one bigger rectangle,
- // blit them all at once.
- w += 8;
- continue;
- }
- // handle vertically scrolling rooms
- if (_vm->_features & GF_NEW_CAMERA)
- drawStripToScreen(vs, start * 8, w, 0, vs->height);
- else
- drawStripToScreen(vs, start * 8, w, top, bottom);
- w = 8;
+ int i;
+ int w = 8;
+ int start = 0;
+
+ for (i = 0; i < _numStrips; i++) {
+ if (vs->bdirty[i]) {
+ const int bottom = vs->bdirty[i];
+ const int top = vs->tdirty[i];
+ vs->tdirty[i] = vs->height;
+ vs->bdirty[i] = 0;
+ if (i != (_numStrips - 1) && vs->bdirty[i + 1] == bottom && vs->tdirty[i + 1] == top) {
+ // Simple optimizations: if two or more neighbouring strips form one bigger rectangle,
+ // blit them all at once.
+ w += 8;
+ continue;
}
- start = i + 1;
+ // handle vertically scrolling rooms
+ if (_vm->_features & GF_NEW_CAMERA)
+ drawStripToScreen(vs, start * 8, w, 0, vs->height);
+ else
+ drawStripToScreen(vs, start * 8, w, top, bottom);
+ w = 8;
}
+ start = i + 1;
}
}
@@ -2257,7 +2253,7 @@ void ScummEngine::fadeOut(int effect) {
case 129:
// Just blit screen 0 to the display (i.e. display will be black)
vs->setDirtyRange(0, vs->height);
- updateDirtyScreen(0);
+ updateDirtyScreen(kMainVirtScreen);
break;
case 134:
dissolveEffect(1, 1);
@@ -2341,7 +2337,7 @@ void ScummEngine::transitionEffect(int a) {
else
virtscr[0].bdirty[l] = (b + 1) * 8;
}
- updateDirtyScreen(0);
+ updateDirtyScreen(kMainVirtScreen);
}
for (i = 0; i < 16; i++)