aboutsummaryrefslogtreecommitdiff
path: root/engines/toltecs/screen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/toltecs/screen.cpp')
-rw-r--r--engines/toltecs/screen.cpp99
1 files changed, 42 insertions, 57 deletions
diff --git a/engines/toltecs/screen.cpp b/engines/toltecs/screen.cpp
index 634917a7b1..be91130c0a 100644
--- a/engines/toltecs/screen.cpp
+++ b/engines/toltecs/screen.cpp
@@ -33,7 +33,6 @@
namespace Toltecs {
Screen::Screen(ToltecsEngine *vm) : _vm(vm) {
-
_frontScreen = new byte[268800];
_backScreen = new byte[870400];
@@ -43,9 +42,11 @@ Screen::Screen(ToltecsEngine *vm) : _vm(vm) {
// Screen shaking
_shakeActive = false;
+ _shakeTime = 0;
_shakeCounterInit = 0;
_shakeCounter = 0;
_shakePos = 0;
+ _shakeTime = 0;
// Verb line
_verbLineNum = 0;
@@ -66,16 +67,13 @@ Screen::Screen(ToltecsEngine *vm) : _vm(vm) {
_renderQueue = new RenderQueue(_vm);
_fullRefresh = false;
_guiRefresh = false;
-
}
Screen::~Screen() {
-
delete[] _frontScreen;
delete[] _backScreen;
-
- delete _renderQueue;
+ delete _renderQueue;
}
void Screen::unpackRle(byte *source, byte *dest, uint16 width, uint16 height) {
@@ -118,7 +116,6 @@ void Screen::loadMouseCursor(uint resIndex) {
}
void Screen::drawGuiImage(int16 x, int16 y, uint resIndex) {
-
byte *imageData = _vm->_res->load(resIndex)->data;
int16 headerSize = READ_LE_UINT16(imageData);
int16 width = imageData[2];
@@ -129,7 +126,7 @@ void Screen::drawGuiImage(int16 x, int16 y, uint resIndex) {
byte *dest = _frontScreen + x + (y + _vm->_cameraHeight) * 640;
//debug(0, "Screen::drawGuiImage() x = %d; y = %d; w = %d; h = %d; resIndex = %d", x, y, width, height, resIndex);
-
+
while (workHeight > 0) {
int count = 1;
byte pixel = *imageData++;
@@ -151,11 +148,11 @@ void Screen::drawGuiImage(int16 x, int16 y, uint resIndex) {
}
_guiRefresh = true;
-
}
void Screen::startShakeScreen(int16 shakeCounter) {
_shakeActive = true;
+ _shakeTime = 0;
_shakeCounterInit = shakeCounter;
_shakeCounter = shakeCounter;
_shakePos = 0;
@@ -166,19 +163,22 @@ void Screen::stopShakeScreen() {
_vm->_system->setShakePos(0);
}
-void Screen::updateShakeScreen() {
- if (_shakeActive) {
+bool Screen::updateShakeScreen() {
+ // Assume shaking happens no more often than 50 times per second
+ if (_shakeActive && _vm->_system->getMillis() - _shakeTime >= 20) {
+ _shakeTime = _vm->_system->getMillis();
_shakeCounter--;
if (_shakeCounter == 0) {
_shakeCounter = _shakeCounterInit;
_shakePos ^= 8;
_vm->_system->setShakePos(_shakePos);
+ return true;
}
}
+ return false;
}
void Screen::addStaticSprite(byte *spriteItem) {
-
DrawRequest drawRequest;
memset(&drawRequest, 0, sizeof(drawRequest));
@@ -193,11 +193,9 @@ void Screen::addStaticSprite(byte *spriteItem) {
debug(0, "Screen::addStaticSprite() x = %d; y = %d; baseColor = %d; resIndex = %d; flags = %04X", drawRequest.x, drawRequest.y, drawRequest.baseColor, drawRequest.resIndex, drawRequest.flags);
addDrawRequest(drawRequest);
-
}
void Screen::addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, int16 *spriteArray, bool loop, int mode) {
-
//debug(0, "Screen::addAnimatedSprite(%d, %d, %d)", x, y, fragmentId);
DrawRequest drawRequest;
@@ -247,12 +245,10 @@ void Screen::addAnimatedSprite(int16 x, int16 y, int16 fragmentId, byte *data, i
} else {
loopNum |= 0x8000;
}
-
+
WRITE_LE_UINT16(spriteItem + 0, loopNum);
WRITE_LE_UINT16(spriteItem + 4, frameNum);
-
}
-
}
void Screen::clearSprites() {
@@ -260,7 +256,6 @@ void Screen::clearSprites() {
}
void Screen::blastSprite(int16 x, int16 y, int16 fragmentId, int16 resIndex, uint16 flags) {
-
DrawRequest drawRequest;
SpriteDrawItem sprite;
@@ -276,11 +271,9 @@ void Screen::blastSprite(int16 x, int16 y, int16 fragmentId, int16 resIndex, uin
sprite.y -= _vm->_cameraY;
drawSprite(sprite);
}
-
}
void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
-
debug(0, "Screen::updateVerbLine() _verbLineNum = %d; _verbLineX = %d; _verbLineY = %d; _verbLineWidth = %d; _verbLineCount = %d",
_verbLineNum, _verbLineX, _verbLineY, _verbLineWidth, _verbLineCount);
@@ -308,9 +301,9 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
wrapState.len2 = 0;
y = _verbLineY;
-
+
memset(wrapState.textBuffer, 0, sizeof(wrapState.textBuffer));
-
+
for (int16 i = 0; i <= _verbLineNum; i++) {
wrapState.sourceString = _vm->_script->getSlotData(_verbLineItems[i].slotIndex) + _verbLineItems[i].slotOffset;
len = wrapGuiText(_fontResIndexArray[0], _verbLineWidth, wrapState);
@@ -331,30 +324,28 @@ void Screen::updateVerbLine(int16 slotIndex, int16 slotOffset) {
wrapState.sourceString++;
wrapState.len1 -= len;
wrapState.len2 = len + 1;
-
- drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0], wrapState);
+
+ drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y - 1, 0xF9, 0xFF, _fontResIndexArray[0], wrapState);
wrapState.destString = wrapState.textBuffer;
wrapState.width = 0;
len = wrapGuiText(_fontResIndexArray[0], _verbLineWidth, wrapState);
wrapState.len1 += len;
-
+
y += 9;
}
y += 9;
}
-
+
wrapState.len1 -= len;
wrapState.len2 = len;
- drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y, 0xF9, 0xFF, _fontResIndexArray[0], wrapState);
+ drawGuiText(_verbLineX - 1 - (wrapState.width / 2), y - 1, 0xF9, 0xFF, _fontResIndexArray[0], wrapState);
_guiRefresh = true;
-
}
-void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
-
+void Screen::updateTalkText(int16 slotIndex, int16 slotOffset, bool alwaysDisplayed) {
int16 x, y, maxWidth, width, length;
byte durationModifier = 1;
byte *textData = _vm->_script->getSlotData(slotIndex) + slotOffset;
@@ -363,6 +354,7 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
item->fontNum = 0;
item->color = _talkTextFontColor;
+ item->alwaysDisplayed = alwaysDisplayed;
x = CLIP<int16>(_talkTextX - _vm->_cameraX, 120, _talkTextMaxWidth);
y = CLIP<int16>(_talkTextY - _vm->_cameraY, 4, _vm->_cameraHeight - 16);
@@ -448,11 +440,9 @@ void Screen::updateTalkText(int16 slotIndex, int16 slotOffset) {
textDurationMultiplier += 100;
}
item->duration = 4 * textDurationMultiplier * durationModifier;
-
}
void Screen::addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16 width, TalkTextItem *item) {
-
if (width > 0) {
TextRect *textRect = &item->lines[item->lineCount];
width = width + 1 - font.getSpacing();
@@ -463,13 +453,11 @@ void Screen::addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16
textRect->x = CLIP<int16>(x - width / 2, 0, 640);
item->lineCount++;
}
-
- y += font.getHeight() - 1;
+ y += font.getHeight() - 1;
}
void Screen::addTalkTextItemsToRenderQueue() {
-
for (int16 i = 0; i <= _talkTextItemNum; i++) {
TalkTextItem *item = &_talkTextItems[i];
byte *text = _vm->_script->getSlotData(item->slotIndex) + item->slotOffset;
@@ -482,14 +470,24 @@ void Screen::addTalkTextItemsToRenderQueue() {
if (item->duration < 0)
item->duration = 0;
+ if (!_vm->_cfgText && !item->alwaysDisplayed)
+ return;
+
for (byte j = 0; j < item->lineCount; j++) {
- _renderQueue->addText(item->lines[j].x, item->lines[j].y, item->color, _fontResIndexArray[item->fontNum],
- text, item->lines[j].length);
+ _renderQueue->addText(item->lines[j].x, item->lines[j].y, item->color,
+ _fontResIndexArray[item->fontNum], text, item->lines[j].length);
text += item->lines[j].length;
}
-
}
+}
+bool Screen::isTalkTextActive(int16 slotIndex) {
+ for (int16 i = 0; i <= _talkTextItemNum; i++) {
+ if (_talkTextItems[i].slotIndex == slotIndex && _talkTextItems[i].duration > 0)
+ return true;
+ }
+
+ return false;
}
int16 Screen::getTalkTextDuration() {
@@ -517,7 +515,6 @@ void Screen::registerFont(uint fontIndex, uint resIndex) {
}
void Screen::drawGuiTextMulti(byte *textData) {
-
int16 x = 0, y = 0;
// Really strange stuff.
@@ -547,19 +544,18 @@ void Screen::drawGuiTextMulti(byte *textData) {
wrapState.width = 0;
wrapState.len1 = 0;
wrapState.len2 = wrapGuiText(_fontResIndexArray[1], 640, wrapState);
- drawGuiText(x - wrapState.width / 2, y, _fontColor1, _fontColor2, _fontResIndexArray[1], wrapState);
+ drawGuiText(x - wrapState.width / 2, y - 1, _fontColor1, _fontColor2, _fontResIndexArray[1], wrapState);
}
} while (*wrapState.sourceString != 0xFF);
_guiRefresh = true;
-
}
int16 Screen::wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wrapState) {
Font font(_vm->_res->load(fontResIndex)->data);
int16 len = 0;
-
+
while (*wrapState.sourceString >= 0x20 && *wrapState.sourceString < 0xF0) {
byte ch = *wrapState.sourceString;
byte charWidth;
@@ -573,9 +569,8 @@ int16 Screen::wrapGuiText(uint fontResIndex, int maxWidth, GuiTextWrapState &wra
wrapState.width += charWidth;
*wrapState.destString++ = *wrapState.sourceString++;
}
-
+
return len;
-
}
void Screen::drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uint fontResIndex, GuiTextWrapState &wrapState) {
@@ -586,11 +581,9 @@ void Screen::drawGuiText(int16 x, int16 y, byte fontColor1, byte fontColor2, uin
x = drawString(x + 1, y + _vm->_cameraHeight, fontColor1, fontResIndex, wrapState.textBuffer, wrapState.len1, &ywobble, false);
x = drawString(x, y + _vm->_cameraHeight, fontColor2, fontResIndex, wrapState.textBuffer + wrapState.len1, wrapState.len2, &ywobble, false);
-
}
int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, const byte *text, int len, int16 *ywobble, bool outline) {
-
//debug(0, "Screen::drawString(%d, %d, %d, %d)", x, y, color, fontResIndex);
Font font(_vm->_res->load(fontResIndex)->data);
@@ -607,7 +600,7 @@ int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, const
if (ch <= 0x20) {
x += font.getWidth();
} else {
- drawChar(font, _frontScreen, x, y - yadd, ch, color, outline);
+ drawChar(font, _frontScreen, x, y + yadd, ch, color, outline);
x += font.getCharWidth(ch) + font.getSpacing() - 1;
yadd = -yadd;
}
@@ -617,11 +610,9 @@ int16 Screen::drawString(int16 x, int16 y, byte color, uint fontResIndex, const
*ywobble = yadd;
return x;
-
}
void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, byte color, bool outline) {
-
int16 charWidth, charHeight;
byte *charData;
@@ -650,11 +641,9 @@ void Screen::drawChar(const Font &font, byte *dest, int16 x, int16 y, byte ch, b
}
dest += 640 - charWidth;
}
-
}
void Screen::drawSurface(int16 x, int16 y, Graphics::Surface *surface) {
-
int16 skipX = 0;
int16 width = surface->w;
int16 height = surface->h;
@@ -699,11 +688,9 @@ void Screen::drawSurface(int16 x, int16 y, Graphics::Surface *surface) {
frontScreen += 640 - width;
surfacePixels += surface->w - width - skipX;
}
-
}
void Screen::saveState(Common::WriteStream *out) {
-
// Save verb line
out->writeUint16LE(_verbLineNum);
out->writeUint16LE(_verbLineX);
@@ -750,11 +737,9 @@ void Screen::saveState(Common::WriteStream *out) {
out->writeUint32LE(_fontResIndexArray[i]);
out->writeByte(_fontColor1);
out->writeByte(_fontColor2);
-
}
void Screen::loadState(Common::ReadStream *in) {
-
// Load verb line
_verbLineNum = in->readUint16LE();
_verbLineX = in->readUint16LE();
@@ -765,7 +750,7 @@ void Screen::loadState(Common::ReadStream *in) {
_verbLineItems[i].slotIndex = in->readUint16LE();
_verbLineItems[i].slotOffset = in->readUint16LE();
}
-
+
// Load talk text items
_talkTextX = in->readUint16LE();
_talkTextY = in->readUint16LE();
@@ -779,6 +764,7 @@ void Screen::loadState(Common::ReadStream *in) {
_talkTextItems[i].fontNum = in->readUint16LE();
_talkTextItems[i].color = in->readByte();
_talkTextItems[i].lineCount = in->readByte();
+ _talkTextItems[i].alwaysDisplayed = false;
for (int j = 0; j < _talkTextItems[i].lineCount; j++) {
_talkTextItems[i].lines[j].x = in->readUint16LE();
_talkTextItems[i].lines[j].y = in->readUint16LE();
@@ -786,7 +772,7 @@ void Screen::loadState(Common::ReadStream *in) {
_talkTextItems[i].lines[j].length = in->readUint16LE();
}
}
-
+
// Load GUI bitmap
{
byte *gui = _frontScreen + _vm->_cameraHeight * 640;
@@ -802,7 +788,6 @@ void Screen::loadState(Common::ReadStream *in) {
_fontResIndexArray[i] = in->readUint32LE();
_fontColor1 = in->readByte();
_fontColor2 = in->readByte();
-
}
} // End of namespace Toltecs