aboutsummaryrefslogtreecommitdiff
path: root/queen
diff options
context:
space:
mode:
authorGregory Montoir2004-01-04 20:25:21 +0000
committerGregory Montoir2004-01-04 20:25:21 +0000
commit143b5bea80762464b4d29040b101ec606703a73f (patch)
tree373bf839bcce32e0444c761c7bc3e4d24385aaff /queen
parent9d547b183bfd56d94ec0b644f3ae12b668fd864e (diff)
downloadscummvm-rg350-143b5bea80762464b4d29040b101ec606703a73f.tar.gz
scummvm-rg350-143b5bea80762464b4d29040b101ec606703a73f.tar.bz2
scummvm-rg350-143b5bea80762464b4d29040b101ec606703a73f.zip
- added code to only redraw changed blocks in order to avoid full screen refresh
- minor code cleanup in Graphics/Display svn-id: r12147
Diffstat (limited to 'queen')
-rw-r--r--queen/display.cpp387
-rw-r--r--queen/display.h87
-rw-r--r--queen/graphics.cpp27
-rw-r--r--queen/graphics.h12
-rw-r--r--queen/journal.cpp9
-rw-r--r--queen/logic.cpp32
-rw-r--r--queen/queen.cpp2
-rw-r--r--queen/xref.txt12
8 files changed, 312 insertions, 256 deletions
diff --git a/queen/display.cpp b/queen/display.cpp
index 969cd40a44..15351be3e1 100644
--- a/queen/display.cpp
+++ b/queen/display.cpp
@@ -29,93 +29,31 @@
namespace Queen {
-void TextRenderer::init() {
- // calculate font justification sizes
- uint16 i, y, x;
-
- for (i = 0; i < 256; ++i) {
- _charWidth[i] = 0;
- for (y = 0; y < 8; ++y) {
- uint8 c = _font[i * 8 + y];
- for (x = 0; x < 8; ++x) {
- if ((c & (0x80 >> x)) && (x > _charWidth[i])) {
- _charWidth[i] = x;
- }
- }
- }
- _charWidth[i] += 2;
- }
- _charWidth[(uint8)' '] = 4;
- --_charWidth[(uint8)'^'];
-}
-
-
-void TextRenderer::drawString(uint8 *dstBuf, uint16 dstPitch, uint16 x, uint16 y, uint8 color, const char *text, bool outlined) {
- const uint8 *str = (const uint8*)text;
- while (*str && x < dstPitch) {
-
- uint8 c = (_lang == FRENCH && *str == 0x96) ? 0xFB : *str;
- const uint8 *pchr = _font + c * 8;
-
- if (outlined) {
- drawChar(dstBuf, dstPitch, x - 1, y - 1, INK_OUTLINED_TEXT, pchr);
- drawChar(dstBuf, dstPitch, x , y - 1, INK_OUTLINED_TEXT, pchr);
- drawChar(dstBuf, dstPitch, x + 1, y - 1, INK_OUTLINED_TEXT, pchr);
- drawChar(dstBuf, dstPitch, x + 1, y , INK_OUTLINED_TEXT, pchr);
- drawChar(dstBuf, dstPitch, x + 1, y + 1, INK_OUTLINED_TEXT, pchr);
- drawChar(dstBuf, dstPitch, x , y + 1, INK_OUTLINED_TEXT, pchr);
- drawChar(dstBuf, dstPitch, x - 1, y + 1, INK_OUTLINED_TEXT, pchr);
- drawChar(dstBuf, dstPitch, x - 1, y , INK_OUTLINED_TEXT, pchr);
- }
- drawChar(dstBuf, dstPitch, x, y, color, pchr);
-
- x += _charWidth[ c ];
- ++str;
- }
-}
-
-
-void TextRenderer::drawChar(uint8 *dstBuf, uint16 dstPitch, uint16 x, uint16 y, uint8 color, const uint8 *chr) {
- dstBuf += dstPitch * y + x;
- uint16 j, i;
- for (j = 0; j < 8; ++j) {
- uint8 *p = dstBuf;
- uint8 c = *chr++;
- if (c != 0) {
- for (i = 0; i < 8; ++i) {
- if(c & 0x80) {
- *p = color;
- }
- ++p;
- c <<= 1;
- }
- }
- dstBuf += dstPitch;
- }
-}
+Display::Display(QueenEngine *vm, OSystem *system)
+ : _horizontalScroll(0), _system(system), _vm(vm) {
+ _dynalum.prevColMask = 0xFF;
+ initFont();
+ _screenBuf = new uint8[SCREEN_W * SCREEN_H];
+ _panelBuf = new uint8[PANEL_W * PANEL_H];
+ _backdropBuf = new uint8[BACKDROP_W * BACKDROP_H];
+ memset(_screenBuf, 0, SCREEN_W * SCREEN_H);
+ memset(_panelBuf, 0, PANEL_W * PANEL_H);
+ memset(_backdropBuf, 0, BACKDROP_W * BACKDROP_H);
-Display::Display(QueenEngine *vm, Language language, OSystem *system)
- : _horizontalScroll(0), _curBlankingEffect(0), _system(system), _vm(vm) {
- _dynalum.prevColMask = 0xFF;
- _textRenderer._lang = language;
- _textRenderer.init();
-
- _buffer[RB_BACKDROP] = new uint8[BACKDROP_W * BACKDROP_H];
- _buffer[RB_PANEL] = new uint8[PANEL_W * PANEL_H];
- _buffer[RB_SCREEN] = new uint8[SCREEN_W * SCREEN_H];
- memset(_buffer[RB_BACKDROP], 0, BACKDROP_W * BACKDROP_H);
- memset(_buffer[RB_PANEL], 0, PANEL_W * PANEL_H);
- memset(_buffer[RB_SCREEN], 0, SCREEN_W * SCREEN_H);
- _bufPitch[RB_BACKDROP] = BACKDROP_W;
- _bufPitch[RB_PANEL] = PANEL_W;
- _bufPitch[RB_SCREEN] = SCREEN_W;
+ _fullRefresh = true;
+ _dirtyBlocksWidth = SCREEN_W / D_BLOCK_W;
+ _dirtyBlocksHeight = SCREEN_H / D_BLOCK_H;
+ _dirtyBlocks = new uint8[_dirtyBlocksWidth * _dirtyBlocksHeight];
+ memset(_dirtyBlocks, 0, _dirtyBlocksWidth * _dirtyBlocksHeight);
_pal.room = new uint8[ 256 * 3 ];
_pal.screen = new uint8[ 256 * 3 ];
+ _pal.panel = new uint8[ 112 * 3 ];
memset(_pal.room, 0, 256 * 3);
memset(_pal.screen, 0, 256 * 3);
+ memset(_pal.panel, 0, 112 * 3);
_pal.dirtyMin = 0;
_pal.dirtyMax = 255;
_pal.scrollable = true;
@@ -123,12 +61,13 @@ Display::Display(QueenEngine *vm, Language language, OSystem *system)
Display::~Display() {
- delete[] _buffer[RB_BACKDROP];
- delete[] _buffer[RB_PANEL];
- delete[] _buffer[RB_SCREEN];
+ delete[] _backdropBuf;
+ delete[] _panelBuf;
+ delete[] _screenBuf;
delete[] _pal.room;
delete[] _pal.screen;
+ delete[] _pal.panel;
}
@@ -222,23 +161,25 @@ void Display::palSet(const uint8 *pal, int start, int end, bool updateScreen) {
}
-void Display::palSetJoe(JoePalette pal) {
- debug(9, "Display::palSetJoe(%d)", pal);
- const uint8 *palJoe = NULL;
- switch (pal) {
- case JP_CLOTHES:
- palJoe = _palJoeClothes;
- break;
- case JP_DRESS:
- palJoe = _palJoeDress;
- break;
- }
- memcpy(_pal.room + 144 * 3, palJoe, 16 * 3);
- memcpy(_pal.screen + 144 * 3, palJoe, 16 * 3);
+void Display::palSetJoeDress() {
+ memcpy(_pal.room + 144 * 3, _palJoeDress, 16 * 3);
+ memcpy(_pal.screen + 144 * 3, _palJoeDress, 16 * 3);
palSet(_pal.screen, 144, 159, true);
}
+void Display::palSetJoeNormal() {
+ memcpy(_pal.room + 144 * 3, _palJoeClothes, 16 * 3);
+ memcpy(_pal.screen + 144 * 3, _palJoeClothes, 16 * 3);
+ palSet(_pal.screen, 144, 159, true);
+}
+
+
+void Display::palSetPanel() {
+ warning("Display::palSetPanel()");
+}
+
+
void Display::palFadeIn(int start, int end, uint16 roomNum, bool dynalum, int16 dynaX, int16 dynaY) {
debug(9, "Display::palFadeIn(%d, %d)", start, end);
memcpy(_pal.screen, _pal.room, 256 * 3);
@@ -633,21 +574,16 @@ void Display::screenMode(int comPanel, bool inCutaway) {
void Display::prepareUpdate() {
- if (!_fullscreen) {
- // draw the panel
- memcpy(_buffer[RB_SCREEN] + _bufPitch[RB_SCREEN] * ROOM_ZONE_HEIGHT,
- _buffer[RB_PANEL], PANEL_W * PANEL_H);
- }
-
- // draw the backdrop bitmap
+ if (!_fullscreen)
+ memcpy(_screenBuf + SCREEN_W * ROOM_ZONE_HEIGHT, _panelBuf, PANEL_W * PANEL_H);
int i;
int n = _fullscreen ? 200 : 150;
- uint8 *dst = _buffer[RB_SCREEN];
- uint8 *src = _buffer[RB_BACKDROP] + _horizontalScroll;
+ uint8 *dst = _screenBuf;
+ uint8 *src = _backdropBuf + _horizontalScroll;
for (i = 0; i < n; ++i) {
- memcpy(dst, src, _bufPitch[RB_SCREEN]);
- dst += _bufPitch[RB_SCREEN];
- src += _bufPitch[RB_BACKDROP];
+ memcpy(dst, src, SCREEN_W);
+ dst += SCREEN_W;
+ src += BACKDROP_W;
}
}
@@ -661,24 +597,78 @@ void Display::update(bool dynalum, int16 dynaX, int16 dynaY) {
_pal.dirtyMin = 144;
_pal.dirtyMax = 144;
}
- drawScreen();
+// _fullRefresh = true;
+ if (_fullRefresh) {
+ _system->copy_rect(_screenBuf, SCREEN_W, 0, 0, SCREEN_W, SCREEN_H);
+ _fullRefresh = false;
+ debug(7, "Display::update() - Full blit");
+ } else {
+ uint16 count = 0;
+ uint8 *scrBuf = _screenBuf;
+ uint8 *dbBuf = _dirtyBlocks;
+ uint16 i, j, x;
+ for (j = 0; j < _dirtyBlocksHeight; ++j) {
+ uint16 accW = 0;
+ for (i = 0; i < _dirtyBlocksWidth; ++i) {
+ if (dbBuf[i] != 0) {
+ --dbBuf[i];
+ ++accW;
+ } else if (accW != 0) {
+ x = (i - accW) * D_BLOCK_W;
+ _system->copy_rect(scrBuf + x, SCREEN_W, x, j * D_BLOCK_H, accW * D_BLOCK_W, D_BLOCK_H);
+ accW = 0;
+ ++count;
+ }
+ }
+ if (accW != 0) {
+ x = (_dirtyBlocksWidth - accW) * D_BLOCK_W;
+ _system->copy_rect(scrBuf + x, SCREEN_W, x, j * D_BLOCK_H, accW * D_BLOCK_W, D_BLOCK_H);
+ ++count;
+ }
+ dbBuf += _dirtyBlocksWidth;
+ scrBuf += SCREEN_W * D_BLOCK_H;
+ }
+ debug(7, "Display::update() - Dirtyblocks blit (%d)", count);
+ }
+ _system->update_screen();
+ waitForTimer();
+}
+
+
+void Display::drawBobSprite(const uint8 *data, uint16 x, uint16 y, uint16 w, uint16 h, uint16 pitch, bool xflip) {
+ blit(_screenBuf, SCREEN_W, x, y, data, pitch, w, h, xflip, true);
+ setDirtyBlock(xflip ? (x - w + 1) : x, y, w, h);
+}
+
+
+void Display::drawBobPasteDown(const uint8 *data, uint16 x, uint16 y, uint16 w, uint16 h) {
+ blit(_backdropBuf, BACKDROP_W, x, y, data, w, w, h, false, true);
}
-void Display::blit(RenderingBuffer dst, uint16 dstX, uint16 dstY, const uint8 *srcBuf, uint16 srcW, uint16 srcH, uint16 srcPitch, bool xflip, bool masked) {
- uint16 dstPitch = _bufPitch[dst];
- uint8 *dstBuf = _buffer[dst] + dstPitch * dstY + dstX;
+void Display::drawInventoryItem(const uint8 *data, uint16 x, uint16 y, uint16 w, uint16 h) {
+ if (data != NULL) {
+ blit(_panelBuf, PANEL_W, x, y, data, w, w, h, false, false);
+ } else {
+ fill(_panelBuf, PANEL_W, x, y, w, h, INK_BG_PANEL);
+ }
+ setDirtyBlock(x, 150 + y, w, h);
+}
+
+void Display::blit(uint8 *dstBuf, uint16 dstPitch, uint16 x, uint16 y, const uint8 *srcBuf, uint16 srcPitch, uint16 w, uint16 h, bool xflip, bool masked) {
+ assert(w <= dstPitch);
+ dstBuf += dstPitch * y + x;
if (!masked) { // Unmasked always unflipped
- while (srcH--) {
- memcpy(dstBuf, srcBuf, srcW);
+ while (h--) {
+ memcpy(dstBuf, srcBuf, w);
srcBuf += srcPitch;
dstBuf += dstPitch;
}
} else if (!xflip) { // Masked bitmap unflipped
- while (srcH--) {
+ while (h--) {
int i;
- for(i = 0; i < srcW; ++i) {
+ for(i = 0; i < w; ++i) {
uint8 b = *(srcBuf + i);
if(b != 0) {
*(dstBuf + i) = b;
@@ -688,25 +678,24 @@ void Display::blit(RenderingBuffer dst, uint16 dstX, uint16 dstY, const uint8 *s
dstBuf += dstPitch;
}
} else { // Masked bitmap flipped
- while (srcH--) {
+ while (h--) {
int i;
- for(i = 0; i < srcW; ++i) {
+ for(i = 0; i < w; ++i) {
uint8 b = *(srcBuf + i);
if(b != 0) {
*(dstBuf - i) = b;
}
}
srcBuf += srcPitch;
- dstBuf += dstPitch;
+ dstBuf += dstPitch;
}
}
}
-void Display::fill(RenderingBuffer dst, uint16 x, uint16 y, uint16 w, uint16 h, uint8 color) {
- assert(w <= _bufPitch[dst]);
- uint16 dstPitch = _bufPitch[dst];
- uint8 *dstBuf = _buffer[dst] + dstPitch * y + x;
+void Display::fill(uint8 *dstBuf, uint16 dstPitch, uint16 x, uint16 y, uint16 w, uint16 h, uint8 color) {
+ assert(w <= dstPitch);
+ dstBuf += dstPitch * y + x;
while (h--) {
memset(dstBuf, color, w);
dstBuf += dstPitch;
@@ -735,20 +724,23 @@ void Display::readPCX(uint8 *dst, uint16 dstPitch, const uint8 *src, uint16 w, u
void Display::readPCXBackdrop(const uint8 *pcxBuf, uint32 size, bool useFullPal) {
_bdWidth = READ_LE_UINT16(pcxBuf + 12);
_bdHeight = READ_LE_UINT16(pcxBuf + 14);
- readPCX(_buffer[RB_BACKDROP], _bufPitch[RB_BACKDROP], pcxBuf + 128, _bdWidth, _bdHeight);
+ readPCX(_backdropBuf, BACKDROP_W, pcxBuf + 128, _bdWidth, _bdHeight);
memcpy(_pal.room, pcxBuf + size - 768, useFullPal ? 256 * 3 : 144 * 3);
}
void Display::readPCXPanel(const uint8 *pcxBuf, uint32 size) {
- uint8 *dst = _buffer[RB_PANEL] + PANEL_W * 10;
+ uint8 *dst = _panelBuf + PANEL_W * 10;
readPCX(dst, PANEL_W, pcxBuf + 128, PANEL_W, PANEL_H - 10);
- memcpy(_pal.room + 144 * 3, pcxBuf + size - 768 + 144 * 3, (256 - 144) * 3);
+ const uint8 *pal = pcxBuf + size - 768 + 144 * 3;
+ memcpy(_pal.room + 144 * 3, pal, (256 - 144) * 3);
+ memcpy(_pal.panel, pal, (256 - 144) * 3);
}
void Display::horizontalScrollUpdate(int16 xCamera) {
debug(9, "Display::horizontalScrollUpdate(%d)", xCamera);
+ int16 hs = _horizontalScroll;
_horizontalScroll = 0;
if (_bdWidth > 320) {
if (xCamera > 160 && xCamera < 480) {
@@ -757,6 +749,30 @@ void Display::horizontalScrollUpdate(int16 xCamera) {
_horizontalScroll = 320;
}
}
+ if (hs != _horizontalScroll) {
+ _fullRefresh = true;
+ }
+}
+
+
+void Display::setDirtyBlock(uint16 x, uint16 y, uint16 w, uint16 h) {
+ if (!_fullRefresh) {
+ uint16 ex = (x + w - 1) / D_BLOCK_W;
+ uint16 ey = (y + h - 1) / D_BLOCK_H;
+ x /= D_BLOCK_W;
+ y /= D_BLOCK_H;
+ uint16 cy = ey - y + 1;
+ uint16 cx = ex - x + 1;
+ if (cy >= _dirtyBlocksHeight) cy = _dirtyBlocksHeight - 1;
+ if (cx >= _dirtyBlocksWidth) cx = _dirtyBlocksWidth - 1;
+ uint8 *p = _dirtyBlocks + _dirtyBlocksWidth * y + x;
+ while (cy--) {
+ for (uint16 i = 0; i < cx; ++i) {
+ p[i] = 2;
+ }
+ p += _dirtyBlocksWidth;
+ }
+ }
}
@@ -774,7 +790,7 @@ void Display::waitForTimer() {
void Display::setMouseCursor(uint8 *buf, uint16 w, uint16 h, uint16 xhs, uint16 yhs) {
- // change transparency color match the one expected by the backend (0xFF)
+ // change transparency color to match the one expected by the backend (0xFF)
uint16 size = w * h;
uint8 *p = buf;
while (size--) {
@@ -794,53 +810,106 @@ void Display::showMouseCursor(bool show) {
}
+void Display::initFont() {
+ // calculate font justification sizes
+ uint16 i, y, x;
+
+ for (i = 0; i < 256; ++i) {
+ _charWidth[i] = 0;
+ for (y = 0; y < 8; ++y) {
+ uint8 c = _font[i * 8 + y];
+ for (x = 0; x < 8; ++x) {
+ if ((c & (0x80 >> x)) && (x > _charWidth[i])) {
+ _charWidth[i] = x;
+ }
+ }
+ }
+ _charWidth[i] += 2;
+ }
+ _charWidth[(uint8)' '] = 4;
+ --_charWidth[(uint8)'^'];
+}
+
+
uint16 Display::textWidth(const char *text) const {
uint16 len = 0;
while (*text) {
- len += _textRenderer._charWidth[ (uint8)*text ];
+ len += _charWidth[ (uint8)*text ];
++text;
}
return len;
}
+void Display::drawChar(uint16 x, uint16 y, uint8 color, const uint8 *chr) {
+ uint8 *dstBuf = _screenBuf + SCREEN_W * y + x;
+ uint16 j, i;
+ for (j = 0; j < 8; ++j) {
+ uint8 *p = dstBuf;
+ uint8 c = *chr++;
+ if (c != 0) {
+ for (i = 0; i < 8; ++i) {
+ if(c & 0x80) {
+ *p = color;
+ }
+ ++p;
+ c <<= 1;
+ }
+ }
+ dstBuf += SCREEN_W;
+ }
+}
+
+
void Display::drawText(uint16 x, uint16 y, uint8 color, const char *text, bool outlined) {
- debug(9, "Display::drawText(%s)", text);
- _textRenderer.drawString(_buffer[RB_SCREEN], _bufPitch[RB_SCREEN], x, y, color, text, outlined);
+ const uint8 *str = (const uint8*)text;
+ uint16 xs = x;
+ while (*str && x < SCREEN_W) {
+
+ uint8 c = (_vm->resource()->getLanguage() == FRENCH && *str == 0x96) ? 0xFB : *str;
+ const uint8 *pchr = _font + c * 8;
+
+ if (outlined) {
+ drawChar(x - 1, y - 1, INK_OUTLINED_TEXT, pchr);
+ drawChar(x , y - 1, INK_OUTLINED_TEXT, pchr);
+ drawChar(x + 1, y - 1, INK_OUTLINED_TEXT, pchr);
+ drawChar(x + 1, y , INK_OUTLINED_TEXT, pchr);
+ drawChar(x + 1, y + 1, INK_OUTLINED_TEXT, pchr);
+ drawChar(x , y + 1, INK_OUTLINED_TEXT, pchr);
+ drawChar(x - 1, y + 1, INK_OUTLINED_TEXT, pchr);
+ drawChar(x - 1, y , INK_OUTLINED_TEXT, pchr);
+ }
+ drawChar(x, y, color, pchr);
+
+ x += _charWidth[ c ];
+ ++str;
+ }
+ setDirtyBlock(xs - 1, y - 1, x - xs + 2, 8 + 2);
}
void Display::drawBox(int16 x1, int16 y1, int16 x2, int16 y2, uint8 col) {
- uint8 *p = _buffer[RB_SCREEN];
- uint16 pitch = _bufPitch[RB_SCREEN];
-
+ uint8 *p = _screenBuf;
int i;
for (i = y1; i <= y2; ++i) {
- *(p + i * pitch + x1) = *(p + i * pitch + x2) = col;
+ *(p + i * SCREEN_W + x1) = *(p + i * SCREEN_W + x2) = col;
}
for (i = x1; i <= x2; ++i) {
- *(p + y1 * pitch + i) = *(p + y2 * pitch + i) = col;
+ *(p + y1 * SCREEN_W + i) = *(p + y2 * SCREEN_W + i) = col;
}
}
-void Display::drawScreen() {
- _system->copy_rect(_buffer[RB_SCREEN], _bufPitch[RB_SCREEN], 0, 0, SCREEN_W, SCREEN_H);
- _system->update_screen();
- waitForTimer();
-}
-
-
-
void Display::blankScreen() {
+ static int current = 0;
typedef void (Display::*BlankerEffect)();
static const BlankerEffect effects[] = {
&Display::blankScreenEffect1,
&Display::blankScreenEffect2,
&Display::blankScreenEffect3
};
- (this->*effects[_curBlankingEffect])();
- _curBlankingEffect = (_curBlankingEffect + 1) % ARRAYSIZE(effects);
+ (this->*effects[current])();
+ current = (current + 1) % ARRAYSIZE(effects);
}
@@ -850,12 +919,12 @@ void Display::blankScreenEffect1() {
for(int i = 0; i < 2; ++i) {
uint16 x = _vm->randomizer.getRandomNumber(SCREEN_W - 32 - 2) + 1;
uint16 y = _vm->randomizer.getRandomNumber(SCREEN_H - 32 - 2) + 1;
- uint8 *p = _buffer[RB_SCREEN] + _bufPitch[RB_SCREEN] * y + x;
+ uint8 *p = _screenBuf + SCREEN_W * y + x;
uint8 *q = buf;
uint16 h = 32;
while (h--) {
memcpy(q, p, 32);
- p += _bufPitch[RB_SCREEN];
+ p += SCREEN_W;
q += 32;
}
if (_vm->randomizer.getRandomNumber(1)) {
@@ -880,7 +949,7 @@ void Display::blankScreenEffect2() {
while (_vm->input()->idleTime() >= Input::DELAY_SCREEN_BLANKER) {
uint16 x = _vm->randomizer.getRandomNumber(SCREEN_W - 2);
uint16 y = _vm->randomizer.getRandomNumber(SCREEN_H - 2);
- uint8 *p = _buffer[RB_SCREEN] + y * _bufPitch[RB_SCREEN] + x;
+ uint8 *p = _screenBuf + y * SCREEN_W + x;
uint8 c = 0;
switch (_vm->randomizer.getRandomNumber(3)) {
case 0:
@@ -890,10 +959,10 @@ void Display::blankScreenEffect2() {
c = *(p + 1);
break;
case 2:
- c = *(p + _bufPitch[RB_SCREEN]);
+ c = *(p + SCREEN_W);
break;
case 3:
- c = *(p + _bufPitch[RB_SCREEN] + 1);
+ c = *(p + SCREEN_W + 1);
break;
default:
break;
@@ -902,9 +971,9 @@ void Display::blankScreenEffect2() {
int j = 2;
while (j--) {
memset(p, c, 2);
- p += _bufPitch[RB_SCREEN];
+ p += SCREEN_W;
}
- _system->copy_rect(buf, _bufPitch[RB_SCREEN], x, y, 2, 2);
+ _system->copy_rect(buf, SCREEN_W, x, y, 2, 2);
_system->update_screen();
waitForTimer();
}
@@ -915,25 +984,25 @@ void Display::blankScreenEffect3() {
uint32 i = 0;
while (_vm->input()->idleTime() >= Input::DELAY_SCREEN_BLANKER) {
if (i > 4000000) {
- memset(_buffer[RB_SCREEN], 0, SCREEN_W * SCREEN_H);
- _system->copy_rect(_buffer[RB_SCREEN], _bufPitch[RB_SCREEN], 0, 0, SCREEN_W, SCREEN_H);
+ memset(_screenBuf, 0, SCREEN_W * SCREEN_H);
+ _system->copy_rect(_screenBuf, SCREEN_W, 0, 0, SCREEN_W, SCREEN_H);
} else {
uint16 x = _vm->randomizer.getRandomNumber(SCREEN_W - 2);
uint16 y = _vm->randomizer.getRandomNumber(SCREEN_H - 2);
- uint8 *p = _buffer[RB_SCREEN] + _bufPitch[RB_SCREEN] * y + x;
+ uint8 *p = _screenBuf + SCREEN_W * y + x;
uint8 p0 = *p;
uint8 p1 = *(p + 1);
- uint8 p2 = *(p + _bufPitch[RB_SCREEN]);
- uint8 p3 = *(p + _bufPitch[RB_SCREEN] + 1);
+ uint8 p2 = *(p + SCREEN_W);
+ uint8 p3 = *(p + SCREEN_W + 1);
uint8 c = (p0 + p1 + p2 + p3) / 4;
uint8 *buf = p;
int j = 2;
while (j--) {
memset(p, c, 2);
- p += _bufPitch[RB_SCREEN];
+ p += SCREEN_W;
}
++i;
- _system->copy_rect(buf, _bufPitch[RB_SCREEN], x, y, 2, 2);
+ _system->copy_rect(buf, SCREEN_W, x, y, 2, 2);
}
_system->update_screen();
waitForTimer();
@@ -941,7 +1010,7 @@ void Display::blankScreenEffect3() {
}
-const uint8 TextRenderer::_font[] = {
+const uint8 Display::_font[] = {
0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0,
0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80,
0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0,
diff --git a/queen/display.h b/queen/display.h
index 1317a81fdd..ae3708d5dc 100644
--- a/queen/display.h
+++ b/queen/display.h
@@ -27,44 +27,12 @@
namespace Queen {
-
-enum RenderingBuffer {
- RB_BACKDROP = 0,
- RB_PANEL = 1,
- RB_SCREEN = 2,
- RB_MINI = 3
-};
-
-enum JoePalette {
- JP_CLOTHES = 0,
- JP_DRESS = 1
-};
-
-
-struct Dynalum {
- bool valid;
- uint8 msk[50 * 160];
- int8 lum[8 * 3];
- uint8 prevColMask;
-};
-
-
-struct TextRenderer {
- void init();
- void drawString(uint8 *dstBuf, uint16 dstPitch, uint16 x, uint16 y, uint8 color, const char *text, bool outlined = true);
- void drawChar(uint8 *dstBuf, uint16 dstPitch, uint16 x, uint16 y, uint8 color, const uint8 *chr);
-
- Language _lang;
- uint8 _charWidth[256];
- static const uint8 _font[];
-};
-
class QueenEngine;
class Display {
public:
- Display(QueenEngine *vm, Language language, OSystem *system);
+ Display(QueenEngine *vm, OSystem *system);
~Display();
void dynalumInit(const char *roomName, uint16 roomNum);
@@ -72,7 +40,9 @@ public:
void palConvert(uint8 *outPal, const uint8 *inPal, int start, int end);
void palSet(const uint8 *pal, int start, int end, bool updateScreen = false);
- void palSetJoe(JoePalette pal);
+ void palSetJoeDress();
+ void palSetJoeNormal();
+ void palSetPanel();
void palFadeIn(int start, int end, uint16 roomNum, bool dynalum = false, int16 dynaX = 0, int16 dynaY = 0);
void palFadeOut(int start, int end, uint16 roomNum);
void palFadePanel();
@@ -89,40 +59,52 @@ public:
void prepareUpdate();
void update(bool dynalum = false, int16 dynaX = 0, int16 dynaY = 0);
- void blit(RenderingBuffer dstBuf, uint16 dstX, uint16 dstY, const uint8 *srcBuf, uint16 srcW, uint16 srcH, uint16 srcPitch, bool xflip, bool masked);
- void fill(RenderingBuffer dstBuf, uint16 x, uint16 y, uint16 w, uint16 h, uint8 color);
+ void drawBobSprite(const uint8 *data, uint16 x, uint16 y, uint16 w, uint16 h, uint16 pitch, bool xflip);
+ void drawBobPasteDown(const uint8 *data, uint16 x, uint16 y, uint16 w, uint16 h);
+ void drawInventoryItem(const uint8 *data, uint16 x, uint16 y, uint16 w, uint16 h);
+
+ void blit(uint8 *dstBuf, uint16 dstPitch, uint16 x, uint16 y, const uint8 *srcBuf, uint16 srcPitch, uint16 w, uint16 h, bool xflip, bool masked);
+ void fill(uint8 *dstBuf, uint16 dstPitch, uint16 x, uint16 y, uint16 w, uint16 h, uint8 color);
void readPCX(uint8 *dst, uint16 dstPitch, const uint8 *src, uint16 w, uint16 h);
void readPCXBackdrop(const uint8 *pcxBuf, uint32 size, bool useFullPal);
void readPCXPanel(const uint8 *pcxBuf, uint32 size);
void horizontalScrollUpdate(int16 xCamera);
- void horizontalScroll(int16 scroll) { _horizontalScroll = scroll; }
+ void horizontalScroll(int16 scroll) { _fullRefresh = true; _horizontalScroll = scroll; }
int16 horizontalScroll() const { return _horizontalScroll; }
- void fullscreen(bool fs) { debug(6, "Display::fullscreen(%d)", fs); _fullscreen = fs; }
+ void fullscreen(bool fs) { debug(6, "Display::fullscreen(%d)", fs); _fullRefresh = true; _fullscreen = fs; }
bool fullscreen() const { return _fullscreen; }
+ void setDirtyBlock(uint16 x, uint16 y, uint16 w, uint16 h);
+ void forceFullRefresh() { _fullRefresh = true; memset(_dirtyBlocks, 0, _dirtyBlocksWidth * _dirtyBlocksHeight); }
+
void handleTimer();
void waitForTimer();
void setMouseCursor(uint8 *buf, uint16 w, uint16 h, uint16 xhs, uint16 yhs);
void showMouseCursor(bool show);
+ void initFont();
+
uint16 textWidth(const char *text) const;
+ void drawChar(uint16 x, uint16 y, uint8 color, const uint8 *chr);
void drawText(uint16 x, uint16 y, uint8 color, const char *text, bool outlined = true);
void drawBox(int16 x1, int16 y1, int16 x2, int16 y2, uint8 col);
- void drawScreen();
void blankScreen();
void blankScreenEffect1();
void blankScreenEffect2();
void blankScreenEffect3();
+
private:
enum {
- FADE_SPEED = 16
+ FADE_SPEED = 16,
+ D_BLOCK_W = 8,
+ D_BLOCK_H = 8
};
enum BufferDimension {
@@ -134,30 +116,43 @@ private:
PANEL_H = 50
};
- TextRenderer _textRenderer;
-
struct {
uint8 *room;
uint8 *screen;
+ uint8 *panel;
int dirtyMin, dirtyMax;
bool scrollable;
} _pal;
- uint8 *_buffer[3];
- uint16 _bufPitch[3];
+ struct Dynalum {
+ bool valid;
+ uint8 msk[50 * 160];
+ int8 lum[8 * 3];
+ uint8 prevColMask;
+ };
+
+ uint8 *_screenBuf;
+ uint8 *_panelBuf;
+ uint8 *_backdropBuf;
+
+ bool _fullRefresh;
+ uint8 *_dirtyBlocks;
+ uint16 _dirtyBlocksWidth, _dirtyBlocksHeight;
bool _fullscreen;
uint16 _horizontalScroll;
uint16 _bdWidth, _bdHeight;
- bool _gotTick;
- int _curBlankingEffect;
+ uint8 _charWidth[256];
+
+ bool _gotTick;
Dynalum _dynalum;
OSystem *_system;
QueenEngine *_vm;
+ static const uint8 _font[];
static const uint8 _palJoeClothes[];
static const uint8 _palJoeDress[];
};
diff --git a/queen/graphics.cpp b/queen/graphics.cpp
index 4205f21ba9..3e82ecf756 100644
--- a/queen/graphics.cpp
+++ b/queen/graphics.cpp
@@ -339,26 +339,27 @@ void Graphics::bobDraw(const BobSlot *bs, int16 x, int16 y) {
src += w - w_new - x_skip;
x += w_new - 1;
}
- _vm->display()->blit(RB_SCREEN, x, y, src, w_new, h_new, w, bs->xflip, true);
+ _vm->display()->drawBobSprite(src, x, y, w_new, h_new, w, bs->xflip);
}
}
-void Graphics::bobDrawInventoryItem(uint32 bobnum, uint16 x, uint16 y) {
- if (bobnum == 0) {
- // clear panel area
- _vm->display()->fill(RB_PANEL, x, y, 32, 32, INK_BG_PANEL);
+void Graphics::bobDrawInventoryItem(uint32 frameNum, uint16 x, uint16 y) {
+ if (frameNum != 0) {
+ BobFrame *bf = frame(frameNum);
+ _vm->display()->drawInventoryItem(bf->data, x, y, bf->width, bf->height);
} else {
- BobFrame *pbf = &_frames[bobnum];
- _vm->display()->blit(RB_PANEL, x, y, pbf->data, pbf->width, pbf->height, pbf->width, false, false);
+ _vm->display()->drawInventoryItem(NULL, x, y, 32, 32);
}
}
-void Graphics::bobPaste(uint32 frameNum, int16 x, int16 y) {
- BobFrame *pbf = &_frames[frameNum];
- _vm->display()->blit(RB_BACKDROP, x, y, pbf->data, pbf->width, pbf->height, pbf->width, false, true);
- frameErase(frameNum);
+void Graphics::bobPaste(uint16 objNum, uint16 image) {
+ GraphicData *pgd = _vm->logic()->graphicData(objNum);
+ _vm->graphics()->bankUnpack(pgd->firstFrame, image, 15);
+ BobFrame *bf = frame(image);
+ _vm->display()->drawBobPasteDown(bf->data, pgd->x, pgd->y, bf->width, bf->height);
+ frameErase(image);
}
@@ -407,8 +408,8 @@ void Graphics::bobShrink(const BobFrame *bf, uint16 percentage) {
}
-void Graphics::bobClear(uint32 bobnum) {
- BobSlot *pbs = &_bobs[bobnum];
+void Graphics::bobClear(uint32 bobNum) {
+ BobSlot *pbs = bob(bobNum);
pbs->clear();
if (_vm->display()->fullscreen()) {
pbs->box.y2 = GAME_SCREEN_HEIGHT - 1;
diff --git a/queen/graphics.h b/queen/graphics.h
index 116bc464c6..87b8f6f151 100644
--- a/queen/graphics.h
+++ b/queen/graphics.h
@@ -117,13 +117,13 @@ public:
void bobSetupControl();
void bobDraw(const BobSlot *bs, int16 x, int16 y);
- void bobDrawInventoryItem(uint32 bobnum, uint16 x, uint16 y); // invbob()
- void bobPaste(uint32 frameNum, int16 x, int16 y); // bobpaste()
+ void bobDrawInventoryItem(uint32 frameNum, uint16 x, uint16 y);
+ void bobPaste(uint16 objNum, uint16 image);
void bobShrink(const BobFrame *bf, uint16 percentage);
- void bobClear(uint32 bobnum); // clearbob()
- void bobSortAll(); // sortbobs()
- void bobDrawAll(); // drawbobs()
- void bobClearAll(); // clearallbobs()
+ void bobClear(uint32 bobNum);
+ void bobSortAll();
+ void bobDrawAll();
+ void bobClearAll();
void bobStopAll();
BobSlot *bob(int index);
diff --git a/queen/journal.cpp b/queen/journal.cpp
index 2c16dcc3dc..ff1a16ba18 100644
--- a/queen/journal.cpp
+++ b/queen/journal.cpp
@@ -82,7 +82,7 @@ void Journal::use() {
break;
}
}
- g_system->delay_msecs(20);
+ system->delay_msecs(20);
}
_vm->logic()->writeOptionSettings();
@@ -103,6 +103,7 @@ void Journal::prepare() {
_vm->graphics()->bobClearAll();
_vm->graphics()->textClear(0, GAME_SCREEN_HEIGHT - 1);
_vm->graphics()->frameEraseAll(false);
+ _vm->graphics()->textCurrentColor(INK_JOURNAL);
int i;
_vm->logic()->zoneClearAll(ZONE_ROOM);
@@ -134,13 +135,12 @@ void Journal::prepare() {
}
}
_vm->graphics()->bankErase(JOURNAL_BANK);
-
- _vm->graphics()->textCurrentColor(INK_JOURNAL);
}
void Journal::restore() {
_vm->display()->fullscreen(false);
+ _vm->display()->forceFullRefresh();
_vm->logic()->joePos(_prevJoeX, _prevJoeY);
_vm->logic()->joeCutFacing(_vm->logic()->joeFacing());
@@ -153,8 +153,8 @@ void Journal::restore() {
void Journal::redraw() {
drawNormalPanel();
drawConfigPanel();
- drawSaveSlot();
drawSaveDescriptions();
+ drawSaveSlot();
}
@@ -165,6 +165,7 @@ void Journal::update() {
int16 y = 9 + _currentSaveSlot * 13 + 8;
_vm->display()->drawBox(x, y, x + 6, y, INK_JOURNAL);
}
+ _vm->display()->forceFullRefresh();
_vm->display()->update();
}
diff --git a/queen/logic.cpp b/queen/logic.cpp
index 006efa4941..4dba02ad37 100644
--- a/queen/logic.cpp
+++ b/queen/logic.cpp
@@ -726,14 +726,8 @@ void Logic::roomSetupFurniture() {
// unpack the paste downs
++curImage;
for (i = 1; i <= furnitureTotal; ++i) {
- int16 obj = gstate[i];
- if (obj > 5000) {
- obj -= 5000;
- GraphicData *pgd = &_graphicData[obj];
- _vm->graphics()->bankUnpack(pgd->firstFrame, curImage, 15);
- _vm->graphics()->bobPaste(curImage, pgd->x, pgd->y);
- // no need to increment curImage here, as bobPaste() destroys the
- // unpacked frame after blitting it
+ if (gstate[i] > 5000) {;
+ _vm->graphics()->bobPaste(gstate[i] - 5000, curImage);
}
}
}
@@ -843,14 +837,8 @@ void Logic::roomSetupObjects() {
_numFrames = curImage;
for (i = firstRoomObj; i <= lastRoomObj; ++i) {
ObjectData *pod = &_objectData[i];
- if (pod->name > 0) {
- int16 obj = pod->image;
- if (obj > 5000) {
- obj -= 5000;
- GraphicData *pgd = &_graphicData[obj];
- _vm->graphics()->bankUnpack(pgd->firstFrame, curImage, 15);
- _vm->graphics()->bobPaste(curImage, pgd->x, pgd->y);
- }
+ if (pod->name > 0 && pod->image > 5000) {
+ _vm->graphics()->bobPaste(pod->image - 5000, curImage);
}
}
}
@@ -980,6 +968,8 @@ void Logic::roomSetup(const char *room, int comPanel, bool inCutaway) {
_numFrames = 37 + FRAMES_JOE_XTRA;
roomSetupFurniture();
roomSetupObjects();
+
+ _vm->display()->forceFullRefresh();
}
@@ -1549,7 +1539,7 @@ void Logic::joeUseDress(bool showCut) {
playCutaway("cudrs.CUT");
}
}
- _vm->display()->palSetJoe(JP_DRESS);
+ _vm->display()->palSetJoeDress();
joeSetupFromBanks("JoeD_A.BBK", "JoeD_B.BBK");
inventoryDeleteItem(ITEM_DRESS);
gameState(VAR_DRESSING_MODE, 2);
@@ -1563,7 +1553,7 @@ void Logic::joeUseClothes(bool showCut) {
playCutaway("cdclo.CUT");
inventoryInsertItem(ITEM_DRESS);
}
- _vm->display()->palSetJoe(JP_CLOTHES);
+ _vm->display()->palSetJoeNormal();
joeSetupFromBanks("Joe_A.BBK", "Joe_B.BBK");
inventoryDeleteItem(ITEM_CLOTHES);
gameState(VAR_DRESSING_MODE, 0);
@@ -1571,7 +1561,7 @@ void Logic::joeUseClothes(bool showCut) {
void Logic::joeUseUnderwear() {
- _vm->display()->palSetJoe(JP_CLOTHES);
+ _vm->display()->palSetJoeNormal();
joeSetupFromBanks("JoeU_A.BBK", "JoeU_B.BBK");
gameState(VAR_DRESSING_MODE, 1);
}
@@ -2580,12 +2570,12 @@ void Logic::asmMakeJoeUseUnderwear() {
void Logic::asmSwitchToDressPalette() {
- _vm->display()->palSetJoe(JP_DRESS);
+ _vm->display()->palSetJoeDress();
}
void Logic::asmSwitchToNormalPalette() {
- _vm->display()->palSetJoe(JP_CLOTHES);
+ _vm->display()->palSetJoeNormal();
}
diff --git a/queen/queen.cpp b/queen/queen.cpp
index cfce6ba62a..210afcea11 100644
--- a/queen/queen.cpp
+++ b/queen/queen.cpp
@@ -159,7 +159,7 @@ void QueenEngine::initialise(void) {
_resource = new Resource(_gameDataPath, _system->get_savefile_manager(), getSavePath());
_command = new Command(this);
_debugger = new Debugger(this);
- _display = new Display(this, _resource->getLanguage(), _system);
+ _display = new Display(this, _system);
_graphics = new Graphics(this);
_input = new Input(_resource->getLanguage(), _system);
_logic = new Logic(this);
diff --git a/queen/xref.txt b/queen/xref.txt
index 789ed58cce..0aa072676c 100644
--- a/queen/xref.txt
+++ b/queen/xref.txt
@@ -296,21 +296,21 @@ tseek() *not needed*
SCREEN
======
calc_screen_scroll() Display::horizontalScrollUpdate
-changejoepal() Display::palSetJoe
+changejoepal() Display::palSetJoe*
check_colors() Display::palCustomColors
check_pal_scroll Display::palCustomScroll
clearpanel() Display::prepareUpdate
drawbackdrop() Display::prepareUpdate
drawpanel() Display::prepareUpdate
drawscreen() Display::update
-dynalum() Dynalum::update
+dynalum() Display::dynalumUpdate
fade_panel() Display::palFadePanel
fadein() Display::palFadeIn
fadeout() Display::palFadeOut
flashspecial() Display::palCustomFlash
-loadfont() TextRenderer::init
+loadfont() Display::initFont
palscroll() Display::palScroll
-putcharacter() TextRenderer::drawChar
+putcharacter() Display::drawChar
setpal() Display::palSet
-
BDxres Display::_bdWidth
@@ -318,8 +318,8 @@ BDyres Display::_bdHeight
clothespal Display::_palJoeClothes
COMPANEL *not needed* (argument)
dresspal Display::_palJoeDress
-font TextRenderer::_font
-font_sizes TextRenderer::_charWidth
+font Display::_font
+font_sizes Display::_charWidth
FULLSCREEN Display::_fullscreen
nopalscroll Display::_pal.scrollable
palette Display::_pal.room