aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorMax Horn2004-01-03 21:22:07 +0000
committerMax Horn2004-01-03 21:22:07 +0000
commit34db2e793a22fc12b6f30289297aeead967e4f26 (patch)
treeead2d13e04d084a65e3845aaa6ac6528c56b87db /scumm
parentd49082065a1cbcecffb9069e449ce5c8686ea23d (diff)
downloadscummvm-rg350-34db2e793a22fc12b6f30289297aeead967e4f26.tar.gz
scummvm-rg350-34db2e793a22fc12b6f30289297aeead967e4f26.tar.bz2
scummvm-rg350-34db2e793a22fc12b6f30289297aeead967e4f26.zip
added & renamed some constants; fixed & added some doxygen comments; cleaned up the dirty screen code a bit (this should also fix a bug in V1/V2 games where part of the screen was not redrawn properly)
svn-id: r12118
Diffstat (limited to 'scumm')
-rw-r--r--scumm/camera.cpp14
-rw-r--r--scumm/gfx.cpp106
-rw-r--r--scumm/gfx.h44
-rw-r--r--scumm/script_v2.cpp2
-rw-r--r--scumm/scummvm.cpp2
5 files changed, 88 insertions, 80 deletions
diff --git a/scumm/camera.cpp b/scumm/camera.cpp
index 0357392ce9..c35a93a5ca 100644
--- a/scumm/camera.cpp
+++ b/scumm/camera.cpp
@@ -29,7 +29,7 @@ namespace Scumm {
void ScummEngine::setCameraAtEx(int at) {
if (!(_features & GF_NEW_CAMERA)) {
- camera._mode = CM_NORMAL;
+ camera._mode = kNormalCameraMode;
camera._cur.x = at;
setCameraAt(at, 0);
camera._movingToActor = false;
@@ -37,7 +37,7 @@ void ScummEngine::setCameraAtEx(int at) {
}
void ScummEngine::setCameraAt(int pos_x, int pos_y) {
- if (camera._mode != CM_FOLLOW_ACTOR || abs(pos_x - camera._cur.x) > (_screenWidth / 2)) {
+ if (camera._mode != kFollowActorCameraMode || abs(pos_x - camera._cur.x) > (_screenWidth / 2)) {
camera._cur.x = pos_x;
}
camera._dest.x = pos_x;
@@ -89,12 +89,12 @@ void ScummEngine::setCameraFollows(Actor *a) {
int t, i;
- camera._mode = CM_FOLLOW_ACTOR;
+ camera._mode = kFollowActorCameraMode;
camera._follows = a->number;
if (!a->isInCurrentRoom()) {
startScene(a->getRoom(), 0, 0);
- camera._mode = CM_FOLLOW_ACTOR;
+ camera._mode = kFollowActorCameraMode;
camera._cur.x = a->_pos.x;
setCameraAt(camera._cur.x, 0);
}
@@ -174,7 +174,7 @@ void ScummEngine::moveCamera() {
return;
}
- if (camera._mode == CM_FOLLOW_ACTOR) {
+ if (camera._mode == kFollowActorCameraMode) {
a = derefActor(camera._follows, "moveCamera");
actorx = a->_pos.x;
@@ -353,7 +353,7 @@ void ScummEngine::cameraMoved() {
void ScummEngine::panCameraTo(int x, int y) {
camera._dest.x = x;
- camera._mode = CM_PANNING;
+ camera._mode = kPanningCameraMode;
camera._movingToActor = false;
}
@@ -373,7 +373,7 @@ void ScummEngine::actorFollowCamera(int act) {
/*
// MI1 compatibilty
if (act == 0) {
- camera._mode = CM_NORMAL;
+ camera._mode = kNormalCameraMode;
camera._follows = 0;
camera._movingToActor = false;
return;
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++)
diff --git a/scumm/gfx.h b/scumm/gfx.h
index 5dc17a97f0..367f92b4fe 100644
--- a/scumm/gfx.h
+++ b/scumm/gfx.h
@@ -29,13 +29,15 @@ namespace Scumm {
class ScummEngine;
-enum { /** Camera modes */
- CM_NORMAL = 1,
- CM_FOLLOW_ACTOR = 2,
- CM_PANNING = 3
+/** Camera modes */
+enum {
+ kNormalCameraMode = 1,
+ kFollowActorCameraMode = 2,
+ kPanningCameraMode = 3
};
-struct CameraData { /** Camera state data */
+/** Camera state data */
+struct CameraData {
Common::Point _cur;
Common::Point _dest;
Common::Point _accel;
@@ -45,7 +47,15 @@ struct CameraData { /** Camera state data */
bool _movingToActor;
};
-struct VirtScreen { /** Virtual screen areas */
+/** Virtual screen identifiers */
+enum {
+ kMainVirtScreen = 0, // The 'stage'
+ kTextVirtScreen = 1, // In V1-V3 games: the area where text is printed
+ kVerbVirtScreen = 2 // The verb area
+};
+
+/** Virtual screen areas */
+struct VirtScreen {
int number;
uint16 topline;
uint16 width, height;
@@ -66,7 +76,8 @@ struct VirtScreen { /** Virtual screen areas */
}
};
-struct ColorCycle { /** Palette cycles */
+/** Palette cycles */
+struct ColorCycle {
uint16 delay;
uint16 counter;
uint16 flags;
@@ -74,7 +85,8 @@ struct ColorCycle { /** Palette cycles */
byte end;
};
-struct BlastObject { /** BlastObjects to draw */
+/** BlastObjects to draw */
+struct BlastObject {
uint16 number;
int16 posX, posY;
uint16 width, height;
@@ -190,14 +202,14 @@ public:
// to get it fixed and so that really interested parties can experiment it.
// It is NOT FIT FOR GENERAL USAGE! You have been warned.
//
-// Doing this correctly will be quite some more complicated. Basically, with smooth
-// scrolling, the virtual screen strips don't match the display screen strips.
-// Hence we either have to draw partial strips - but that'd be rather cumbersome.
-// Or the much simple (and IMHO more elegant) solution is to simply use a screen pitch
-// that is 8 pixel wider than the real screen width, and always draw one strip more than
-// needed to the backbuf. This will still require quite some code to be changed but
-// should otherwise be relatively easy to understand, and using VirtScreen::pitch
-// will actually clean up the code.
+// Doing this correctly will be complicated. Basically, with smooth scrolling,
+// the virtual screen strips don't match the display screen strips. Hence we
+// either have to draw partial strips (but that'd be rather cumbersome). Or the
+// alternative (and IMHO more elegant) solution is to simply use a screen pitch
+// that is 8 pixel wider than the real screen width, and always draw one strip
+// more than needed to the backbuf. This will still require quite some code to
+// be changed but should otherwise be relatively easy to understand, and using
+// VirtScreen::pitch will actually clean up the code.
//
// #define V7_SMOOTH_SCROLLING_HACK
diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp
index 19a2b558f4..d21c844943 100644
--- a/scumm/script_v2.cpp
+++ b/scumm/script_v2.cpp
@@ -1411,7 +1411,7 @@ void ScummEngine_v2::o2_endCutscene() {
if (_gameId == GID_MANIAC) {
camera._mode = (byte) vm.cutSceneData[3];
- if (camera._mode == CM_FOLLOW_ACTOR) {
+ if (camera._mode == kFollowActorCameraMode) {
actorFollowCamera(VAR(VAR_EGO));
} else if (vm.cutSceneData[2] != _currentRoom) {
startScene(vm.cutSceneData[2], 0, 0);
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index 1072356ad3..ffb7b74942 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -2083,7 +2083,7 @@ void ScummEngine::startScene(int room, Actor *a, int objectNr) {
VAR(VAR_CAMERA_MAX_Y) = _roomHeight - (_screenHeight / 2);
setCameraAt(_screenWidth / 2, _screenHeight / 2);
} else {
- camera._mode = CM_NORMAL;
+ camera._mode = kNormalCameraMode;
if (_version > 2)
camera._cur.x = camera._dest.x = _screenWidth / 2;
camera._cur.y = camera._dest.y = _screenHeight / 2;