aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2004-01-06 11:47:34 +0000
committerMax Horn2004-01-06 11:47:34 +0000
commitcc67301791cd46bc6e81bb76ef30c45d692a7547 (patch)
tree300a72019bd2213d2c7ab415977dafe0e7641dfd
parent3b20850a8906d1be6bd2eb8f2a1f506975ae17df (diff)
downloadscummvm-rg350-cc67301791cd46bc6e81bb76ef30c45d692a7547.tar.gz
scummvm-rg350-cc67301791cd46bc6e81bb76ef30c45d692a7547.tar.bz2
scummvm-rg350-cc67301791cd46bc6e81bb76ef30c45d692a7547.zip
renamed VirtScreen::alloctwobuffers to hasTwoBuffers; added lots of doxygen comments to VirtScreen; cleanup
svn-id: r12168
-rw-r--r--scumm/charset.cpp15
-rw-r--r--scumm/cursor.cpp4
-rw-r--r--scumm/debugger.cpp2
-rw-r--r--scumm/gfx.cpp19
-rw-r--r--scumm/gfx.h110
-rw-r--r--scumm/verbs.cpp6
6 files changed, 130 insertions, 26 deletions
diff --git a/scumm/charset.cpp b/scumm/charset.cpp
index 8f9b6465c7..8295941e55 100644
--- a/scumm/charset.cpp
+++ b/scumm/charset.cpp
@@ -970,15 +970,16 @@ void CharsetRendererV3::printChar(int chr) {
w++;
h++;
}
-
+
drawTop = _top - vs->topline;
char_ptr = _fontPtr + chr * 8;
dest_ptr = vs->screenPtr + vs->xstart + drawTop * vs->width + _left;
mask_ptr = _vm->getMaskBuffer(_left, drawTop, 0);
- useMask = (vs->number == 0 && !_ignoreCharsetMask);
+ useMask = (vs->number == kMainVirtScreen && !_ignoreCharsetMask);
_vm->markRectAsDirty(vs->number, _left, _left + w, drawTop, drawTop + h, 0);
- if (vs->number == 0)
+
+ if (vs->number == kMainVirtScreen)
_hasMask = true;
drawBits1(vs, dest_ptr, char_ptr, mask_ptr, drawTop, 8, 8);
@@ -1084,9 +1085,9 @@ void CharsetRendererClassic::printChar(int chr) {
_vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height + offsY, 0);
- if (vs->number != 0)
+ if (vs->number != kMainVirtScreen)
_blitAlso = false;
- if (vs->number == 0 && !_ignoreCharsetMask)
+ if (vs->number == kMainVirtScreen && !_ignoreCharsetMask)
_hasMask = true;
@@ -1134,7 +1135,7 @@ void CharsetRendererClassic::drawBitsN(VirtScreen *vs, byte *dst, const byte *sr
int maskpos;
int color;
byte numbits, bits;
- bool useMask = (vs->number == 0 && !_ignoreCharsetMask);
+ bool useMask = (vs->number == kMainVirtScreen && !_ignoreCharsetMask);
assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8);
bits = *src++;
@@ -1176,7 +1177,7 @@ void CharsetRendererCommon::drawBits1(VirtScreen *vs, byte *dst, const byte *src
int y, x;
int maskpos;
byte bits = 0;
- bool useMask = (vs->number == 0 && !_ignoreCharsetMask);
+ bool useMask = (vs->number == kMainVirtScreen && !_ignoreCharsetMask);
for (y = 0; y < height && y + drawTop < vs->height; y++) {
maskmask = revBitMask[_left & 7];
diff --git a/scumm/cursor.cpp b/scumm/cursor.cpp
index 9a8ae5a4fa..674b7150f9 100644
--- a/scumm/cursor.cpp
+++ b/scumm/cursor.cpp
@@ -130,10 +130,10 @@ void ScummEngine::useIm01Cursor(const byte *im, int w, int h) {
drawBox(0, 0, w - 1, h - 1, 0xFF);
- vs->alloctwobuffers = false;
+ vs->hasTwoBuffers = false;
gdi.disableZBuffer();
gdi.drawBitmap(im, vs, _screenStartStrip, 0, w, h, 0, w / 8, 0);
- vs->alloctwobuffers = true;
+ vs->hasTwoBuffers = true;
gdi.enableZBuffer();
grabCursor(vs->screenPtr + vs->xstart, w, h);
diff --git a/scumm/debugger.cpp b/scumm/debugger.cpp
index d20634773b..568b51cbd9 100644
--- a/scumm/debugger.cpp
+++ b/scumm/debugger.cpp
@@ -630,7 +630,7 @@ static void hlineColor(ScummEngine *scumm, int x1, int x2, int y, byte color) {
x2 = right - 1;
- ptr = vs->screenPtr + x1 + y * scumm->_screenWidth;
+ ptr = vs->screenPtr + x1 + y * vs->width;
while (x1++ <= x2) {
*ptr++ = color;
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
index 93511842e9..9b974699a7 100644
--- a/scumm/gfx.cpp
+++ b/scumm/gfx.cpp
@@ -216,7 +216,7 @@ void ScummEngine::initVirtScreen(VirtScreenNumber slot, int number, int top, int
vs->width = width;
vs->topline = top;
vs->height = height;
- vs->alloctwobuffers = twobufs;
+ vs->hasTwoBuffers = twobufs;
vs->scrollable = scrollable;
vs->xstart = 0;
vs->backBuf = NULL;
@@ -573,7 +573,7 @@ void ScummEngine::restoreCharsetBg() {
void ScummEngine::restoreBG(Common::Rect rect, byte backColor) {
VirtScreen *vs;
int topline, height, width;
- byte *backbuff, *bgbak;
+ byte *backbuff;
bool lightsOn;
if (rect.top < 0)
@@ -602,7 +602,6 @@ void ScummEngine::restoreBG(Common::Rect rect, byte backColor) {
int offset = (rect.top - topline) * vs->width + vs->xstart + rect.left;
backbuff = vs->screenPtr + offset;
- bgbak = vs->backBuf + offset;
height = rect.height();
width = rect.width();
@@ -610,8 +609,8 @@ void ScummEngine::restoreBG(Common::Rect rect, byte backColor) {
// Check whether lights are turned on or not
lightsOn = (_features & GF_NEW_OPCODES) || (vs->number != kMainVirtScreen) || (VAR(VAR_CURRENT_LIGHTS) & LIGHTMODE_screen);
- if (vs->alloctwobuffers && _currentRoom != 0 && lightsOn ) {
- blit(backbuff, bgbak, width, height);
+ if (vs->hasTwoBuffers && _currentRoom != 0 && lightsOn ) {
+ blit(backbuff, vs->backBuf + offset, width, height);
if (vs->number == kMainVirtScreen && _charset->_hasMask && height) {
byte *mask;
// Note: At first sight it may look as if this could
@@ -939,6 +938,10 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi
_vertStripNextInc = height * vs->width - 1;
sx = x;
+ // FIXME / TODO: This is the only place vs->scrollable is ever checked, and
+ // I think we can simply remove the condition and always use xstart - it
+ // should always be 0 for any non-scrolling virtual screen, after all.
+ assert(vs->scrollable || !vs->xstart);
if (vs->scrollable)
sx -= vs->xstart / 8;
@@ -951,7 +954,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi
//
if (_vm->_version == 2) {
- if (vs->alloctwobuffers)
+ if (vs->hasTwoBuffers)
bgbak_ptr = vs->backBuf + (y * _numStrips + x) * 8;
else
bgbak_ptr = vs->screenPtr + (y * _numStrips + x) * 8;
@@ -1074,7 +1077,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi
vs->bdirty[sx] = bottom;
backbuff_ptr = vs->screenPtr + (y * _numStrips + x) * 8;
- if (vs->alloctwobuffers)
+ if (vs->hasTwoBuffers)
bgbak_ptr = vs->backBuf + (y * _numStrips + x) * 8;
else
bgbak_ptr = backbuff_ptr;
@@ -1097,7 +1100,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi
mask_ptr = getMaskBuffer(x, y);
CHECK_HEAP;
- if (vs->alloctwobuffers) {
+ if (vs->hasTwoBuffers) {
if (_vm->hasCharsetMask(sx * 8, y, (sx + 1) * 8, bottom)) {
if (flag & dbClear || !lightsOn)
clear8ColWithMasking(backbuff_ptr, height, mask_ptr);
diff --git a/scumm/gfx.h b/scumm/gfx.h
index 1aaca41b49..0f381ef3bb 100644
--- a/scumm/gfx.h
+++ b/scumm/gfx.h
@@ -55,19 +55,119 @@ enum VirtScreenNumber {
kUnkVirtScreen = 3 // ?? Not sure what this one is good for...
};
-/** Virtual screen areas */
+/**
+ * In all Scumm games, one to four virtual screen (or 'windows') together make
+ * up the content of the actual screen. Thinking of virtual screens as fixed
+ * size, fixed location windows might help understanding them. Typical, in all
+ * scumm games there is either one single virtual screen covering the entire
+ * real screen (mostly in all newer games, e.g. Sam & Max, and all V7+ games).
+ * The classic setup consists of three virtual screens: one at the top of the
+ * screen, where all conversation texts are printed; then the main one (which
+ * I like calling 'the stage', since all the actors are doing their stuff
+ * there), and finally the lower part of the real screen is taken up by the
+ * verb area.
+ * Finally, in V5 games and some V6 games, it's almost the same as in the
+ * original games, except that there is no separate conversation area.
+ *
+ * If you now wonder what the last screen is/was good for: I am not 100% sure,
+ * but it appears that it was used by the original engine to display stuff
+ * like the pause message, or questions ("Do you really want to restart?").
+ * It seems that it is not used at all by ScummVM, so we probably could just
+ * get rid of it and save a couple kilobytes of RAM.
+ *
+ * Each of these virtual screens has a fixed number or id (see also the
+ * VirtScreenNumber enum).
+ */
struct VirtScreen {
+ /**
+ * The unique id of this screen (correponds to its position in the
+ * ScummEngine:virtscr array).
+ */
VirtScreenNumber number;
+
+ /**
+ * Vertical position of the virtual screen. Tells how much the virtual
+ * screen is shifted along the y axis relative to the real screen.
+ * If you wonder why there is no horizontal position: there is none,
+ * because all virtual screens are always exactly as wide as the
+ * real screen. This might change in the future to allow smooth
+ * horizontal scrolling in V7-V8 games.
+ */
uint16 topline;
- uint16 width, height;
- byte alloctwobuffers;
+
+ /** Width of the virtual screen (currently always identical to _screenWidth). */
+ uint16 width;
+
+ /** Height of the virtual screen. */
+ uint16 height;
+
+ /**
+ * Flag indicating that this virtual screen allows (horizontal) scrolling.
+ * This is always only true for the main screen (stage)! After all, verbs
+ * and the conversation text box don't have to scroll.
+ * @todo Get rid of this, there is only one place where it is used,
+ * and there it is trivial to remove the usage.
+ */
bool scrollable;
+
+ /**
+ * Horizontal scroll offset, tells how far the screen is scrolled to the
+ * right. Only used for the main screen.
+ */
uint16 xstart;
- uint16 tdirty[80];
- uint16 bdirty[80];
+
+ /**
+ * Flag indicating which tells whether this screen has a back buffer or
+ * not. This is yet another feature which is only used by the main screen.
+ * Strictly spoken one could remove this variable and replace checks
+ * on it with checks on backBuf. But since some code needs to temporarily
+ * disable the backBuf (so it can abuse drawBitmap; see drawVerbBitmap()
+ * and useIm01Cursor()), we keep it (at least for now).
+ */
+ bool hasTwoBuffers;
+
+ /**
+ * Pointer to the screen's data buffer. This is where the content of
+ * the screen is stored. Just as one would expect :-).
+ */
byte *screenPtr;
+
+ /**
+ * Pointer to the screen's back buffer, if it has one (see also
+ * the hasTwoBuffers member).
+ * The backBuf is used by drawBitmap to store the background graphics of
+ * the active room. This eases redrawing: whenever a portion of the screen
+ * has to be redrawn, first a copy from the backBuf content to screenPtr is
+ * performed. Then, any objects/actors in that area are redrawn atop that.
+ */
byte *backBuf;
+ /**
+ * Array containing for each visible strip of this virtual screen the
+ * coordinate at which the dirty region of that strip starts.
+ * 't' stands for 'top' - the top coordinate of the dirty region.
+ * This together with bdirty is used to do efficient redrawing of
+ * the screen.
+ */
+ uint16 tdirty[80];
+
+ /**
+ * Array containing for each visible strip of this virtual screen the
+ * coordinate at which the dirty region of that strip end.
+ * 'b' stands for 'bottom' - the bottom coordinate of the dirty region.
+ * This together with tdirty is used to do efficient redrawing of
+ * the screen.
+ */
+ uint16 bdirty[80];
+
+ /**
+ * Convenience method to set the whole tdirty and bdirty arrays to one
+ * specific value each. This is mostly used to mark every as dirty in
+ * a single step, like so:
+ * vs->setDirtyRange(0, vs->height);
+ * or to mark everything as clean, like so:
+ * vs->setDirtyRange(0, 0);
+ */
void setDirtyRange(int top, int bottom) {
for (int i = 0; i < 80; i++) {
tdirty[i] = top;
diff --git a/scumm/verbs.cpp b/scumm/verbs.cpp
index 6891fc3a54..15fceedf1f 100644
--- a/scumm/verbs.cpp
+++ b/scumm/verbs.cpp
@@ -449,8 +449,8 @@ void ScummEngine::drawVerbBitmap(int verb, int x, int y) {
gdi.disableZBuffer();
- twobufs = vs->alloctwobuffers;
- vs->alloctwobuffers = 0;
+ twobufs = vs->hasTwoBuffers;
+ vs->hasTwoBuffers = 0;
xstrip = x / 8;
ydiff = y - vs->topline;
@@ -499,7 +499,7 @@ void ScummEngine::drawVerbBitmap(int verb, int x, int y) {
gdi.enableZBuffer();
- vs->alloctwobuffers = twobufs;
+ vs->hasTwoBuffers = twobufs;
}
int ScummEngine::getVerbSlot(int id, int mode) const {