aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO7
-rw-r--r--scumm/charset.cpp15
-rw-r--r--scumm/charset.h6
-rw-r--r--scumm/gfx.cpp97
-rw-r--r--scumm/gfx.h7
-rw-r--r--scumm/scumm.cpp4
-rw-r--r--scumm/scumm.h4
7 files changed, 73 insertions, 67 deletions
diff --git a/TODO b/TODO
index e5dbedd4e2..e131c1dbcf 100644
--- a/TODO
+++ b/TODO
@@ -279,6 +279,13 @@ SCUMM
- Fix cursor transparency in puzzle of pajama2 (Related to floodState support?)
- Fix sprites graphical glitches
- Fix inventory background/items disappearing in puttzoo/zoodemo/putttime/timedemo
+* Clean up class Gdi. This class right now mostly is about decoding various
+ graphic formats. However some other functionality has crept into it, too.
+ It would be nice if class Gdi would only contain the GFX decoding code, and
+ nothing else (assuming that is feasible w/o too much trouble).
+ OTOH, the code which is responsible for managing virtual screens, rendering
+ virtual screens to the real display etc. could be grouped into a new class
+ (e.g. VSManager or so).
Broken Sword 2
==============
diff --git a/scumm/charset.cpp b/scumm/charset.cpp
index c62140630e..458de41a13 100644
--- a/scumm/charset.cpp
+++ b/scumm/charset.cpp
@@ -202,6 +202,7 @@ CharsetRenderer::CharsetRenderer(ScummEngine *vm) {
_blitAlso = false;
_firstChar = false;
_disableOffsX = false;
+ _textSurface.pixels = 0;
_vm = vm;
_curId = 0;
@@ -1218,8 +1219,8 @@ void CharsetRendererV3::printChar(int chr) {
dst = vs->getPixels(_left, drawTop);
drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
} else {
- dst = (byte *)_vm->gdi._textSurface.pixels + _top * _vm->gdi._textSurface.pitch + _left;
- drawBits1(_vm->gdi._textSurface, dst, charPtr, drawTop, origWidth, origHeight);
+ dst = (byte *)_textSurface.pixels + _top * _textSurface.pitch + _left;
+ drawBits1(_textSurface, dst, charPtr, drawTop, origWidth, origHeight);
}
if (_str.left > _left)
@@ -1375,8 +1376,8 @@ void CharsetRendererClassic::printChar(int chr) {
dstSurface = *vs;
dstPtr = vs->getPixels(_left, drawTop);
} else {
- dstSurface = _vm->gdi._textSurface;
- dstPtr = (byte *)_vm->gdi._textSurface.pixels + (_top - _vm->_screenTop) * _vm->gdi._textSurface.pitch + _left;
+ dstSurface = _textSurface;
+ dstPtr = (byte *)_textSurface.pixels + (_top - _vm->_screenTop) * _textSurface.pitch + _left;
}
if (_blitAlso && vs->hasTwoBuffers) {
@@ -1650,7 +1651,7 @@ void CharsetRendererNut::printChar(int chr) {
s = *vs;
s.pixels = vs->getPixels(0, 0);
} else {
- s = _vm->gdi._textSurface;
+ s = _textSurface;
drawTop -= _vm->_screenTop;
}
@@ -1790,8 +1791,8 @@ void CharsetRendererNES::printChar(int chr) {
dst = vs->getPixels(_left, drawTop);
drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
} else {
- dst = (byte *)_vm->gdi._textSurface.pixels + _top * _vm->gdi._textSurface.pitch + _left;
- drawBits1(_vm->gdi._textSurface, dst, charPtr, drawTop, origWidth, origHeight);
+ dst = (byte *)_textSurface.pixels + _top * _textSurface.pitch + _left;
+ drawBits1(_textSurface, dst, charPtr, drawTop, origWidth, origHeight);
}
if (_str.left > _left)
diff --git a/scumm/charset.h b/scumm/charset.h
index e1a023e0d1..c41f1051e6 100644
--- a/scumm/charset.h
+++ b/scumm/charset.h
@@ -76,6 +76,12 @@ public:
bool _firstChar;
bool _disableOffsX;
+ /**
+ * All text is normally rendered into this overlay surface. Then later
+ * drawStripToScreen() composits it over the game graphics.
+ */
+ Graphics::Surface _textSurface;
+
protected:
ScummEngine *_vm;
byte _curId;
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
index 7525518622..6ad0d3a753 100644
--- a/scumm/gfx.cpp
+++ b/scumm/gfx.cpp
@@ -202,10 +202,6 @@ Gdi::Gdi(ScummEngine *vm) {
_roomPalette = vm->_roomPalette;
if ((vm->_features & GF_AMIGA) && (vm->_version >= 4))
_roomPalette += 16;
-
- _compositeBuf = 0;
- _textSurface.pixels = 0;
- _herculesBuf = 0;
}
void ScummEngine::initScreens(int b, int h) {
@@ -243,28 +239,29 @@ void ScummEngine::initScreens(int b, int h) {
_screenH = h;
gdi.init();
-}
-void Gdi::init() {
- const int size = _vm->_screenWidth * _vm->_screenHeight;
+ const int size = _screenWidth * _screenHeight;
free(_compositeBuf);
- free(_textSurface.pixels);
+ free(_charset->_textSurface.pixels);
free(_herculesBuf);
_compositeBuf = (byte *)malloc(size);
- _textSurface.pixels = malloc(size);
+ _charset->_textSurface.pixels = malloc(size);
memset(_compositeBuf, CHARSET_MASK_TRANSPARENCY, size);
- memset(_textSurface.pixels, CHARSET_MASK_TRANSPARENCY, size);
+ memset(_charset->_textSurface.pixels, CHARSET_MASK_TRANSPARENCY, size);
- if (_vm->_renderMode == Common::kRenderHercA || _vm->_renderMode == Common::kRenderHercG) {
+ if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
_herculesBuf = (byte *)malloc(Common::kHercW * Common::kHercH);
memset(_herculesBuf, CHARSET_MASK_TRANSPARENCY, Common::kHercW * Common::kHercH);
}
- _textSurface.w = _vm->_screenWidth;
- _textSurface.h = _vm->_screenHeight;
- _textSurface.pitch = _vm->_screenWidth;
- _textSurface.bytesPerPixel = 1;
+ _charset->_textSurface.w = _screenWidth;
+ _charset->_textSurface.h = _screenHeight;
+ _charset->_textSurface.pitch = _screenWidth;
+ _charset->_textSurface.bytesPerPixel = 1;
+}
+
+void Gdi::init() {
_numStrips = _vm->_screenWidth / 8;
// Increase the number of screen strips by one; needed for smooth scrolling
@@ -422,7 +419,7 @@ void ScummEngine::drawDirtyScreenParts() {
if (camera._last.x != camera._cur.x || (_features & GF_NEW_CAMERA && (camera._cur.y != camera._last.y))) {
// Camera moved: redraw everything
VirtScreen *vs = &virtscr[kMainVirtScreen];
- gdi.drawStripToScreen(vs, 0, vs->w, 0, vs->h);
+ drawStripToScreen(vs, 0, vs->w, 0, vs->h);
vs->setDirtyRange(vs->h, 0);
} else {
updateDirtyScreen(kMainVirtScreen);
@@ -438,15 +435,13 @@ void ScummEngine::drawDirtyScreenParts() {
}
}
-void ScummEngine::updateDirtyScreen(VirtScreenNumber slot) {
- gdi.updateDirtyScreen(&virtscr[slot]);
-}
-
/**
* 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) {
+void ScummEngine::updateDirtyScreen(VirtScreenNumber slot) {
+ VirtScreen *vs = &virtscr[slot];
+
// Do nothing for unused virtual screens
if (vs->h == 0)
return;
@@ -455,13 +450,13 @@ void Gdi::updateDirtyScreen(VirtScreen *vs) {
int w = 8;
int start = 0;
- for (i = 0; i < _numStrips; i++) {
+ for (i = 0; i < gdi._numStrips; i++) {
if (vs->bdirty[i]) {
const int top = vs->tdirty[i];
const int bottom = vs->bdirty[i];
vs->tdirty[i] = vs->h;
vs->bdirty[i] = 0;
- if (i != (_numStrips - 1) && vs->bdirty[i + 1] == bottom && vs->tdirty[i + 1] == top) {
+ if (i != (gdi._numStrips - 1) && vs->bdirty[i + 1] == bottom && vs->tdirty[i + 1] == top) {
// Simple optimizations: if two or more neighbouring strips
// form one bigger rectangle, coalesce them.
w += 8;
@@ -481,7 +476,7 @@ void Gdi::updateDirtyScreen(VirtScreen *vs) {
* arrays which map 'strips' (sections of the real screen) to dirty areas as
* specified by top/bottom coordinate in the virtual screen.
*/
-void Gdi::drawStripToScreen(VirtScreen *vs, int x, int width, int top, int bottom) {
+void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, int bottom) {
if (bottom <= top)
return;
@@ -491,26 +486,26 @@ void Gdi::drawStripToScreen(VirtScreen *vs, int x, int width, int top, int botto
assert(top >= 0 && bottom <= vs->h); // Paranoia checks
assert(x >= 0 && width <= vs->pitch);
- assert(_textSurface.pixels);
+ assert(_charset->_textSurface.pixels);
assert(_compositeBuf);
if (width > vs->w - x)
width = vs->w - x;
// Clip to the visible part of the scene
- if (top < _vm->_screenTop)
- top = _vm->_screenTop;
- if (bottom > _vm->_screenTop + _vm->_screenHeight)
- bottom = _vm->_screenTop + _vm->_screenHeight;
+ if (top < _screenTop)
+ top = _screenTop;
+ if (bottom > _screenTop + _screenHeight)
+ bottom = _screenTop + _screenHeight;
// Convert the vertical coordinates to real screen coords
- int y = vs->topline + top - _vm->_screenTop;
+ int y = vs->topline + top - _screenTop;
int height = bottom - top;
// Compute screen etc. buffer pointers
const byte *src = vs->getPixels(x, top);
- byte *dst = _compositeBuf + x + y * _vm->_screenWidth;
- const byte *text = (byte *)_textSurface.pixels + x + y * _textSurface.pitch;
+ byte *dst = _compositeBuf + x + y * _screenWidth;
+ const byte *text = (byte *)_charset->_textSurface.pixels + x + y * _charset->_textSurface.pitch;
#ifdef __PALM_OS__
ARM_START(DrawStripType)
@@ -520,9 +515,9 @@ void Gdi::drawStripToScreen(VirtScreen *vs, int x, int width, int top, int botto
ARM_ADDM(src)
ARM_ADDM(dst)
ARM_ADDM(text)
- ARM_ADDV(_vm_screenWidth, _vm->_screenWidth)
+ ARM_ADDV(_vm_screenWidth, _screenWidth)
ARM_ADDV(vs_pitch, vs->pitch)
- ARM_ADDV(_textSurface_pitch, _textSurface.pitch)
+ ARM_ADDV(_charset->_textSurface_pitch, _charset->_textSurface.pitch)
ARM_CALL(ARM_ENGINE, PNO_DATA())
ARM_CONTINUE()
#endif
@@ -535,18 +530,18 @@ void Gdi::drawStripToScreen(VirtScreen *vs, int x, int width, int top, int botto
dst[w] = text[w];
}
src += vs->pitch;
- dst += _vm->_screenWidth;
- text += _textSurface.pitch;
+ dst += _screenWidth;
+ text += _charset->_textSurface.pitch;
}
- if (_vm->_renderMode == Common::kRenderCGA)
- ditherCGA(_compositeBuf + x + y * _vm->_screenWidth, _vm->_screenWidth, x, y, width, height);
+ if (_renderMode == Common::kRenderCGA)
+ gdi.ditherCGA(_compositeBuf + x + y * _screenWidth, _screenWidth, x, y, width, height);
- if (_vm->_renderMode == Common::kRenderHercA || _vm->_renderMode == Common::kRenderHercG) {
- ditherHerc(_compositeBuf + x + y * _vm->_screenWidth, _herculesBuf, _vm->_screenWidth, &x, &y, &width, &height);
+ if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
+ gdi.ditherHerc(_compositeBuf + x + y * _screenWidth, _herculesBuf, _screenWidth, &x, &y, &width, &height);
// center image on the screen
- _vm->_system->copyRectToScreen(_herculesBuf + x + y * Common::kHercW,
- Common::kHercW, x + (Common::kHercW - _vm->_screenWidth * 2) / 2, y, width, height);
+ _system->copyRectToScreen(_herculesBuf + x + y * Common::kHercW,
+ Common::kHercW, x + (Common::kHercW - _screenWidth * 2) / 2, y, width, height);
} else {
// Finally blit the whole thing to the screen
int x1 = x;
@@ -555,11 +550,11 @@ void Gdi::drawStripToScreen(VirtScreen *vs, int x, int width, int top, int botto
// NES can address negative number sprites and that poses problem for
// our code. So instead adding zillions of fixes and potentially break
// other games we shift it right on rendering stage
- if (_vm->_features & GF_NES && ((_vm->_NESStartStrip > 0) || (vs->number != kMainVirtScreen))) {
+ if (_features & GF_NES && ((_NESStartStrip > 0) || (vs->number != kMainVirtScreen))) {
x += 16;
}
- _vm->_system->copyRectToScreen(_compositeBuf + x1 + y * _vm->_screenWidth, _vm->_screenWidth, x, y, width, height);
+ _system->copyRectToScreen(_compositeBuf + x1 + y * _screenWidth, _screenWidth, x, y, width, height);
}
}
@@ -810,14 +805,12 @@ void ScummEngine::redrawBGStrip(int start, int num) {
for (int i = 0; i < num; i++)
setGfxUsageBit(s + i, USAGE_BIT_DIRTY);
- if (_version == 1) {
- gdi._objectMode = false;
- }
if (_heversion >= 70)
room = getResourceAddress(rtRoomImage, _roomResource);
else
room = getResourceAddress(rtRoom, _roomResource);
+ gdi._objectMode = false;
gdi.drawBitmap(room + _IM00_offs,
&virtscr[0], s, 0, _roomWidth, virtscr[0].h, s, num, 0, _roomStrips);
}
@@ -856,8 +849,8 @@ void ScummEngine::restoreBG(Common::Rect rect, byte backColor) {
if (vs->hasTwoBuffers && _currentRoom != 0 && isLightOn()) {
blit(screenBuf, vs->pitch, vs->getBackPixels(rect.left, rect.top), vs->pitch, width, height);
if (vs->number == kMainVirtScreen && _charset->_hasMask) {
- byte *mask = (byte *)gdi._textSurface.pixels + gdi._textSurface.pitch * (rect.top - _screenTop) + rect.left;
- fill(mask, gdi._textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height);
+ byte *mask = (byte *)_charset->_textSurface.pixels + _charset->_textSurface.pitch * (rect.top - _screenTop) + rect.left;
+ fill(mask, _charset->_textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height);
}
} else {
fill(screenBuf, vs->pitch, backColor, width, height);
@@ -898,7 +891,7 @@ void CharsetRenderer::restoreCharsetBg() {
if (vs->hasTwoBuffers) {
// Clean out the charset mask
- memset(_vm->gdi._textSurface.pixels, CHARSET_MASK_TRANSPARENCY, _vm->gdi._textSurface.pitch * _vm->gdi._textSurface.h);
+ memset(_textSurface.pixels, CHARSET_MASK_TRANSPARENCY, _textSurface.pitch * _textSurface.h);
}
}
}
@@ -1038,8 +1031,8 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) {
bgbuff = vs->getBackPixels(x, y);
blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
if (_charset->_hasMask) {
- byte *mask = (byte *)gdi._textSurface.pixels + gdi._textSurface.pitch * (y - _screenTop) + x;
- fill(mask, gdi._textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height);
+ byte *mask = (byte *)_charset->_textSurface.pixels + _charset->_textSurface.pitch * (y - _screenTop) + x;
+ fill(mask, _charset->_textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height);
}
} else {
fill(backbuff, vs->pitch, color, width, height);
diff --git a/scumm/gfx.h b/scumm/gfx.h
index 6d031545dd..c1e70c005d 100644
--- a/scumm/gfx.h
+++ b/scumm/gfx.h
@@ -211,12 +211,7 @@ public:
Gdi(ScummEngine *vm);
- Graphics::Surface _textSurface;
-
protected:
- byte *_compositeBuf;
- byte *_herculesBuf;
-
byte *_roomPalette;
byte _decomp_shr, _decomp_mask;
byte _transparentColor;
@@ -269,8 +264,6 @@ protected:
void decompressMaskImg(byte *dst, const byte *src, int height) const;
/* Misc */
- void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
- void updateDirtyScreen(VirtScreen *vs);
void ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const;
void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height) const;
diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp
index f96a3e9ac6..28a8dc466d 100644
--- a/scumm/scumm.cpp
+++ b/scumm/scumm.cpp
@@ -807,8 +807,10 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
_doEffect = false;
memset(&_flashlight, 0, sizeof(_flashlight));
_roomStrips = 0;
+ _compositeBuf = 0;
+ _herculesBuf = 0;
_bompActorPalettePtr = NULL;
- _shakeEnabled= false;
+ _shakeEnabled = false;
_shakeFrame = 0;
_screenStartStrip = 0;
_screenEndStrip = 0;
diff --git a/scumm/scumm.h b/scumm/scumm.h
index 3d487f483a..7b324e3df7 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -984,8 +984,12 @@ public:
markRectAsDirty(virt, rect.left, rect.right, rect.top, rect.bottom, dirtybit);
}
protected:
+ // Screen rendering
+ byte *_compositeBuf;
+ byte *_herculesBuf;
void drawDirtyScreenParts();
void updateDirtyScreen(VirtScreenNumber slot);
+ void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
public:
VirtScreen *findVirtScreen(int y);