[Scummvm-cvs-logs] CVS: scummvm/scumm gfx.cpp,1.84,1.85 gfx.h,1.14,1.15 object.cpp,1.19,1.20 scumm.h,1.86,1.87 string.cpp,1.55,1.56
Max Horn
fingolfin at users.sourceforge.net
Fri Dec 20 17:12:14 CET 2002
Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1:/tmp/cvs-serv14049
Modified Files:
gfx.cpp gfx.h object.cpp scumm.h string.cpp
Log Message:
got rid of _curVirtScreen and VirtScreen::unk1; added some comments to gfx.cpp; added a hack to enable smooth scrolling in V7 games (note: when I say hack, I mean it, it is buggy as hell and not enabled by default, use at your own risk and don't report problems with it, it's disabled by default)
Index: gfx.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/gfx.cpp,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -d -r1.84 -r1.85
--- gfx.cpp 16 Dec 2002 19:53:41 -0000 1.84
+++ gfx.cpp 21 Dec 2002 01:11:41 -0000 1.85
@@ -32,6 +32,26 @@
#endif
+// If you wan to try buggy hacked smooth scrolling support in The Dig, enable
+// the following preprocessor flag by uncommenting it.
+//
+// Note: This is purely experimental, NOT WORKING COMPLETLY and very buggy.
+// Please do not make reports about problems with it - this is only in CVS
+// 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.
+//
+// #define V7_SMOOTH_SCROLLING_HACK
+
+
enum {
kScrolltime = 500, // ms scrolling is supposed to take
kPictureDelay = 20
@@ -159,8 +179,6 @@
{
VirtScreen *vs = &virtscr[slot];
int size;
- int i;
- byte *ptr;
assert(height >= 0);
assert(slot >= 0 && slot < 4);
@@ -171,7 +189,6 @@
}
vs->number = slot;
- vs->unk1 = 0;
vs->width = _realWidth;
vs->topline = top;
vs->height = height;
@@ -182,18 +199,17 @@
vs->size = size;
vs->backBuf = NULL;
- if ((vs->scrollable) && (_features & GF_AFTER_V7)) {
- size += _realWidth * 8;
- } else {
- size += _realWidth * 4;
+ if (vs->scrollable) {
+ if (_features & GF_AFTER_V7) {
+ size += _realWidth * 8;
+ } else {
+ size += _realWidth * 4;
+ }
}
-
+
createResource(rtBuffer, slot + 1, size);
vs->screenPtr = getResourceAddress(rtBuffer, slot + 1);
-
- ptr = vs->screenPtr;
- for (i = 0; i < size; i++) // reset background ?
- *ptr++ = 0;
+ memset(vs->screenPtr, 0, size); // reset background
if (twobufs) {
createResource(rtBuffer, slot + 5, size);
@@ -211,10 +227,10 @@
for (i = 0; i < 3; i++, vs++) {
if (y >= vs->topline && y < vs->topline + vs->height) {
- return _curVirtScreen = vs;
+ return vs;
}
}
- return _curVirtScreen = NULL;
+ return NULL;
}
void Scumm::updateDirtyRect(int virt, int left, int right, int top, int bottom, uint32 dirtybits)
@@ -237,14 +253,19 @@
right = vs->width;
if (virt == 0 && dirtybits) {
- rp = (right >> 3) + _screenStartStrip;
lp = (left >> 3) + _screenStartStrip;
if (lp < 0)
lp = 0;
if (_features & GF_AFTER_V7) {
+#ifdef V7_SMOOTH_SCROLLING_HACK
+ rp = (right + vs->xstart) >> 3;
+#else
+ rp = (right >> 3) + _screenStartStrip;
+#endif
if (rp > 409)
rp = 409;
} else {
+ rp = (right >> 3) + _screenStartStrip;
if (rp >= 200)
rp = 200;
}
@@ -306,8 +327,8 @@
} else {
vs = &virtscr[0];
- src = vs->screenPtr + _screenStartStrip * 8 + _screenTop * _realWidth;
- _system->copy_rect(src, _realWidth, 0, vs->topline, _realWidth, vs->height);
+ src = vs->screenPtr + vs->xstart + _screenTop * _realWidth;
+ _system->copy_rect(src, _realWidth, 0, vs->topline, _realWidth, vs->height - _screenTop);
for (i = 0; i < gdi._numStrips; i++) {
vs->tdirty[i] = (byte)vs->height;
@@ -330,14 +351,16 @@
gdi.updateDirtyScreen(&virtscr[slot]);
}
+// Blit the 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)
{
if (vs->height == 0)
return;
- if (_vm->_features & GF_AFTER_V7 && (_vm->camera._cur.y != _vm->camera._last.y))
+ if (_vm->_features & GF_AFTER_V7 && (_vm->camera._cur.y != _vm->camera._last.y)) {
drawStripToScreen(vs, 0, _numStrips << 3, 0, vs->height);
- else {
+ } else {
int i;
int start, w, top, bottom;
@@ -352,6 +375,8 @@
vs->tdirty[i] = (byte)vs->height;
vs->bdirty[i] = 0;
if (i != (_numStrips - 1) && vs->bdirty[i + 1] == (byte)bottom && vs->tdirty[i + 1] == (byte)top) {
+ // Simple optimizations: if two or more neighbouring strips form one bigger rectangle,
+ // blit them all at once.
w += 8;
continue;
}
@@ -366,6 +391,7 @@
}
}
+// Blit the specified rectangle from the given virtual screen to the display.
void Gdi::drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b)
{
byte *ptr;
@@ -395,6 +421,7 @@
memset(_vm->getResourceAddress(rtBuffer, 9), 0, _imgBufOffs[1] - _imgBufOffs[0]);
}
+// Reset the background behind an actor or blast object
void Gdi::resetBackground(int top, int bottom, int strip)
{
VirtScreen *vs = &_vm->virtscr[0];
@@ -569,6 +596,8 @@
_flashlightIsDrawn = true;
}
+// Redraw background as needed, i.e. the left/right sides if scrolling took place etc.
+// Note that this only updated the virtual screen, not the actual display.
void Scumm::redrawBGAreas()
{
int i;
@@ -581,6 +610,7 @@
val = 0;
+ // Redraw parts of the background which are marked as dirty.
if (!_fullRedraw && _BgNeedsRedraw) {
for (i = 0; i != gdi._numStrips; i++) {
if (gfxUsageBits[_screenStartStrip + i] & 0x80000000) {
@@ -626,19 +656,11 @@
assert(s >= 0 && (size_t) s < sizeof(gfxUsageBits) / sizeof(gfxUsageBits[0]));
- _curVirtScreen = &virtscr[0];
-
for (int i = 0; i < num; i++)
gfxUsageBits[s + i] |= 0x80000000;
- /*if (_curVirtScreen->height < _scrHeight) {
- warning("Screen Y size %d < Room height %d",
- _curVirtScreen->height,
- _scrHeight);
- } */
-
gdi.drawBitmap(getResourceAddress(rtRoom, _roomResource) + _IM00_offs,
- _curVirtScreen, s, 0, _curVirtScreen->height, s, num, 0);
+ &virtscr[0], s, 0, virtscr[0].height, s, num, 0);
}
void Scumm::restoreCharsetBg()
@@ -765,7 +787,6 @@
byte *zplane_list[6];
int bottom;
- byte twobufs;
int numzbuf;
int sx;
bool lightsOn;
@@ -815,8 +836,6 @@
warning("Gdi::drawBitmap, strip drawn to %d below window bottom %d", bottom, vs->height);
}
- twobufs = vs->alloctwobuffers;
-
_vertStripNextInc = h * _vm->_realWidth - 1;
do {
@@ -838,7 +857,7 @@
vs->bdirty[sx] = bottom;
backbuff_ptr = vs->screenPtr + (y * _numStrips + x) * 8;
- if (twobufs)
+ if (vs->alloctwobuffers)
bgbak_ptr = _vm->getResourceAddress(rtBuffer, vs->number + 5) + (y * _numStrips + x) * 8;
else
bgbak_ptr = backbuff_ptr;
@@ -851,7 +870,7 @@
decompressBitmap(bgbak_ptr, smap_ptr + READ_LE_UINT32(smap_ptr + stripnr * 4 + 8), h);
CHECK_HEAP;
- if (twobufs) {
+ if (vs->alloctwobuffers) {
if (_vm->hasCharsetMask(sx << 3, y, (sx + 1) << 3, bottom)) {
if (flag & dbClear || !lightsOn)
clear8ColWithMasking(backbuff_ptr, h, _mask_ptr);
@@ -1954,8 +1973,6 @@
_screenStartStrip = (camera._cur.x - (_realWidth / 2)) >> 3;
_screenEndStrip = _screenStartStrip + gdi._numStrips - 1;
- virtscr[0].xstart = _screenStartStrip << 3;
-
_screenTop = camera._cur.y - (_realHeight / 2);
if (_features & GF_AFTER_V7) {
@@ -1966,6 +1983,11 @@
_screenLeft = _screenStartStrip << 3;
}
+#ifdef V7_SMOOTH_SCROLLING_HACK
+ virtscr[0].xstart = _screenLeft;
+#else
+ virtscr[0].xstart = _screenStartStrip << 3;
+#endif
}
void Scumm::panCameraTo(int x, int y)
Index: gfx.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/gfx.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- gfx.h 16 Dec 2002 07:13:47 -0000 1.14
+++ gfx.h 21 Dec 2002 01:11:41 -0000 1.15
@@ -42,7 +42,6 @@
struct VirtScreen { /* Virtual screen areas */
int number;
- uint16 unk1;
uint16 topline;
uint16 width, height;
uint16 size;
Index: object.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/object.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- object.cpp 13 Dec 2002 01:33:23 -0000 1.19
+++ object.cpp 21 Dec 2002 01:11:41 -0000 1.20
@@ -336,8 +336,6 @@
if (_BgNeedsRedraw)
arg = 0;
- _curVirtScreen = &virtscr[0];
-
od = &_objs[obj];
xpos = od->x_pos >> 3;
@@ -386,7 +384,7 @@
// the inventory and conversation icons.
if ((_features & GF_AFTER_V7 || _gameId == GID_SAMNMAX) && getClass(od->obj_nr, 22))
flags |= Gdi::dbDrawMaskOnAll;
- gdi.drawBitmap(ptr, _curVirtScreen, x, ypos, height, x - xpos, numstrip, flags);
+ gdi.drawBitmap(ptr, &virtscr[0], x, ypos, height, x - xpos, numstrip, flags);
}
}
Index: scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.86
retrieving revision 1.87
diff -u -d -r1.86 -r1.87
--- scumm.h 17 Dec 2002 01:15:13 -0000 1.86
+++ scumm.h 21 Dec 2002 01:11:42 -0000 1.87
@@ -219,7 +219,7 @@
int _offsX, _offsY;
int _virtScreenHeight;
- void drawBits(byte *dst, byte *mask, int drawTop, int width, int height);
+ void drawBits(byte *dst, byte *mask, int drawTop, int width, int height, bool useMask);
public:
byte _colorMap[16];
@@ -406,7 +406,6 @@
int _curVerbSlot;
int _curPalIndex;
byte _currentRoom;
- VirtScreen *_curVirtScreen;
bool _egoPositioned;
int _keyPressed;
Index: string.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/string.cpp,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- string.cpp 13 Dec 2002 00:52:14 -0000 1.55
+++ string.cpp 21 Dec 2002 01:11:42 -0000 1.56
@@ -320,17 +320,18 @@
+ drawTop * _vm->gdi._numStrips + _left / 8 + _vm->_screenStartStrip;
byte *dst = vs->screenPtr + vs->xstart + drawTop * _vm->_realWidth + _left;
+ bool useMask = (vs->number == 0 && !_ignoreCharsetMask);
if (_blitAlso) {
byte *back = dst;
dst = _vm->getResourceAddress(rtBuffer, vs->number + 5)
+ vs->xstart + drawTop * _vm->_realWidth + _left;
- drawBits(dst, mask, drawTop, width, height);
+ drawBits(dst, mask, drawTop, width, height, useMask);
_vm->blit(back, dst, width, height);
} else {
- drawBits(dst, mask, drawTop, width, height);
+ drawBits(dst, mask, drawTop, width, height, useMask);
}
_left += width;
@@ -343,17 +344,14 @@
_top -= _offsY;
}
-void CharsetRenderer::drawBits(byte *dst, byte *mask, int drawTop, int width, int height)
+void CharsetRenderer::drawBits(byte *dst, byte *mask, int drawTop, int width, int height, bool useMask)
{
- bool usemask;
byte maskmask;
int y, x;
int maskpos;
int color;
byte numbits, bits;
- usemask = (_vm->_curVirtScreen->number == 0 && !_ignoreCharsetMask);
-
bits = *_charPtr++;
numbits = 8;
@@ -370,7 +368,7 @@
assert(color == myColor);
if (color) {
- if (usemask) {
+ if (useMask) {
mask[maskpos] |= maskmask;
}
*dst = _colorMap[color];
More information about the Scummvm-git-logs
mailing list