From 14aa27c4771059382bf9e1094263e11eabfda428 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Sat, 9 Jun 2007 05:30:20 +0000 Subject: Add dirtyClips code for Simon the Sorcerer 1/2. svn-id: r27227 --- engines/agos/agos.cpp | 1 + engines/agos/agos.h | 10 +++- engines/agos/draw.cpp | 157 ++++++++++++++++++++++++++++++++++++++++++++++---- engines/agos/vga.cpp | 4 +- 4 files changed, 156 insertions(+), 16 deletions(-) (limited to 'engines/agos') diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index fd8de533b0..30df5af26e 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -336,6 +336,7 @@ AGOSEngine::AGOSEngine(OSystem *syst) _showPreposition = 0; _showMessageFlag = 0; + _newDirtyClip = false; _copyScnFlag = 0; _vgaSpriteChanged = 0; diff --git a/engines/agos/agos.h b/engines/agos/agos.h index 54e1107e7f..90bd73600e 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -90,7 +90,8 @@ struct VgaSprite { int16 x, y; uint16 flags; uint16 priority; - uint16 windowNum, zoneNum; + uint16 windowNum; + uint16 zoneNum; VgaSprite() { memset(this, 0, sizeof(*this)); } }; @@ -117,8 +118,9 @@ struct AnimTable { int16 y; uint16 width; uint16 height; - uint16 window; + uint16 windowNum; uint16 id; + uint16 zoneNum; AnimTable() { memset(this, 0, sizeof(*this)); } }; @@ -414,6 +416,7 @@ protected: bool _showPreposition; bool _showMessageFlag; + bool _newDirtyClip; uint _copyScnFlag, _vgaSpriteChanged; byte *_block, *_blockEnd; @@ -478,7 +481,7 @@ protected: HitArea _hitAreas[250]; - AnimTable _screenAnim1[60]; + AnimTable _screenAnim1[90]; VgaPointersEntry _vgaBufferPointers[450]; VgaSprite _vgaSprites[200]; VgaSleepStruct _waitEndTable[60]; @@ -1151,6 +1154,7 @@ protected: virtual void animateSprites(); void dirtyClips(); + void dirtyClipCheck(int16 x, int16 y, int16 w, int16 h); void dirtyBackGround(); void restoreBackGround(); void saveBackGround(VgaSprite *vsp); diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp index fd1249575d..06ec7f62af 100644 --- a/engines/agos/draw.cpp +++ b/engines/agos/draw.cpp @@ -209,7 +209,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,7 +228,6 @@ void AGOSEngine::animateSprites() { saveBackGround(vsp); drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags); - vsp++; } if (getGameType() == GType_ELVIRA1 && _variableArray[293]) { @@ -304,7 +308,121 @@ 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) { + const byte *ptr = _curVgaFile2 + 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; + + const byte *ptr = _curVgaFile2 + 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 +444,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 +463,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 +474,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 +519,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() { @@ -575,6 +696,20 @@ void AGOSEngine::scrollScreen() { } _scrollFlag = 0; + + if (getGameType() == GType_SIMON2) { + AnimTable *animTable = _screenAnim1; + while (animTable->srcPtr) { + animTable->srcPtr = 0; + animTable++; + } + + VgaSprite *vsp = _vgaSprites; + while (vsp->id) { + vsp->windowNum |= 0x8000; + vsp++; + } + } } void AGOSEngine::clearBackFromTop(uint lines) { diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index 9579dc7c83..49c765b7ff 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -215,8 +215,8 @@ bool AGOSEngine::vc_maybe_skip_proc_1(uint16 a, int16 b) { void AGOSEngine::dirtyBackGround() { AnimTable *animTable = _screenAnim1; while (animTable->srcPtr) { - if (animTable->id == _vgaCurSpriteId) { - animTable->window |= 0x8000; + if (animTable->id == _vgaCurSpriteId && ((getGameType() == GType_SIMON1) || animTable->zoneNum == _vgaCurZoneNum)) { + animTable->windowNum |= 0x8000; break; } animTable++; -- cgit v1.2.3