aboutsummaryrefslogtreecommitdiff
path: root/engines/agos/draw.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/agos/draw.cpp')
-rw-r--r--engines/agos/draw.cpp298
1 files changed, 207 insertions, 91 deletions
diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp
index f5f7161805..bb28da73b5 100644
--- a/engines/agos/draw.cpp
+++ b/engines/agos/draw.cpp
@@ -27,22 +27,16 @@
#include "common/system.h"
+#include "graphics/surface.h"
+
#include "agos/agos.h"
#include "agos/intern.h"
namespace AGOS {
-byte *AGOSEngine::getFrontBuf() {
- if (getGameType() != GType_PP && getGameType() != GType_FF)
- _updateScreen = true;
-
- _dxSurfacePitch = _screenWidth;
- return _frontBuf;
-}
-
byte *AGOSEngine::getBackBuf() {
_dxSurfacePitch = _screenWidth;
- return _useBackGround ? _backGroundBuf : _backBuf;
+ return _backBuf;
}
byte *AGOSEngine::getBackGround() {
@@ -166,27 +160,29 @@ void AGOSEngine::animateSprites() {
_vgaSpriteChanged++;
}
- if ((getGameType() == GType_ELVIRA1 && !_variableArray[293] ||
- getGameType() == GType_ELVIRA2 && !_variableArray[71]) &&
- _wallOn) {
+ if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) {
+ const uint8 var = (getGameType() == GType_ELVIRA1) ? 293 : 71;
+ if (_wallOn && !_variableArray[var]) {
+ _wallOn--;
- VC10_state state;
- state.srcPtr = getBackGround() + 504;
- state.height = 127;
- state.width = 14;
- state.y = 0;
- state.x = 0;
- state.palette = 0;
- state.paletteMod = 0;
- state.flags = kDFNonTrans;
+ VC10_state state;
+ state.srcPtr = getBackGround() + 3 * _screenWidth + 3 * 16;
+ state.height = state.draw_height = 127;
+ state.width = state.draw_width = 14;
+ state.y = 0;
+ state.x = 0;
+ state.palette = 0;
+ state.paletteMod = 0;
+ state.flags = kDFNonTrans;
- _windowNum = 4;
+ _windowNum = 4;
- _backFlag = 1;
- drawImage(&state);
- _backFlag = 0;
+ _backFlag = 1;
+ drawImage(&state);
+ _backFlag = 0;
- _vgaSpriteChanged++;
+ _vgaSpriteChanged++;
+ }
}
if (!_scrollFlag && !_vgaSpriteChanged) {
@@ -209,7 +205,12 @@ void AGOSEngine::animateSprites() {
restoreBackGround();
vsp = _vgaSprites;
- while (vsp->id) {
+ for (; vsp->id !=0; vsp++) {
+ if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
+ !(vsp->windowNum & 0x8000)) {
+ continue;
+ }
+
vsp->windowNum &= 0x7FFF;
vpe = &_vgaBufferPointers[vsp->zoneNum];
@@ -223,10 +224,10 @@ void AGOSEngine::animateSprites() {
saveBackGround(vsp);
drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags);
- vsp++;
}
if (getGameType() == GType_ELVIRA1 && _variableArray[293]) {
+ // Used by the Fire Wall and Ice Wall spells
debug(0, "Using special wall");
uint8 color, h, len;
@@ -256,10 +257,9 @@ void AGOSEngine::animateSprites() {
}
_window4Flag = 1;
- setMoveRect(0, 224, 0, 127);
+ setMoveRect(0, 0, 224, 127);
} else if (getGameType() == GType_ELVIRA2 && _variableArray[71] & 2) {
- debug(0, "Using special wall");
-
+ // Used by the Unholy Barrier spell
uint8 color, h, len;
byte *dst = _window4BackScn;
@@ -284,14 +284,14 @@ void AGOSEngine::animateSprites() {
while (len--) {
dst += 2;
*dst++ = color;
- dst++;
+ dst += 1;
}
dst += 448;
h--;
}
_window4Flag = 1;
- setMoveRect(0, 224, 0, 127);
+ setMoveRect(0, 0, 224, 127);
}
if (_window6Flag == 1)
@@ -304,7 +304,123 @@ void AGOSEngine::animateSprites() {
}
void AGOSEngine::dirtyClips() {
- // TODO
+ int16 x, y, w, h;
+restart:
+ _newDirtyClip = 0;
+
+ VgaSprite *vsp = _vgaSprites;
+ while (vsp->id != 0) {
+ if (vsp->windowNum & 0x8000) {
+ x = vsp->x;
+ y = vsp->y;
+ w = 1;
+ h = 1;
+
+ if (vsp->image != 0) {
+ VgaPointersEntry *vpe = &_vgaBufferPointers[vsp->zoneNum];
+ const byte *ptr = vpe->vgaFile2 + vsp->image * 8;
+ w = READ_BE_UINT16(ptr + 6) / 8;
+ h = ptr[5];
+ }
+
+ dirtyClipCheck(x, y, w, h);
+ }
+ vsp++;
+ }
+
+ AnimTable *animTable = _screenAnim1;
+ while (animTable->srcPtr != 0) {
+ if (animTable->windowNum & 0x8000) {
+ x = animTable->x + _scrollX;
+ y = animTable->y;
+ w = animTable->width * 2;
+ h = animTable->height;
+
+ dirtyClipCheck(x, y, w, h);
+ }
+ animTable++;
+ }
+
+ if (_newDirtyClip != 0)
+ goto restart;
+
+}
+
+void AGOSEngine::dirtyClipCheck(int16 x, int16 y, int16 w, int16 h) {
+ int16 width, height, tmp;
+
+ VgaSprite *vsp = _vgaSprites;
+ for (; vsp->id != 0; vsp++) {
+ if (vsp->windowNum & 0x8000)
+ continue;
+
+ if (vsp->image == 0)
+ continue;
+
+ VgaPointersEntry *vpe = &_vgaBufferPointers[vsp->zoneNum];
+ const byte *ptr = vpe->vgaFile2 + vsp->image * 8;
+ width = READ_BE_UINT16(ptr + 6) / 8;
+ height = ptr[5];
+
+ tmp = vsp->x;
+ if (tmp >= x) {
+ tmp -= w;
+ if (tmp >= x)
+ continue;
+ } else {
+ tmp += width;
+ if (tmp < x)
+ continue;
+ }
+
+ tmp = vsp->y;
+ if (tmp >= y) {
+ tmp -= h;
+ if (tmp >= y)
+ continue;
+ } else {
+ tmp += height;
+ if (tmp < y)
+ continue;
+ }
+
+ vsp->windowNum |= 0x8000;
+ _newDirtyClip = 1;
+ }
+
+ AnimTable *animTable = _screenAnim1;
+ for (; animTable->srcPtr != 0; animTable++) {
+ if (animTable->windowNum & 0x8000)
+ continue;
+
+ width = animTable->width * 2;
+ height = animTable->height;
+
+ tmp = animTable->x + _scrollX;
+ if (tmp >= x) {
+ tmp -= w;
+ if (tmp >= x)
+ continue;
+ } else {
+ tmp += width;
+ if (tmp < x)
+ continue;
+ }
+
+ tmp = animTable->y;
+ if (tmp >= y) {
+ tmp -= h;
+ if (tmp >= y)
+ continue;
+ } else {
+ tmp += height;
+ if (tmp < y)
+ continue;
+ }
+
+ animTable->windowNum |= 0x8000;
+ _newDirtyClip = 1;
+ }
}
void AGOSEngine::restoreBackGround() {
@@ -326,12 +442,11 @@ void AGOSEngine::restoreBackGround() {
animTable--;
if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
- !(animTable->window & 0x8000)) {
- //continue;
+ !(animTable->windowNum & 0x8000)) {
+ continue;
}
- animTable->window &= 0x7FFF;
- _windowNum = animTable->window;
+ _windowNum = animTable->windowNum & 0x7FFF;
VC10_state state;
state.srcPtr = animTable->srcPtr;
@@ -346,9 +461,9 @@ void AGOSEngine::restoreBackGround() {
_backFlag = 1;
drawImage(&state);
- //if (getGameType() != GType_SIMON1 && getGameType() != GType_SIMON2) {
+ if (getGameType() != GType_SIMON1 && getGameType() != GType_SIMON2) {
animTable->srcPtr = 0;
- //}
+ }
}
_backFlag = 0;
@@ -357,7 +472,7 @@ void AGOSEngine::restoreBackGround() {
animTable = animTableTmp = _screenAnim1;
while (animTable->srcPtr) {
- if (!(animTable->window & 8000)) {
+ if (!(animTable->windowNum & 0x8000)) {
memcpy(animTableTmp, animTable, sizeof(AnimTable));
animTableTmp++;
}
@@ -402,8 +517,12 @@ void AGOSEngine::saveBackGround(VgaSprite *vsp) {
}
animTable->height = ptr[5];
- animTable->window = vsp->windowNum;
+ animTable->windowNum = vsp->windowNum;
animTable->id = vsp->id;
+ animTable->zoneNum = vsp->zoneNum;
+
+ animTable++;
+ animTable->srcPtr = 0;
}
void AGOSEngine::displayBoxStars() {
@@ -422,10 +541,13 @@ void AGOSEngine::displayBoxStars() {
uint curHeight = (getGameType() == GType_SIMON2) ? _boxStarHeight : 134;
+
for (int i = 0; i < 5; i++) {
ha = _hitAreas;
count = ARRAYSIZE(_hitAreas);
+ Graphics::Surface *screen = _system->lockScreen();
+
do {
if (ha->id != 0 && ha->flags & kBFBoxInUse && !(ha->flags & kBFBoxDead)) {
@@ -453,7 +575,7 @@ void AGOSEngine::displayBoxStars() {
if (x_ >= 311)
continue;
- dst = getFrontBuf();
+ dst = (byte *)screen->pixels;
dst += (((_dxSurfacePitch / 4) * y_) * 4) + x_;
@@ -492,6 +614,8 @@ void AGOSEngine::displayBoxStars() {
}
} while (ha++, --count);
+ _system->unlockScreen();
+
delay(100);
setMoveRect(0, 0, 320, curHeight);
@@ -509,11 +633,7 @@ void AGOSEngine::scrollScreen() {
const byte *src;
uint x, y;
- if (getGameType() == GType_SIMON2) {
- dst = getBackGround();
- } else {
- dst = getFrontBuf();
- }
+ dst = getBackGround();
if (_scrollXMax == 0) {
uint screenSize = 8 * _screenWidth;
@@ -536,8 +656,7 @@ void AGOSEngine::scrollScreen() {
_scrollY += _scrollFlag;
vcWriteVar(250, _scrollY);
- memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight);
- memcpy(_backGroundBuf, _backBuf, _screenHeight * _scrollWidth);
+ fillBackFromBackGround(_screenHeight, _scrollWidth);
} else {
if (_scrollFlag < 0) {
memmove(dst + 8, dst, _screenWidth * _scrollHeight - 8);
@@ -565,8 +684,7 @@ void AGOSEngine::scrollScreen() {
if (getGameType() == GType_SIMON2) {
memcpy(_window4BackScn, _backGroundBuf, _scrollHeight * _screenWidth);
} else {
- memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight);
- memcpy(_backGroundBuf, _backBuf, _scrollHeight * _screenWidth);
+ fillBackFromBackGround(_scrollHeight, _screenWidth);
}
setMoveRect(0, 0, 320, _scrollHeight);
@@ -575,49 +693,48 @@ void AGOSEngine::scrollScreen() {
}
_scrollFlag = 0;
-}
-void AGOSEngine::clearBackFromTop(uint lines) {
- memset(_backBuf, 0, lines * _screenWidth);
-}
+ if (getGameType() == GType_SIMON2) {
+ AnimTable *animTable = _screenAnim1;
+ while (animTable->srcPtr) {
+ animTable->srcPtr = 0;
+ animTable++;
+ }
-void AGOSEngine::clearSurfaces(uint num_lines) {
- memset(_backBuf, 0, num_lines * _screenWidth);
+ VgaSprite *vsp = _vgaSprites;
+ while (vsp->id) {
+ vsp->windowNum |= 0x8000;
+ vsp++;
+ }
+ }
+}
- _system->copyRectToScreen(_backBuf, _screenWidth, 0, 0, _screenWidth, num_lines);
+void AGOSEngine::clearSurfaces() {
+ _system->clearScreen();
- if (_useBackGround) {
- memset(_frontBuf, 0, num_lines * _screenWidth);
- memset(_backGroundBuf, 0, num_lines * _screenWidth);
+ if (_backBuf) {
+ memset(_backBuf, 0, _screenHeight * _screenWidth);
}
}
-void AGOSEngine::fillFrontFromBack(uint x, uint y, uint w, uint h) {
- uint offs = x + y * _screenWidth;
- byte *s = _backBuf + offs;
- byte *d = _frontBuf + offs;
-
- do {
- memcpy(d, s, w);
- d += _screenWidth;
- s += _screenWidth;
- } while (--h);
+void AGOSEngine::fillBackFromBackGround(uint16 height, uint16 width) {
+ memcpy(_backBuf, _backGroundBuf, height * width);
}
-void AGOSEngine::fillBackFromFront(uint x, uint y, uint w, uint h) {
- uint offs = x + y * _screenWidth;
- byte *s = _frontBuf + offs;
- byte *d = _backBuf + offs;
+void AGOSEngine::fillBackFromFront() {
+ Graphics::Surface *screen = _system->lockScreen();
+ memcpy(_backBuf, (byte *)screen->pixels, _screenHeight * _screenWidth);
+ _system->unlockScreen();
+}
- do {
- memcpy(d, s, w);
- d += _screenWidth;
- s += _screenWidth;
- } while (--h);
+void AGOSEngine::fillBackGroundFromBack() {
+ memcpy(_backGroundBuf, _backBuf, _screenHeight * _screenWidth);
}
-void AGOSEngine::fillBackGroundFromBack(uint lines) {
- memcpy(_backGroundBuf, _backBuf, lines * _screenWidth);
+void AGOSEngine::fillBackGroundFromFront() {
+ Graphics::Surface *screen = _system->lockScreen();
+ memcpy(_backGroundBuf, (byte *)screen->pixels, _screenHeight * _screenWidth);
+ _system->unlockScreen();
}
void AGOSEngine::setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height) {
@@ -643,18 +760,18 @@ void AGOSEngine::displayScreen() {
}
}
+ Graphics::Surface *screen = _system->lockScreen();
if (getGameType() == GType_PP || getGameType() == GType_FF) {
- _system->copyRectToScreen(getBackBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
- _system->updateScreen();
+ memcpy((byte *)screen->pixels, getBackBuf(), _screenWidth * _screenHeight);
if (getGameId() != GID_DIMP)
- memcpy(getBackBuf(), getFrontBuf(), _screenWidth * _screenHeight);
+ fillBackFromBackGround(_screenHeight, _screenWidth);
} else {
if (_window4Flag == 2) {
_window4Flag = 0;
uint16 srcWidth, width, height;
- byte *dst = getFrontBuf();
+ byte *dst = (byte *)screen->pixels;
const byte *src = _window4BackScn;
if (_window3Flag == 1) {
@@ -688,18 +805,17 @@ void AGOSEngine::displayScreen() {
_window6Flag = 0;
byte *src = _window6BackScn;
- byte *dst = getFrontBuf() + 16320;
+ byte *dst = (byte *)screen->pixels + 16320;
for (int i = 0; i < 80; i++) {
memcpy(dst, src, 48);
dst += _screenWidth;
src += 48;
}
}
-
- _system->copyRectToScreen(getFrontBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
- _system->updateScreen();
}
+ _system->unlockScreen();
+
if (getGameType() == GType_FF && _scrollFlag) {
scrollScreen();
}