aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/agos/agos.cpp44
-rw-r--r--engines/agos/agos.h46
-rw-r--r--engines/agos/charset.cpp10
-rw-r--r--engines/agos/draw.cpp207
-rw-r--r--engines/agos/event.cpp25
-rw-r--r--engines/agos/gfx.cpp830
-rw-r--r--engines/agos/input.cpp1
-rw-r--r--engines/agos/saveload.cpp10
-rw-r--r--engines/agos/script_e1.cpp14
-rw-r--r--engines/agos/script_e2.cpp2
-rw-r--r--engines/agos/subroutine.cpp2
-rw-r--r--engines/agos/verb.cpp12
-rw-r--r--engines/agos/vga.cpp138
-rw-r--r--engines/agos/vga.h3
-rw-r--r--engines/agos/vga_e2.cpp44
-rw-r--r--engines/agos/vga_s1.cpp11
-rw-r--r--engines/agos/vga_ww.cpp21
-rw-r--r--engines/agos/window.cpp14
18 files changed, 1009 insertions, 425 deletions
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index 78634c81e2..b3e615bfec 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -199,6 +199,9 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_copyPartialMode = 0;
_fastMode = 0;
_useBackGround = 0;
+
+ _oldDrawMethod = 0;
+ _backFlag = 0;
_debugMode = 0;
_startMainScript = false;
@@ -291,6 +294,7 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_leftButtonDown = 0;
_rightButtonDown = 0;
+ _clickOnly = 0;
_noRightClick = false;
_leftButton = 0;
@@ -477,6 +481,17 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_backBuf = 0;
_scaleBuf = 0;
+ _window3Flag = 0;
+ _window4Flag = 0;
+ _window6Flag = 0;
+ _window4BackScn = 0;
+ _window6BackScn = 0;
+
+ _moveXMin = 0;
+ _moveYMin = 0;
+ _moveXMax = 0;
+ _moveYMax = 0;
+
_vc10BasePtrOld = 0;
memcpy (_hebrewCharWidths,
"\x5\x5\x4\x6\x5\x3\x4\x5\x6\x3\x5\x5\x4\x6\x5\x3\x4\x6\x5\x6\x6\x6\x5\x5\x5\x6\x5\x6\x6\x6\x6\x6", 32);
@@ -511,6 +526,12 @@ int AGOSEngine::init() {
return -1;
}
+ // TODO: Enable for Simon the Sorcerer 1/2 when complete
+ if (getGameType() == GType_WW || getGameType() == GType_ELVIRA2 ||
+ getGameType() == GType_ELVIRA1) {
+ _oldDrawMethod = true;
+ }
+
if (getGameId() == GID_DIMP) {
_screenWidth = 496;
_screenHeight = 400;
@@ -562,9 +583,25 @@ int AGOSEngine::init() {
// allocate buffers
_backGroundBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
_frontBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
- _backBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
- if (getGameType() == GType_FF || getGameType() == GType_PP)
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
_scaleBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
+ }
+
+ if (!_oldDrawMethod) {
+ _backBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
+ } else {
+ if (getGameType() == GType_SIMON2) {
+ _window4BackScn = (byte *)calloc(_screenWidth * _screenHeight, 1);
+ } else if (getGameType() == GType_SIMON1) {
+ _window4BackScn = (byte *)calloc(_screenWidth * 134, 1);
+ } else if (getGameType() == GType_WW || getGameType() == GType_ELVIRA2) {
+ _window4BackScn = (byte *)calloc(224 * 127, 1);
+ } else if (getGameType() == GType_ELVIRA1) {
+ _window4BackScn = (byte *)calloc(224 * 127, 1);
+ _window6BackScn = (byte *)calloc(48 * 80, 1);
+ }
+ }
setupGame();
@@ -851,6 +888,9 @@ AGOSEngine::~AGOSEngine() {
free(_backBuf);
free(_scaleBuf);
+ free(_window4BackScn);
+ free(_window6BackScn);
+
free(_variableArray);
free(_variableArray2);
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index cf1bc8e7b4..af28cd2729 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -83,9 +83,9 @@ struct VgaPointersEntry {
struct VgaSprite {
uint16 id;
- uint16 image;
+ int16 image;
uint16 palette;
- uint16 x, y; /* actually signed numbers */
+ int16 x, y;
uint16 flags;
uint16 priority;
uint16 windowNum, zoneNum;
@@ -108,6 +108,17 @@ struct VgaTimerEntry {
VgaTimerEntry() { memset(this, 0, sizeof(*this)); }
};
+struct AnimTable {
+ const byte *srcPtr;
+ int16 x;
+ int16 y;
+ uint16 width;
+ uint16 height;
+ uint16 window;
+ uint16 id;
+ AnimTable() { memset(this, 0, sizeof(*this)); }
+};
+
enum SIMONGameType {
GType_ELVIRA1 = 0,
GType_ELVIRA2 = 1,
@@ -262,6 +273,9 @@ protected:
bool _fastMode;
bool _useBackGround;
+ bool _oldDrawMethod;
+ bool _backFlag;
+
uint16 _debugMode;
uint16 _language;
bool _copyProtection;
@@ -361,6 +375,7 @@ protected:
byte _leftButtonDown;
byte _leftButton, _leftButtonCount, _leftButtonOld;
byte _rightButtonDown;
+ bool _clickOnly;
bool _noRightClick;
Item *_dummyItem1;
@@ -450,10 +465,11 @@ protected:
HitArea _hitAreas[250];
+ AnimTable _screenAnim1[60];
VgaPointersEntry _vgaBufferPointers[450];
VgaSprite _vgaSprites[200];
- VgaSleepStruct _waitSyncTable[60];
VgaSleepStruct _waitEndTable[60];
+ VgaSleepStruct _waitSyncTable[60];
const uint16 *_pathFindArray[100];
@@ -472,6 +488,15 @@ protected:
byte _videoBuf1[32000];
uint16 _videoWindows[128];
+ uint16 _window3Flag;
+ uint16 _window4Flag;
+ uint16 _window6Flag;
+ byte *_window4BackScn;
+ byte *_window6BackScn;
+
+ uint16 _moveXMin, _moveYMin;
+ uint16 _moveXMax, _moveYMax;
+
VgaTimerEntry _vgaTimerList[205];
WindowBlock *_windowList;
@@ -1025,6 +1050,10 @@ protected:
void drawImage_init(int16 image, uint16 palette, uint16 x, uint16 y, uint16 flags);
virtual void drawImage(VC10_state *state);
+ void drawBackGroundImage(VC10_state *state);
+ void drawVertImage(VC10_state *state);
+
+ void setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height);
void horizontalScroll(VC10_state *state);
void verticalScroll(VC10_state *state);
@@ -1041,7 +1070,9 @@ protected:
void checkScrollY(int16 y, int16 ypos);
void centreScroll();
- void clearWindow(uint windowNum, uint color);
+ void clearVideoWindow(uint windowNum, uint color);
+ void clearVideoBackGround(uint windowNum, uint color);
+
void setPaletteSlot(uint srcOffs, uint dstOffs);
void checkWaitEndTable();
@@ -1100,6 +1131,11 @@ protected:
void animateSpritesDebug();
void animateSpritesByY();
+ void dirtyClips();
+ void dirtyBackGround();
+ void restoreBackGround();
+ void saveBackGround(VgaSprite *vsp);
+
void clearSurfaces(uint num_lines);
void updateScreen();
@@ -1416,6 +1452,8 @@ protected:
const OpcodeEntrySimon1 *_opcodesSimon1;
virtual void drawImage(VC10_state *state);
+ void drawMaskedImage(VC10_state *state);
+ void draw32ColorImage(VC10_state *state);
virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y);
diff --git a/engines/agos/charset.cpp b/engines/agos/charset.cpp
index 874108e872..2dbf8277af 100644
--- a/engines/agos/charset.cpp
+++ b/engines/agos/charset.cpp
@@ -703,12 +703,16 @@ void AGOSEngine_Feeble::windowNewLine(WindowBlock *window) {
}
void AGOSEngine::windowNewLine(WindowBlock *window) {
- if (window->textRow != window->height)
- window->textRow++;
-
window->textColumn = 0;
window->textColumnOffset = 0;
window->textLength = 0;
+
+ if (window->textRow == window->height) {
+ // TODO
+ debug(0, "Window Scroll");
+ } else {
+ window->textRow++;
+ }
}
#ifdef PALMOS_68K
diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp
index 701a6af5f2..c2183bffc2 100644
--- a/engines/agos/draw.cpp
+++ b/engines/agos/draw.cpp
@@ -69,8 +69,15 @@ void AGOSEngine::animateSprites() {
return;
}
- vsp = _vgaSprites;
+ if (_oldDrawMethod) {
+ if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ dirtyClips();
+ }
+ restoreBackGround();
+ }
+
+ vsp = _vgaSprites;
while (vsp->id != 0) {
vsp->windowNum &= 0x7FFF;
@@ -82,17 +89,119 @@ void AGOSEngine::animateSprites() {
_vgaCurSpriteId = vsp->id;
_vgaCurSpritePriority = vsp->priority;
- drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags);
+ if (_oldDrawMethod) {
+ saveBackGround(vsp);
+ }
+ drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags);
vsp++;
}
if (_drawImagesDebug)
memset(_backBuf, 0, _screenWidth * _screenHeight);
+ if (_window6Flag == 1)
+ _window6Flag++;
+
+ if (_window4Flag == 1)
+ _window4Flag++;
+
_updateScreen = true;
}
+void AGOSEngine::dirtyClips() {
+ // TODO
+}
+
+void AGOSEngine::restoreBackGround() {
+ AnimTable *animTable;
+ uint images = 0;
+
+ animTable = _screenAnim1;
+ while (animTable->srcPtr) {
+ animTable++;
+ images++;
+ }
+
+ while (images--) {
+ animTable--;
+
+ if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
+ !(animTable->window & 0x8000)) {
+ //continue;
+ }
+
+ animTable->window &= 0x7FFF;
+ _windowNum = animTable->window;
+
+ VC10_state state;
+ state.srcPtr = animTable->srcPtr;
+ state.height = state.draw_height = animTable->height;
+ state.width = state.draw_width = animTable->width;
+ state.y = animTable->y;
+ state.x = animTable->x;
+ state.palette = 0;
+ state.paletteMod = 0;
+ state.flags = kDFNonTrans;
+
+ _backFlag = 1;
+ drawImage(&state);
+
+ //if (getGameType() != GType_SIMON1 && getGameType() != GType_SIMON2) {
+ animTable->srcPtr = 0;
+ //}
+ }
+ _backFlag = 0;
+
+ if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ AnimTable *animTableTmp;
+
+ animTable = animTableTmp = _screenAnim1;
+ while (animTable->srcPtr != 0) {
+ if (!(animTable->window & 8000)) {
+ memcpy(animTableTmp, animTable, sizeof(AnimTable));
+ animTableTmp++;
+ }
+ animTable++;
+ }
+ animTableTmp->id = 0;
+ }
+}
+
+void AGOSEngine::saveBackGround(VgaSprite *vsp) {
+ if ((vsp->flags & 4) || !vsp->image)
+ return;
+
+ AnimTable *animTable = _screenAnim1;
+
+ while (animTable->srcPtr)
+ animTable++;
+
+ const byte *ptr = _curVgaFile2 + vsp->image * 8;
+ int16 x = vsp->x - _scrollX;
+ int16 y = vsp->y - _scrollY;
+
+ if (_window3Flag == 1) {
+ animTable->srcPtr = (const byte *)_window4BackScn;
+ } else {
+ uint xoffs = (_videoWindows[vsp->windowNum * 4 + 0] * 2 + x) * 8;
+ uint yoffs = (_videoWindows[vsp->windowNum * 4 + 1] + y);
+ animTable->srcPtr = getBackGround() + xoffs + yoffs * _screenWidth;
+ }
+
+ animTable->x = x;
+ animTable->y = y;
+
+ animTable->width = READ_BE_UINT16(ptr + 6) / 16;
+ if (vsp->flags & 40) {
+ animTable->width++;
+ }
+
+ animTable->height = ptr[5];
+ animTable->window = vsp->windowNum;
+ animTable->id = vsp->id;
+}
+
void AGOSEngine::animateSpritesDebug() {
VgaSprite *vsp;
VgaPointersEntry *vpe;
@@ -289,10 +398,16 @@ void AGOSEngine::displayBoxStars() {
}
void AGOSEngine::scrollScreen() {
- byte *dst = getFrontBuf();
+ byte *dst;
const byte *src;
uint x, y;
+ if (!_oldDrawMethod) {
+ dst = getFrontBuf();
+ } else {
+ dst = getBackGround();
+ }
+
if (_scrollXMax == 0) {
uint screenSize = 8 * _screenWidth;
if (_scrollFlag < 0) {
@@ -340,8 +455,16 @@ void AGOSEngine::scrollScreen() {
_scrollX += _scrollFlag;
vcWriteVar(251, _scrollX);
- memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight);
- memcpy(_backGroundBuf, _backBuf, _scrollHeight * _screenWidth);
+ if (!_oldDrawMethod) {
+ memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight);
+ memcpy(_backGroundBuf, _backBuf, _scrollHeight * _screenWidth);
+ } else {
+ memcpy(_window4BackScn, _backGroundBuf, _scrollHeight * _screenWidth);
+ }
+
+ setMoveRect(0, 0, 320, _scrollHeight);
+
+ _window4Flag = 1;
}
_scrollFlag = 0;
@@ -390,6 +513,20 @@ void AGOSEngine::fillBackGroundFromBack(uint lines) {
memcpy(_backGroundBuf, _backBuf, lines * _screenWidth);
}
+void AGOSEngine::setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height) {
+ if (x < _moveXMin)
+ _moveXMin = x;
+
+ if (y < _moveYMin)
+ _moveYMin = y;
+
+ if (width > _moveXMax)
+ _moveXMax = width;
+
+ if (height > _moveYMax)
+ _moveYMax = height;
+}
+
void AGOSEngine::updateScreen() {
if (_fastFadeInFlag == 0 && _paletteFlag == 1) {
_paletteFlag = 0;
@@ -399,11 +536,63 @@ void AGOSEngine::updateScreen() {
}
}
- _system->copyRectToScreen(getBackBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
- _system->updateScreen();
+ if (_oldDrawMethod) {
+ if (_window4Flag == 2) {
+ _window4Flag = 0;
+
+ uint16 srcWidth, width, height;
+ byte *dst = getFrontBuf();
+
+ const byte *src = _window4BackScn;
+ if (_window3Flag == 1) {
+ src = getBackGround();
+ }
- if (getGameId() != GID_DIMP)
- memcpy(getBackBuf(), getFrontBuf(), _screenWidth * _screenHeight);
+ dst += (_moveYMin + _videoWindows[17]) * _screenWidth;
+ dst += (_videoWindows[16] * 16) + _moveXMin;
+
+ src += (_videoWindows[18] * 16 * _moveYMin);
+ src += _moveXMin;
+
+ srcWidth = _videoWindows[18] * 16;
+
+ width = _moveXMax - _moveXMin;
+ height = _moveYMax - _moveYMin;
+
+ for (; height > 0; height--) {
+ memcpy(dst, src, width);
+ dst += _screenWidth;
+ src += srcWidth;
+ }
+
+ _moveXMin = 0xFFFF;
+ _moveYMin = 0xFFFF;
+ _moveXMax = 0;
+ _moveYMax = 0;
+ }
+
+ if (_window6Flag == 2) {
+ _window6Flag = 0;
+
+ byte *src = _window6BackScn;
+ byte *dst = getFrontBuf() + 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();
+ } else {
+ _system->copyRectToScreen(getBackBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
+ _system->updateScreen();
+
+ if (getGameId() != GID_DIMP)
+ memcpy(getBackBuf(), getFrontBuf(), _screenWidth * _screenHeight);
+
+ }
if (getGameType() == GType_FF && _scrollFlag) {
scrollScreen();
diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp
index 93ab997e64..579837833d 100644
--- a/engines/agos/event.cpp
+++ b/engines/agos/event.cpp
@@ -123,6 +123,7 @@ void AGOSEngine::killAllTimers() {
next = cur->next;
delTimeEvent(cur);
}
+ _clickOnly = 0;
}
bool AGOSEngine::kickoffTimeEvents() {
@@ -164,32 +165,30 @@ bool AGOSEngine::isVgaQueueEmpty() {
}
void AGOSEngine::haltAnimation() {
- VgaTimerEntry *vte = _vgaTimerList;
+ if (_lockWord & 0x10)
+ return;
_lockWord |= 0x10;
- while (vte->delay) {
- vte->delay += 10;
+ if (_updateScreen != false) {
+ updateScreen();
+ _updateScreen = false;
}
}
void AGOSEngine::restartAnimation() {
+ if (!(_lockWord & 0x10))
+ return;
+
+ updateScreen();
_lockWord &= ~0x10;
+
+ // Check picture queue
}
void AGOSEngine::addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum) {
VgaTimerEntry *vte;
- // When Simon talks to the Golum about stew in French version of
- // Simon the Sorcerer 1 the code_ptr is at wrong location for
- // sprite 200. This was a bug in the original game, which
- // caused several glitches in this scene.
- // We work around the problem by correcting the code_ptr for sprite
- // 200 in this scene, if it is wrong.
- if (getGameType() == GType_SIMON1 && _language == Common::FR_FRA &&
- (code_ptr - _vgaBufferPointers[curZoneNum].vgaFile1 == 4) && (cur_sprite == 200) && (curZoneNum == 2))
- code_ptr += 0x66;
-
_lockWord |= 1;
for (vte = _vgaTimerList; vte->delay; vte++) {
diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp
index 5f7ec849f8..607c07d2b3 100644
--- a/engines/agos/gfx.cpp
+++ b/engines/agos/gfx.cpp
@@ -224,6 +224,70 @@ bool AGOSEngine::drawImage_clip(VC10_state *state) {
return 1;
}
+void AGOSEngine_Feeble::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) {
+ Common::Rect srcRect, dstRect;
+ float factor, xscale;
+
+ srcRect.left = 0;
+ srcRect.top = 0;
+ srcRect.right = w;
+ srcRect.bottom = h;
+
+ if (scrollY > _baseY)
+ factor = 1 + ((scrollY - _baseY) * _scale);
+ else
+ factor = 1 - ((_baseY - scrollY) * _scale);
+
+ xscale = ((w * factor) / 2);
+
+ dstRect.left = (int16)(x - xscale);
+ if (dstRect.left > _screenWidth - 1)
+ return;
+ dstRect.top = (int16)(y - (h * factor));
+ if (dstRect.top > _screenHeight - 1)
+ return;
+
+ dstRect.right = (int16)(x + xscale);
+ dstRect.bottom = y;
+
+ _feebleRect = dstRect;
+
+ _variableArray[20] = _feebleRect.top;
+ _variableArray[21] = _feebleRect.left;
+ _variableArray[22] = _feebleRect.bottom;
+ _variableArray[23] = _feebleRect.right;
+
+ debug(5, "Left %d Right %d Top %d Bottom %d", dstRect.left, dstRect.right, dstRect.top, dstRect.bottom);
+
+ // Unlike normal rectangles in ScummVM, it seems that in the case of
+ // the destination rectangle the bottom and right coordinates are
+ // considered to be inside the rectangle. For the source rectangle,
+ // I believe that they are not.
+
+ int scaledW = dstRect.width() + 1;
+ int scaledH = dstRect.height() + 1;
+
+ byte *src = getScaleBuf();
+ byte *dst = getBackBuf();
+
+ dst += _dxSurfacePitch * dstRect.top + dstRect.left;
+
+ for (int dstY = 0; dstY < scaledH; dstY++) {
+ if (dstRect.top + dstY >= 0 && dstRect.top + dstY < _screenHeight) {
+ int srcY = (dstY * h) / scaledH;
+ byte *srcPtr = src + _dxSurfacePitch * srcY;
+ byte *dstPtr = dst + _dxSurfacePitch * dstY;
+ for (int dstX = 0; dstX < scaledW; dstX++) {
+ if (dstRect.left + dstX >= 0 && dstRect.left + dstX < _screenWidth) {
+ int srcX = (dstX * w) / scaledW;
+ if (srcPtr[srcX])
+ dstPtr[dstX] = srcPtr[srcX];
+ }
+ }
+ }
+ }
+}
+
void AGOSEngine_Feeble::drawImage(VC10_state *state) {
if (state->flags & kDFCompressed) {
if (state->flags & kDFScaled) {
@@ -387,304 +451,285 @@ void AGOSEngine_Feeble::drawImage(VC10_state *state) {
}
}
-void AGOSEngine_Simon1::drawImage(VC10_state *state) {
- const uint16 *vlut = &_videoWindows[_windowNum * 4];
-
- if (drawImage_clip(state) == 0)
- return;
+void AGOSEngine_Simon1::drawMaskedImage(VC10_state *state) {
+ if (getFeatures() & GF_32COLOR) {
+ const byte *mask = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8);
+ byte *src = state->surf2_addr;
+ byte *dst = state->surf_addr;
- if (getFeatures() & GF_32COLOR)
- state->palette = 0xC0;
+ state->draw_width *= 2;
- uint xoffs, yoffs;
- if (getGameType() == GType_SIMON1 && (_subroutine == 2923 || _subroutine == 2926)) {
- // Allow one section of Simon the Sorcerer 1 introduction to be displayed
- // in lower half of screen
- xoffs = state->x * 8;
- yoffs = state->y;
- } else {
- xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
- yoffs = (vlut[1] - _videoWindows[17] + state->y);
- }
+ uint h = state->draw_height;
+ do {
+ for (uint i = 0; i != state->draw_width; i++) {
+ if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
+ /* transparency */
+ if (mask[i] && (dst[i] & 16))
+ dst[i] = src[i];
+ } else {
+ /* no transparency */
+ if (mask[i])
+ dst[i] = src[i];
+ }
+ }
+ dst += state->surf_pitch;
+ src += state->surf2_pitch;
+ mask += state->width * 16;
+ } while (--h);
+ } else if (state->flags & kDFCompressed) {
+ byte *mask, *src, *dst;
+ byte h;
+ uint w;
- state->surf2_addr += xoffs + yoffs * state->surf_pitch;
- state->surf_addr += xoffs + yoffs * state->surf2_pitch;
+ state->x_skip *= 4;
+ state->dl = state->width;
+ state->dh = state->height;
- if (state->flags & kDFMasked) {
- if (getFeatures() & GF_32COLOR) {
- const byte *mask = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8);
- byte *src = state->surf2_addr;
- byte *dst = state->surf_addr;
+ vc10_skip_cols(state);
- state->draw_width *= 2;
+ w = 0;
+ do {
+ mask = vc10_depackColumn(state); /* esi */
+ src = state->surf2_addr + w * 2; /* ebx */
+ dst = state->surf_addr + w * 2; /* edi */
- uint h = state->draw_height;
+ h = state->draw_height;
do {
- for (uint i = 0; i != state->draw_width; i++) {
- if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
- /* transparency */
- if (mask[i] && (dst[i] & 16))
- dst[i] = src[i];
- } else {
- /* no transparency */
- if (mask[i])
- dst[i] = src[i];
- }
+ if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
+ /* transparency */
+ if ((mask[0] & 0xF0) && (dst[0] & 0x0F0) == 0x20)
+ dst[0] = src[0];
+ if ((mask[0] & 0x0F) && (dst[1] & 0x0F0) == 0x20)
+ dst[1] = src[1];
+ } else {
+ /* no transparency */
+ if (mask[0] & 0xF0)
+ dst[0] = src[0];
+ if (mask[0] & 0x0F)
+ dst[1] = src[1];
}
+ mask++;
dst += state->surf_pitch;
src += state->surf2_pitch;
- mask += state->width * 16;
} while (--h);
- } else if (state->flags & kDFCompressed) {
- byte *mask, *src, *dst;
- byte h;
- uint w;
-
- state->x_skip *= 4;
- state->dl = state->width;
- state->dh = state->height;
-
- vc10_skip_cols(state);
-
- w = 0;
- do {
- mask = vc10_depackColumn(state); /* esi */
- src = state->surf2_addr + w * 2; /* ebx */
- dst = state->surf_addr + w * 2; /* edi */
-
- h = state->draw_height;
- do {
- if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
- /* transparency */
- if ((mask[0] & 0xF0) && (dst[0] & 0x0F0) == 0x20)
- dst[0] = src[0];
- if ((mask[0] & 0x0F) && (dst[1] & 0x0F0) == 0x20)
- dst[1] = src[1];
- } else {
- /* no transparency */
- if (mask[0] & 0xF0)
- dst[0] = src[0];
- if (mask[0] & 0x0F)
- dst[1] = src[1];
- }
- mask++;
- dst += state->surf_pitch;
- src += state->surf2_pitch;
- } while (--h);
- } while (++w != state->draw_width);
- } else {
- const byte *src, *mask;
- byte *dst;
- uint count;
+ } while (++w != state->draw_width);
+ } else {
+ const byte *src, *mask;
+ byte *dst;
+ uint count;
- mask = state->srcPtr + (state->width * state->y_skip) * 8;
- src = state->surf2_addr;
- dst = state->surf_addr;
+ mask = state->srcPtr + (state->width * state->y_skip) * 8;
+ src = state->surf2_addr;
+ dst = state->surf_addr;
- state->x_skip *= 4;
+ state->x_skip *= 4;
- do {
- for (count = 0; count != state->draw_width; count++) {
- if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
- /* transparency */
- if (mask[count + state->x_skip] & 0xF0)
- if ((dst[count * 2] & 0xF0) == 0x20)
- dst[count * 2] = src[count * 2];
- if (mask[count + state->x_skip] & 0x0F)
- if ((dst[count * 2 + 1] & 0x0F) == 0x20)
- dst[count * 2 + 1] = src[count * 2 + 1];
- } else {
- /* no transparency */
- if (mask[count + state->x_skip] & 0xF0)
+ do {
+ for (count = 0; count != state->draw_width; count++) {
+ if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
+ /* transparency */
+ if (mask[count + state->x_skip] & 0xF0)
+ if ((dst[count * 2] & 0xF0) == 0x20)
dst[count * 2] = src[count * 2];
- if (mask[count + state->x_skip] & 0x0F)
+ if (mask[count + state->x_skip] & 0x0F)
+ if ((dst[count * 2 + 1] & 0x0F) == 0x20)
dst[count * 2 + 1] = src[count * 2 + 1];
- }
+ } else {
+ /* no transparency */
+ if (mask[count + state->x_skip] & 0xF0)
+ dst[count * 2] = src[count * 2];
+ if (mask[count + state->x_skip] & 0x0F)
+ dst[count * 2 + 1] = src[count * 2 + 1];
}
- src += _screenWidth;
- dst += _screenWidth;
- mask += state->width * 8;
- } while (--state->draw_height);
- }
- } else if (((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) {
- const byte *src;
- byte *dst;
- uint h, i;
+ }
+ src += _screenWidth;
+ dst += _screenWidth;
+ mask += state->width * 8;
+ } while (--state->draw_height);
+ }
+}
+
+void AGOSEngine_Simon1::draw32ColorImage(VC10_state *state) {
+ const byte *src;
+ byte *dst;
+ uint h, i;
+
+ if (state->flags & kDFCompressed) {
+ byte *dstPtr = state->surf_addr;
+ src = state->srcPtr;
+ /* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE
+ * aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh
+ */
- if (state->flags & kDFCompressed) {
- byte *dstPtr = state->surf_addr;
- src = state->srcPtr;
- /* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE
- * aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh
- */
+ do {
+ uint count = state->draw_width / 4;
+ dst = dstPtr;
do {
- uint count = state->draw_width / 4;
+ uint32 bits = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | (src[3]);
+ byte color;
- dst = dstPtr;
- do {
- uint32 bits = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | (src[3]);
- byte color;
+ color = (byte)((bits >> (32 - 5)) & 31);
+ if ((state->flags & kDFNonTrans) || color)
+ dst[0] = color;
+ color = (byte)((bits >> (32 - 10)) & 31);
+ if ((state->flags & kDFNonTrans) || color)
+ dst[1] = color;
+ color = (byte)((bits >> (32 - 15)) & 31);
+ if ((state->flags & kDFNonTrans) || color)
+ dst[2] = color;
+ color = (byte)((bits >> (32 - 20)) & 31);
+ if ((state->flags & kDFNonTrans) || color)
+ dst[3] = color;
+ color = (byte)((bits >> (32 - 25)) & 31);
+ if ((state->flags & kDFNonTrans) || color)
+ dst[4] = color;
+ color = (byte)((bits >> (32 - 30)) & 31);
+ if ((state->flags & kDFNonTrans) || color)
+ dst[5] = color;
- color = (byte)((bits >> (32 - 5)) & 31);
- if ((state->flags & kDFNonTrans) || color)
- dst[0] = color;
- color = (byte)((bits >> (32 - 10)) & 31);
- if ((state->flags & kDFNonTrans) || color)
- dst[1] = color;
- color = (byte)((bits >> (32 - 15)) & 31);
- if ((state->flags & kDFNonTrans) || color)
- dst[2] = color;
- color = (byte)((bits >> (32 - 20)) & 31);
- if ((state->flags & kDFNonTrans) || color)
- dst[3] = color;
- color = (byte)((bits >> (32 - 25)) & 31);
- if ((state->flags & kDFNonTrans) || color)
- dst[4] = color;
- color = (byte)((bits >> (32 - 30)) & 31);
- if ((state->flags & kDFNonTrans) || color)
- dst[5] = color;
-
- bits = (bits << 8) | src[4];
-
- color = (byte)((bits >> (40 - 35)) & 31);
- if ((state->flags & kDFNonTrans) || color)
- dst[6] = color;
- color = (byte)((bits) & 31);
- if ((state->flags & kDFNonTrans) || color)
- dst[7] = color;
-
- dst += 8;
- src += 5;
- } while (--count);
- dstPtr += _screenWidth;
- } while (--state->draw_height);
- } else {
- src = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8);
- dst = state->surf_addr;
+ bits = (bits << 8) | src[4];
- state->draw_width *= 2;
+ color = (byte)((bits >> (40 - 35)) & 31);
+ if ((state->flags & kDFNonTrans) || color)
+ dst[6] = color;
+ color = (byte)((bits) & 31);
+ if ((state->flags & kDFNonTrans) || color)
+ dst[7] = color;
- h = state->draw_height;
- do {
- for (i = 0; i != state->draw_width; i++)
- if ((state->flags & kDFNonTrans) || src[i])
- dst[i] = src[i];
- dst += _screenWidth;
- src += state->width * 16;
- } while (--h);
- }
+ dst += 8;
+ src += 5;
+ } while (--count);
+ dstPtr += _screenWidth;
+ } while (--state->draw_height);
} else {
- if (getGameType() == GType_SIMON2 && state->flags & kDFUseFrontBuf && getBitFlag(171)) {
- state->surf_addr = state->surf2_addr;
- state->surf_pitch = state->surf2_pitch;
+ src = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8);
+ dst = state->surf_addr;
+
+ state->draw_width *= 2;
+
+ h = state->draw_height;
+ do {
+ for (i = 0; i != state->draw_width; i++)
+ if ((state->flags & kDFNonTrans) || src[i])
+ dst[i] = src[i];
+ dst += _screenWidth;
+ src += state->width * 16;
+ } while (--h);
+ }
+}
+
+void AGOSEngine_Simon1::drawImage(VC10_state *state) {
+ const uint16 *vlut = &_videoWindows[_windowNum * 4];
+
+ if (drawImage_clip(state) == 0)
+ return;
+
+ if (getFeatures() & GF_32COLOR)
+ state->palette = 0xC0;
+
+ uint16 xoffs, yoffs;
+ if (!_oldDrawMethod) {
+ if (getGameType() == GType_SIMON1 && (_subroutine == 2923 || _subroutine == 2926)) {
+ // Allow one section of Simon the Sorcerer 1 introduction to be displayed
+ // in lower half of screen
+ xoffs = state->x * 8;
+ yoffs = state->y;
+ } else {
+ xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+ yoffs = (vlut[1] - _videoWindows[17] + state->y);
}
+ } else if (getGameType() == GType_SIMON2) {
+ state->surf2_addr = getBackGround();
+ state->surf2_pitch = _screenWidth;
- if (state->flags & kDFCompressed) {
- uint w, h;
- byte *src, *dst, *dstPtr;
+ state->surf_addr = _window4BackScn;
+ state->surf_pitch = _screenWidth;
- state->x_skip *= 4; /* reached */
+ xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+ yoffs = (vlut[1] - _videoWindows[17] + state->y);
- state->dl = state->width;
- state->dh = state->height;
+ uint xmax = (xoffs + state->draw_width * 2);
+ uint ymax = (yoffs + state->draw_height);
+ setMoveRect(xoffs, yoffs, xmax, ymax);
- vc10_skip_cols(state);
+ _window4Flag = 1;
+ } else if (getGameType() == GType_SIMON1) {
+ if (_windowNum == 3 || _windowNum == 4 || _windowNum >= 10) {
+ if (_windowNum == 3) {
+ state->surf2_addr = getBackGround();
+ state->surf2_pitch = _screenWidth;
- dstPtr = state->surf_addr;
- if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */
- dstPtr += vcReadVar(252);
+ state->surf_addr = getBackGround();
+ state->surf_pitch = _screenWidth;
+ } else {
+ state->surf2_addr = getBackGround();
+ state->surf2_pitch = _screenWidth;
+
+ state->surf_addr = _window4BackScn;
+ state->surf_pitch = _screenWidth;
}
- w = 0;
- do {
- byte color;
- src = vc10_depackColumn(state);
- dst = dstPtr;
+ xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+ yoffs = (vlut[1] - _videoWindows[17] + state->y);
- h = 0;
- do {
- color = (*src / 16);
- if ((state->flags & kDFNonTrans) || color != 0)
- dst[0] = color | state->palette;
- color = (*src & 15);
- if ((state->flags & kDFNonTrans) || color != 0)
- dst[1] = color | state->palette;
- dst += _screenWidth;
- src++;
- } while (++h != state->draw_height);
- dstPtr += 2;
- } while (++w != state->draw_width);
+ uint xmax = (xoffs + state->draw_width * 2);
+ uint ymax = (yoffs + state->draw_height);
+ setMoveRect(xoffs, yoffs, xmax, ymax);
+
+ _window4Flag = 1;
} else {
- const byte *src;
- byte *dst;
- uint count;
+ state->surf2_addr = getBackGround();
+ state->surf2_pitch = _screenWidth;
- src = state->srcPtr + (state->width * state->y_skip) * 8;
- dst = state->surf_addr;
- state->x_skip *= 4;
+ state->surf_addr = getFrontBuf();
+ state->surf_pitch = _screenWidth;
- do {
- for (count = 0; count != state->draw_width; count++) {
- byte color;
- color = (src[count + state->x_skip] / 16);
- if ((state->flags & kDFNonTrans) || color)
- dst[count * 2] = color | state->palette;
- color = (src[count + state->x_skip] & 15);
- if ((state->flags & kDFNonTrans) || color)
- dst[count * 2 + 1] = color | state->palette;
- }
- dst += _screenWidth;
- src += state->width * 8;
- } while (--state->draw_height);
+ xoffs = (vlut[0] * 2 + state->x) * 8;
+ yoffs = vlut[1] + state->y;
}
}
+
+ state->surf_addr += xoffs + yoffs * state->surf_pitch;
+ state->surf2_addr += xoffs + yoffs * state->surf2_pitch;
+
+ if (_backFlag == 1) {
+ drawBackGroundImage(state);
+ } else if (state->flags & kDFMasked) {
+ drawMaskedImage(state);
+ } else if (((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) {
+ draw32ColorImage(state);
+ } else {
+ drawVertImage(state);
+ }
}
-void AGOSEngine::drawImage(VC10_state *state) {
- const uint16 *vlut = &_videoWindows[_windowNum * 4];
+void AGOSEngine::drawBackGroundImage(VC10_state *state) {
+ const byte *src;
+ byte *dst;
+ uint h, i;
- if (drawImage_clip(state) == 0)
- return;
+ src = state->srcPtr + (_screenWidth * state->y_skip) + (state->x_skip * 8);
+ dst = state->surf_addr;
- uint xoffs = 0, yoffs = 0;
- if (getGameType() == GType_ELVIRA1) {
- //if (_windowNum != 2 && _windowNum != 3 && _windowNum != 6) {
- // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
- // yoffs = (vlut[1] - _videoWindows[17] + state->y);
- //} else {
- xoffs = (vlut[0] * 2 + state->x) * 8;
- yoffs = vlut[1] + state->y;
- //}
- } else if (getGameType() == GType_ELVIRA2) {
- //if (_windowNum == 4 || _windowNum >= 10) {
- // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
- // yoffs = (vlut[1] - _videoWindows[17] + state->y);
- //} else {
- xoffs = (vlut[0] * 2 + state->x) * 8;
- yoffs = vlut[1] + state->y;
- //}
- } else if (getGameType() == GType_WW) {
- //if (_windowNum == 4 || (_windowNum >= 10 && _windowNum < 28)) {
- // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
- // yoffs = (vlut[1] - _videoWindows[17] + state->y);
- //} else {
- xoffs = (vlut[0] * 2 + state->x) * 8;
- yoffs = vlut[1] + state->y;
- //}
- }
+ state->draw_width *= 2;
- state->surf_addr += xoffs + yoffs * state->surf_pitch;
- state->surf2_addr += xoffs + yoffs * state->surf2_pitch;
+ h = state->draw_height;
+ do {
+ for (i = 0; i != state->draw_width; i++)
+ dst[i] = src[i] + state->paletteMod;
+ dst += state->surf_pitch;
+ src += _screenWidth;
+ } while (--h);
+}
- if (state->flags & kDFUseFrontBuf) {
+void AGOSEngine::drawVertImage(VC10_state *state) {
+ if (getGameType() == GType_SIMON2 && (state->flags & kDFUseFrontBuf) && getBitFlag(171) &&
+ !_oldDrawMethod) {
state->surf_addr = state->surf2_addr;
state->surf_pitch = state->surf2_pitch;
}
- if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
- state->palette = state->surf_addr[0] & 0xF0;
-
if (state->flags & kDFCompressed) {
uint w, h;
byte *src, *dst, *dstPtr;
@@ -697,6 +742,9 @@ void AGOSEngine::drawImage(VC10_state *state) {
vc10_skip_cols(state);
dstPtr = state->surf_addr;
+ if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */
+ dstPtr += vcReadVar(252);
+ }
w = 0;
do {
byte color;
@@ -712,7 +760,7 @@ void AGOSEngine::drawImage(VC10_state *state) {
color = (*src & 15);
if ((state->flags & kDFNonTrans) || color != 0)
dst[1] = color | state->palette;
- dst += _screenWidth;
+ dst += state->surf_pitch;
src++;
} while (++h != state->draw_height);
dstPtr += 2;
@@ -726,26 +774,112 @@ void AGOSEngine::drawImage(VC10_state *state) {
dst = state->surf_addr;
state->x_skip *= 4;
- uint8 extraPal = 0;
- if (getGameType() == GType_ELVIRA1 && (state->flags & kDFNonTrans) && yoffs > 133)
- extraPal = 16;
-
do {
for (count = 0; count != state->draw_width; count++) {
byte color;
- color = (src[count + state->x_skip] / 16) + extraPal;
+ color = (src[count + state->x_skip] / 16) + state->paletteMod;
if ((state->flags & kDFNonTrans) || color)
dst[count * 2] = color | state->palette;
- color = (src[count + state->x_skip] & 15) + extraPal;
+ color = (src[count + state->x_skip] & 15) + state->paletteMod;
if ((state->flags & kDFNonTrans) || color)
dst[count * 2 + 1] = color | state->palette;
}
- dst += _screenWidth;
+ dst += state->surf_pitch;
src += state->width * 8;
} while (--state->draw_height);
}
}
+void AGOSEngine::drawImage(VC10_state *state) {
+ const uint16 *vlut = &_videoWindows[_windowNum * 4];
+
+ if (drawImage_clip(state) == 0)
+ return;
+
+ uint16 xoffs, yoffs;
+ if (getGameType() == GType_WW) {
+ if (_windowNum == 4 || (_windowNum >= 10 && _windowNum <= 27)) {
+ state->surf_addr = _window4BackScn;
+ state->surf_pitch = _videoWindows[18] * 16;
+
+ xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+ yoffs = (vlut[1] - _videoWindows[17] + state->y);
+
+ uint xmax = (xoffs + state->draw_width * 2);
+ uint ymax = (yoffs + state->draw_height);
+ setMoveRect(xoffs, yoffs, xmax, ymax);
+
+ _window4Flag = 1;
+ } else {
+ state->surf_addr = getFrontBuf();
+ state->surf_pitch = _screenWidth;
+
+ xoffs = (vlut[0] * 2 + state->x) * 8;
+ yoffs = vlut[1] + state->y;
+ }
+ } else if (getGameType() == GType_ELVIRA2) {
+ if (_windowNum == 4 || _windowNum >= 10) {
+ state->surf_addr = _window4BackScn;
+ state->surf_pitch = _videoWindows[18] * 16;
+
+ xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+ yoffs = (vlut[1] - _videoWindows[17] + state->y);
+
+ uint xmax = (xoffs + state->draw_width * 2);
+ uint ymax = (yoffs + state->draw_height);
+ setMoveRect(xoffs, yoffs, xmax, ymax);
+
+ _window4Flag = 1;
+ } else {
+ state->surf_addr = getFrontBuf();
+ state->surf_pitch = _screenWidth;
+
+ xoffs = (vlut[0] * 2 + state->x) * 8;
+ yoffs = vlut[1] + state->y;
+ }
+ } else if (getGameType() == GType_ELVIRA1) {
+ if (_windowNum == 6) {
+ state->surf_addr = _window6BackScn;
+ state->surf_pitch = 48;
+
+ xoffs = state->x * 8;
+ yoffs = state->y;
+ } else if (_windowNum == 2 || _windowNum == 3) {
+ state->surf_addr = getFrontBuf();
+ state->surf_pitch = _screenWidth;
+
+ xoffs = (vlut[0] * 2 + state->x) * 8;
+ yoffs = vlut[1] + state->y;
+
+ } else {
+ state->surf_addr = _window4BackScn;
+ state->surf_pitch = _videoWindows[18] * 16;
+
+ xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+ yoffs = (vlut[1] - _videoWindows[17] + state->y);
+
+ uint xmax = (xoffs + state->draw_width * 2);
+ uint ymax = (yoffs + state->draw_height);
+ setMoveRect(xoffs, yoffs, xmax, ymax);
+
+ _window4Flag = 1;
+ }
+ }
+
+ state->surf_addr += xoffs + yoffs * state->surf_pitch;
+
+ if (getGameType() == GType_ELVIRA1 && (state->flags & kDFNonTrans) && yoffs > 133)
+ state->paletteMod = 16;
+
+ if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
+ state->palette = state->surf_addr[0] & 0xF0;
+
+ if (_backFlag == 1) {
+ drawBackGroundImage(state);
+ } else {
+ drawVertImage(state);
+ }
+}
void AGOSEngine::horizontalScroll(VC10_state *state) {
const byte *src;
@@ -766,7 +900,11 @@ void AGOSEngine::horizontalScroll(VC10_state *state) {
vcWriteVar(251, _scrollX);
- dst = getBackBuf();
+ if (!_oldDrawMethod) {
+ dst = getBackBuf();
+ } else {
+ dst = _window4BackScn;
+ }
if (getGameType() == GType_FF)
src = state->srcPtr + _scrollX / 2;
@@ -778,6 +916,10 @@ void AGOSEngine::horizontalScroll(VC10_state *state) {
dst += 8;
src += 4;
}
+
+ setMoveRect(0, 0, 320, _scrollHeight);
+
+ _window4Flag = 1;
}
void AGOSEngine::verticalScroll(VC10_state *state) {
@@ -806,70 +948,6 @@ void AGOSEngine::verticalScroll(VC10_state *state) {
}
}
-void AGOSEngine_Feeble::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) {
- Common::Rect srcRect, dstRect;
- float factor, xscale;
-
- srcRect.left = 0;
- srcRect.top = 0;
- srcRect.right = w;
- srcRect.bottom = h;
-
- if (scrollY > _baseY)
- factor = 1 + ((scrollY - _baseY) * _scale);
- else
- factor = 1 - ((_baseY - scrollY) * _scale);
-
- xscale = ((w * factor) / 2);
-
- dstRect.left = (int16)(x - xscale);
- if (dstRect.left > _screenWidth - 1)
- return;
- dstRect.top = (int16)(y - (h * factor));
- if (dstRect.top > _screenHeight - 1)
- return;
-
- dstRect.right = (int16)(x + xscale);
- dstRect.bottom = y;
-
- _feebleRect = dstRect;
-
- _variableArray[20] = _feebleRect.top;
- _variableArray[21] = _feebleRect.left;
- _variableArray[22] = _feebleRect.bottom;
- _variableArray[23] = _feebleRect.right;
-
- debug(5, "Left %d Right %d Top %d Bottom %d", dstRect.left, dstRect.right, dstRect.top, dstRect.bottom);
-
- // Unlike normal rectangles in ScummVM, it seems that in the case of
- // the destination rectangle the bottom and right coordinates are
- // considered to be inside the rectangle. For the source rectangle,
- // I believe that they are not.
-
- int scaledW = dstRect.width() + 1;
- int scaledH = dstRect.height() + 1;
-
- byte *src = getScaleBuf();
- byte *dst = getBackBuf();
-
- dst += _dxSurfacePitch * dstRect.top + dstRect.left;
-
- for (int dstY = 0; dstY < scaledH; dstY++) {
- if (dstRect.top + dstY >= 0 && dstRect.top + dstY < _screenHeight) {
- int srcY = (dstY * h) / scaledH;
- byte *srcPtr = src + _dxSurfacePitch * srcY;
- byte *dstPtr = dst + _dxSurfacePitch * dstY;
- for (int dstX = 0; dstX < scaledW; dstX++) {
- if (dstRect.left + dstX >= 0 && dstRect.left + dstX < _screenWidth) {
- int srcX = (dstX * w) / scaledW;
- if (srcPtr[srcX])
- dstPtr[dstX] = srcPtr[srcX];
- }
- }
- }
- }
-}
-
void AGOSEngine::paletteFadeOut(byte *palPtr, uint num, uint size) {
byte *p = palPtr;
@@ -1074,6 +1152,9 @@ void AGOSEngine::setImage(uint16 vga_res_id, bool vgaScript) {
b += sizeof(ImageHeader_Simon);
}
assert(READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == vga_res_id);
+
+ if (!vgaScript && _oldDrawMethod)
+ clearVideoWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_Simon *) b)->color));
} else {
b = bb + READ_BE_UINT16(bb + 10);
b += 20;
@@ -1089,7 +1170,7 @@ void AGOSEngine::setImage(uint16 vga_res_id, bool vgaScript) {
assert(READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == vga_res_id);
if (!vgaScript)
- clearWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_WW *) b)->color));
+ clearVideoWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_WW *) b)->color));
}
if (_startVgaScript) {
@@ -1117,6 +1198,8 @@ void AGOSEngine::setImage(uint16 vga_res_id, bool vgaScript) {
}
void AGOSEngine::setWindowImageEx(uint16 mode, uint16 vga_res) {
+ _window3Flag = 0;
+
if (mode == 4) {
vc29_stopAllSounds();
@@ -1151,10 +1234,10 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
vc27_resetSprite();
}
- if (vga_res_id == 0) {
+ if (!vga_res_id) {
if (getGameType() == GType_SIMON1) {
_unkPalFlag = true;
- } else if (getGameType() == GType_SIMON2) {
+ } else if (getGameType() == GType_SIMON2 && !_oldDrawMethod) {
_useBackGround = true;
_restoreWindow6 = true;
}
@@ -1187,7 +1270,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
fillFrontFromBack(0, 0, _screenWidth, _screenHeight);
fillBackGroundFromBack(_screenHeight);
_syncFlag2 = 1;
- } else if (getGameType() == GType_SIMON2) {
+ } else if (getGameType() == GType_SIMON2 && !_oldDrawMethod) {
if (!_useBackGround) {
num_lines = _windowNum == 4 ? 134 : 200;
_boxStarHeight = num_lines;
@@ -1196,7 +1279,7 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
_syncFlag2 = 1;
}
_useBackGround = false;
- } else if (getGameType() == GType_SIMON1) {
+ } else if (getGameType() == GType_SIMON1 && !_oldDrawMethod) {
// Allow one section of Simon the Sorcerer 1 introduction to be displayed
// in lower half of screen
if (_subroutine == 2923 || _subroutine == 2926)
@@ -1209,21 +1292,90 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
_syncFlag2 = 1;
_timer5 = 0;
} else {
- num_lines = _windowNum == 4 ? 134 : 200;
- fillFrontFromBack(0, 0, _screenWidth, num_lines);
- fillBackGroundFromBack(num_lines);
- _syncFlag2 = 1;
- _timer5 = 0;
- }
+ if (_window3Flag == 1) {
+ clearVideoBackGround(3, 0); // (window, color)
+ }
- if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette != 0) {
- byte *dst = getBackBuf() + 42560;
- int size = 21440;
+ uint xoffs = _videoWindows[updateWindow * 4 + 0] * 16;
+ uint yoffs = _videoWindows[updateWindow * 4 + 1];
+ uint width = _videoWindows[updateWindow * 4 + 2] * 16;
+ uint height = _videoWindows[updateWindow * 4 + 3];
+
+ byte *dst = getBackGround() + xoffs + yoffs * _screenWidth;
+ byte *src;
+ uint srcWidth;
+
+ if (getGameType() == GType_SIMON2) {
+ src = _window4BackScn + xoffs + yoffs * 320;
+ srcWidth = 320;
+ } else if (getGameType() == GType_SIMON1) {
+ if (updateWindow == 4) {
+ src = _window4BackScn;
+ srcWidth = _videoWindows[18] * 16;
+ } else if (updateWindow >= 10) {
+ src = _window4BackScn + xoffs + yoffs * 320;
+ srcWidth = _videoWindows[18] * 16;
+ } else if (updateWindow == 0) {
+ src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+ srcWidth = _screenWidth;
+ } else {
+ _lockWord &= ~0x20;
+ return;
+ }
+ } else if (getGameType() == GType_WW) {
+ if (updateWindow == 4 || updateWindow >= 10) {
+ src = _window4BackScn;
+ srcWidth = _videoWindows[18] * 16;
+ } else if (updateWindow == 3 || updateWindow == 9) {
+ src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+ srcWidth = _screenWidth;
+ } else {
+ _lockWord &= ~0x20;
+ return;
+ }
+ } else if (getGameType() == GType_ELVIRA2) {
+ if (updateWindow == 4 || updateWindow >= 10) {
+ src = _window4BackScn;
+ srcWidth = _videoWindows[18] * 16;
+ } else if (updateWindow == 3) {
+ src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+ srcWidth = _screenWidth;
+ } else {
+ _lockWord &= ~0x20;
+ return;
+ }
+ } else if (getGameType() == GType_ELVIRA1) {
+ if (updateWindow == 6) {
+ _window6Flag = 1;
+ src = _window6BackScn;
+ srcWidth = 48;
+ } else if (updateWindow == 2 || updateWindow == 3) {
+ src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+ srcWidth = _screenWidth;
+ } else {
+ src = _window4BackScn;
+ srcWidth = _videoWindows[18] * 16;
+ }
+ }
- while (size--) {
- *dst += 0x10;
- dst++;
+ for (; height > 0; height--) {
+ memcpy(dst, src, width);
+ dst += _screenWidth;
+ src += srcWidth;
}
+
+ if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette != 0) {
+ dst = getFrontBuf() + 42560;
+ int size = 21440;
+
+ while (size--) {
+ *dst += 0x10;
+ dst++;
+ }
+ }
+
+ _syncFlag2 = 1;
+ _timer5 = 0;
}
_lockWord &= ~0x20;
diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp
index f84083b7bc..d0fab120f5 100644
--- a/engines/agos/input.cpp
+++ b/engines/agos/input.cpp
@@ -174,6 +174,7 @@ void AGOSEngine::waitForInput() {
_verbHitArea = 0;
_hitAreaSubjectItem = NULL;
_hitAreaObjectItem = NULL;
+ _clickOnly = 0;
_nameLocked = 0;
if (getGameType() == GType_WW) {
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 0e82033ea2..40960c0cbe 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -118,15 +118,21 @@ char *AGOSEngine::genSaveName(int slot) {
sprintf(buf, "feeble.%.3d", slot);
} else if (getGameType() == GType_SIMON2) {
sprintf(buf, "simon2.%.3d", slot);
- } else {
+ } else if (getGameType() == GType_SIMON1) {
sprintf(buf, "simon1.%.3d", slot);
+ } else if (getGameType() == GType_WW) {
+ sprintf(buf, "waxworks.%.3d", slot);
+ } else if (getGameType() == GType_ELVIRA2) {
+ sprintf(buf, "elvira2.%.3d", slot);
+ } else if (getGameType() == GType_ELVIRA1) {
+ sprintf(buf, "elvira1.%.3d", slot);
}
return buf;
}
void AGOSEngine::quickLoadOrSave() {
// Quick load & save is only supported complete version of Simon the Sorcerer 1/2
- if (getGameType() != GType_SIMON1 && getGameType() != GType_SIMON2 ||
+ if (getGameType() == GType_PP || getGameType() == GType_FF ||
(getFeatures() & GF_DEMO)) {
return;
}
diff --git a/engines/agos/script_e1.cpp b/engines/agos/script_e1.cpp
index b74c4f3c19..3becdc37bf 100644
--- a/engines/agos/script_e1.cpp
+++ b/engines/agos/script_e1.cpp
@@ -608,9 +608,9 @@ void AGOSEngine_Elvira1::oe1_pName() {
void AGOSEngine_Elvira1::oe1_pcName() {
// 115:
Item *i = getNextItemPtr();
- Common::String name = (const char *)getStringPtrByID(i->itemName);
- name.toUppercase();
- showMessageFormat("%s", name.c_str());
+
+ // TODO: Change first letter to upper case.
+ showMessageFormat("%s\n", (const byte *)getStringPtrByID(i->itemName)); // Difference
}
void AGOSEngine_Elvira1::oe1_isCalled() {
@@ -815,6 +815,8 @@ void AGOSEngine_Elvira1::oe1_enableInput() {
_lastHitArea3 = 0;
_lastHitArea = 0;
+
+ _clickOnly = 1;
}
void AGOSEngine_Elvira1::oe1_setTime() {
@@ -1208,12 +1210,6 @@ void AGOSEngine::printScroll() {
state.x_skip = 0;
state.y_skip = 0;
- state.surf2_addr = getFrontBuf();
- state.surf2_pitch = _dxSurfacePitch;
-
- state.surf_addr = getBackBuf();
- state.surf_pitch = _dxSurfacePitch;
-
drawImage(&state);
}
diff --git a/engines/agos/script_e2.cpp b/engines/agos/script_e2.cpp
index ebcde7b038..203b95cd5e 100644
--- a/engines/agos/script_e2.cpp
+++ b/engines/agos/script_e2.cpp
@@ -310,7 +310,7 @@ void AGOSEngine_Elvira2::oe2_pObj() {
SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2);
if (subObject != NULL && subObject->objectFlags & kOFText)
- showMessageFormat((const char *)getStringPtrByID(subObject->objectFlagValue[0]));
+ showMessageFormat("%s\n", (const char *)getStringPtrByID(subObject->objectFlagValue[0])); // Difference
}
void AGOSEngine_Elvira2::oe2_loadGame() {
diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp
index 17039d1974..347aca997a 100644
--- a/engines/agos/subroutine.cpp
+++ b/engines/agos/subroutine.cpp
@@ -522,7 +522,7 @@ int AGOSEngine::startSubroutine(Subroutine *sub) {
// WORKAROUND: Bit Flag 171 isn't set when Simon rides the lion to the
// goblin camp in non-English versions. Bit Flag 171 is required to display
// the red trail between locations on the map, during the ride.
- if (getGameType() == GType_SIMON2) {
+ if (getGameType() == GType_SIMON2 && !_oldDrawMethod) {
if (sub->id == 13020)
setBitFlag(171, true);
if (sub->id == 13021)
diff --git a/engines/agos/verb.cpp b/engines/agos/verb.cpp
index 645010f369..4142580184 100644
--- a/engines/agos/verb.cpp
+++ b/engines/agos/verb.cpp
@@ -682,7 +682,17 @@ void AGOSEngine::boxController(uint x, uint y, uint mode) {
_variableArray[500] = best_ha->verb & 0xBFFF;
}
}
- }
+
+ if (_clickOnly != 0 && best_ha->id < 8) {
+ uint id = best_ha->id;
+ if (id >= 4)
+ id -= 4;
+
+ invertBox(findBox(id), 0, 0, 0, 0);
+ _clickOnly = 0;
+ return;
+ }
+ }
if (best_ha->flags & kBFDragBox) {
_lastClickRem = best_ha;
diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp
index 43745e6c7a..5b8bbafd54 100644
--- a/engines/agos/vga.cpp
+++ b/engines/agos/vga.cpp
@@ -210,6 +210,17 @@ bool AGOSEngine::vc_maybe_skip_proc_1(uint16 a, int16 b) {
return item->state == b;
}
+void AGOSEngine::dirtyBackGround() {
+ AnimTable *animTable = _screenAnim1;
+ while (animTable->srcPtr) {
+ if (animTable->id == _vgaCurSpriteId) {
+ animTable->window |= 0x8000;
+ break;
+ }
+ animTable++;
+ }
+}
+
VgaSprite *AGOSEngine::findCurSprite() {
VgaSprite *vsp = _vgaSprites;
while (vsp->id) {
@@ -400,19 +411,22 @@ void AGOSEngine::vc3_loadSprite() {
return;
}
- windowNum = vcReadNextWord(); /* 0 */
+ windowNum = vcReadNextWord();
+ if (getGameType() == GType_SIMON1 && windowNum == 3) {
+ _window3Flag = 1;
+ }
if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) {
- zoneNum = vcReadNextWord(); /* 0 */
- vgaSpriteId = vcReadNextWord(); /* 2 */
+ zoneNum = vcReadNextWord();
+ vgaSpriteId = vcReadNextWord();
} else {
- vgaSpriteId = vcReadNextWord(); /* 2 */
+ vgaSpriteId = vcReadNextWord();
zoneNum = vgaSpriteId / 100;
}
- x = vcReadNextWord(); /* 4 */
- y = vcReadNextWord(); /* 6 */
- palette = vcReadNextWord(); /* 8 */
+ x = vcReadNextWord();
+ y = vcReadNextWord();
+ palette = vcReadNextWord();
old_file_1 = _curVgaFile1;
@@ -607,6 +621,7 @@ void AGOSEngine::drawImage_init(int16 image, uint16 palette, uint16 x, uint16 y,
state.image = vcReadVar(-state.image);
state.palette = palette * 16;
+ state.paletteMod = 0;
state.x = x - _scrollX;
state.y = y - _scrollY;
@@ -718,12 +733,18 @@ void AGOSEngine::vc12_delay() {
void AGOSEngine::vc13_addToSpriteX() {
VgaSprite *vsp = findCurSprite();
vsp->x += (int16)vcReadNextWord();
+
+ vsp->windowNum |= 0x8000;
+ dirtyBackGround();
_vgaSpriteChanged++;
}
void AGOSEngine::vc14_addToSpriteY() {
VgaSprite *vsp = findCurSprite();
vsp->y += (int16)vcReadNextWord();
+
+ vsp->windowNum |= 0x8000;
+ dirtyBackGround();
_vgaSpriteChanged++;
}
@@ -951,6 +972,8 @@ void AGOSEngine::vc24_setSpriteXY() {
vsp->flags = vcReadNextWord();
}
+ vsp->windowNum |= 0x8000;
+ dirtyBackGround();
_vgaSpriteChanged++;
}
@@ -963,6 +986,8 @@ void AGOSEngine::vc25_halt_sprite() {
vsp++;
}
_vcPtr = (byte *)&_vc_get_out_of_code;
+
+ dirtyBackGround();
_vgaSpriteChanged++;
}
@@ -1024,6 +1049,14 @@ void AGOSEngine::vc27_resetSprite() {
}
}
+ if (_lockWord & 0x20) {
+ AnimTable *animTable = _screenAnim1;
+ while (animTable->srcPtr) {
+ animTable->srcPtr = 0;
+ animTable++;
+ }
+ }
+
if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP)
vcWriteVar(254, 0);
@@ -1083,8 +1116,20 @@ void AGOSEngine::vc31_setWindow() {
}
void AGOSEngine::vc32_saveScreen() {
- // TODO
- debug(0, "vc32_saveScreen: stub");
+ uint xoffs = _videoWindows[4 * 4 + 0] * 16;
+ uint yoffs = _videoWindows[4 * 4 + 1];
+ uint width = _videoWindows[4 * 4 + 2] * 16;
+ uint height = _videoWindows[4 * 4 + 3];
+
+ byte *dst = getBackGround() + xoffs + yoffs * _screenWidth;
+ byte *src = _window4BackScn;
+ uint srcWidth = _videoWindows[4 * 4 + 2] * 16;
+
+ for (; height > 0; height--) {
+ memcpy(dst, src, width);
+ dst += _screenWidth;
+ src += srcWidth;
+ }
}
void AGOSEngine::vc33_setMouseOn() {
@@ -1111,24 +1156,65 @@ void AGOSEngine::vc34_setMouseOff() {
_leftButtonDown = 0;
}
-void AGOSEngine::clearWindow(uint num, uint color) {
+void AGOSEngine::clearVideoBackGround(uint num, uint color) {
+ debug(0, "clearVideoBackGround: num %d color %d", num, color);
+
+ const uint16 *vlut = &_videoWindows[num * 4];
+ byte *dst = getBackGround() + vlut[0] * 16 + (vlut[1] * (vlut[2] * 16));
+
+ for (uint h = 0; h < vlut[3]; h++) {
+ memset(dst, color, vlut[2] * 16);
+ dst += _screenWidth;
+ }
+}
+
+void AGOSEngine::clearVideoWindow(uint num, uint color) {
if (getGameType() == GType_ELVIRA1) {
if (num == 2 || num == 6)
return;
} else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
if (num != 4 && num < 10)
return;
+ } else if (getGameType() == GType_SIMON1) {
+ if (num != 4)
+ return;
}
- if (num == 3) {
- memset(getBackBuf(), 0, _screenWidth * _screenHeight);
- } else {
+ debug(0, "clearVideoWindow: num %d color %d", num, color);
+
+ if (getGameType() == GType_SIMON2) {
const uint16 *vlut = &_videoWindows[num * 4];
- byte *dst = getBackBuf() + vlut[0] * 16 + vlut[1] * _dxSurfacePitch;
+ uint xoffs = vlut[0] * 16;
+ uint yoffs = vlut[1];
+ uint dstWidth = _videoWindows[18] * 16;
+ byte *dst = _window4BackScn + xoffs + yoffs * dstWidth;
+
+ setMoveRect(0, 0, vlut[2] * 16, vlut[3]);
for (uint h = 0; h < vlut[3]; h++) {
- memset(dst, 0, vlut[2] * 16);
- dst += _screenWidth;
+ memset(dst, color, vlut[2] * 16);
+ dst += dstWidth;
+ }
+
+ _window4Flag = 1;
+ } else {
+ if (getGameType() == GType_ELVIRA1 && num == 3) {
+ memset(getFrontBuf(), color, _screenWidth * _screenHeight);
+ } else if (num == 4) {
+ const uint16 *vlut = &_videoWindows[num * 4];
+ uint xoffs = (vlut[0] - _videoWindows[16]) * 16;
+ uint yoffs = (vlut[1] - _videoWindows[17]);
+ uint dstWidth = _videoWindows[18] * 16;
+ byte *dst = _window4BackScn + xoffs + yoffs * dstWidth;
+
+ setMoveRect(0, 0, vlut[2] * 16, vlut[3]);
+
+ for (uint h = 0; h < vlut[3]; h++) {
+ memset(dst, color, vlut[2] * 16);
+ dst += dstWidth;
+ }
+
+ _window4Flag = 1;
}
}
}
@@ -1136,7 +1222,23 @@ void AGOSEngine::clearWindow(uint num, uint color) {
void AGOSEngine::vc35_clearWindow() {
uint16 num = vcReadNextWord();
uint16 color = vcReadNextWord();
- clearWindow(num, color);
+
+ // Clear video window
+ clearVideoWindow(num, color);
+
+ // Clear video background
+ if (getGameType() == GType_ELVIRA1) {
+ if (num == 2 || num == 6)
+ return;
+ } else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
+ if (num != 4 && num < 10)
+ return;
+ } else if (getGameType() == GType_SIMON1) {
+ if (num != 4)
+ return;
+ }
+
+ clearVideoBackGround(num, color);
}
void AGOSEngine::vc36_setWindowImage() {
@@ -1147,7 +1249,7 @@ void AGOSEngine::vc36_setWindowImage() {
if (getGameType() == GType_FF || getGameType() == GType_PP) {
_copyPartialMode = 2;
} else if (getGameType() == GType_SIMON1) {
- if (windowNum == 16) {
+ if (windowNum == 16 && !_oldDrawMethod) {
_copyPartialMode = 2;
} else {
setWindowImage(windowNum, vga_res);
diff --git a/engines/agos/vga.h b/engines/agos/vga.h
index 7a4f06f26f..ac84262cbf 100644
--- a/engines/agos/vga.h
+++ b/engines/agos/vga.h
@@ -56,7 +56,7 @@ struct AnimationHeader_Feeble {
// Simon 1/2
struct ImageHeader_Simon {
uint16 id;
- uint16 x_1;
+ uint16 color;
uint16 x_2;
uint16 scriptOffs;
};
@@ -116,6 +116,7 @@ struct VC10_state {
int16 image;
uint16 flags;
byte palette;
+ byte paletteMod;
int16 x, y;
uint16 width, height;
diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp
index a85135a9d2..2c40037b40 100644
--- a/engines/agos/vga_e2.cpp
+++ b/engines/agos/vga_e2.cpp
@@ -68,21 +68,37 @@ void AGOSEngine::vc45_setWindowPalette() {
uint num = vcReadNextWord();
uint color = vcReadNextWord();
- const uint16 *vlut = &_videoWindows[num * 4];
- uint16 *dst = (uint16 *)getBackBuf() + vlut[0] * 8 + vlut[1] * _dxSurfacePitch / 2;
- uint width = vlut[2] * 8;
-
- if (getGameType() == GType_ELVIRA2 && num == 7) {
- dst -= 4;
- width += 4;
- }
+ if (num == 4) {
+ const uint16 *vlut = &_videoWindows[num * 4];
+ uint16 *dst = (uint16 *)_window4BackScn;
+ uint width = vlut[2] * 16 / 2;
+ uint height = vlut[3];
+
+ for (uint h = 0; h < height; h++) {
+ for (uint w = 0; w < width; w++) {
+ dst[w] &= 0xF0F;
+ dst[w] |= color * 16;
+ }
+ dst += width;
+ }
+ } else {
+ const uint16 *vlut = &_videoWindows[num * 4];
+ uint16 *dst = (uint16 *)getFrontBuf() + vlut[0] * 8 + vlut[1] * _dxSurfacePitch / 2;
+ uint width = vlut[2] * 16 / 2;
+ uint height = vlut[3];
+
+ if (getGameType() == GType_ELVIRA2 && num == 7) {
+ dst -= 4;
+ width += 4;
+ }
- for (uint h = 0; h < vlut[3]; h++) {
- for (uint w = 0; w < width; w++) {
- dst[w] &= 0xF0F;
- dst[w] |= color * 16;
+ for (uint h = 0; h < height; h++) {
+ for (uint w = 0; w < width; w++) {
+ dst[w] &= 0xF0F;
+ dst[w] |= color * 16;
+ }
+ dst += _dxSurfacePitch / 2;
}
- dst += _dxSurfacePitch / 2;
}
}
@@ -211,7 +227,7 @@ void AGOSEngine::vc55_moveBox() {
void AGOSEngine::vc56_fullScreen() {
byte *src = _curVgaFile2 + 32;
- byte *dst = getBackBuf();
+ byte *dst = getFrontBuf();
memcpy(dst, src + 768, _screenHeight * _screenWidth);
//fullFade();
diff --git a/engines/agos/vga_s1.cpp b/engines/agos/vga_s1.cpp
index 9ddc3becf3..ad7b8b06f5 100644
--- a/engines/agos/vga_s1.cpp
+++ b/engines/agos/vga_s1.cpp
@@ -103,18 +103,27 @@ void AGOSEngine::vc32_copyVar() {
void AGOSEngine::vc37_addToSpriteY() {
VgaSprite *vsp = findCurSprite();
vsp->y += vcReadVar(vcReadNextWord());
+
+ vsp->windowNum |= 0x8000;
+ dirtyBackGround();
_vgaSpriteChanged++;
}
void AGOSEngine::vc45_setSpriteX() {
VgaSprite *vsp = findCurSprite();
vsp->x = vcReadVar(vcReadNextWord());
+
+ vsp->windowNum |= 0x8000;
+ dirtyBackGround();
_vgaSpriteChanged++;
}
void AGOSEngine::vc46_setSpriteY() {
VgaSprite *vsp = findCurSprite();
vsp->y = vcReadVar(vcReadNextWord());
+
+ vsp->windowNum |= 0x8000;
+ dirtyBackGround();
_vgaSpriteChanged++;
}
@@ -209,6 +218,8 @@ void AGOSEngine::vc61_setMaskImage() {
vsp->y += vcReadNextWord();
vsp->flags = kDFMasked | kDFUseFrontBuf;
+ vsp->windowNum |= 0x8000;
+ dirtyBackGround();
_vgaSpriteChanged++;
}
diff --git a/engines/agos/vga_ww.cpp b/engines/agos/vga_ww.cpp
index f73476c5cb..f9995fc715 100644
--- a/engines/agos/vga_ww.cpp
+++ b/engines/agos/vga_ww.cpp
@@ -110,7 +110,7 @@ void AGOSEngine::vc61() {
if (a == 6) {
src = _curVgaFile2 + 800;
- dstPtr = getBackBuf();
+ dstPtr = getFrontBuf();
memcpy(dstPtr, src, 64000);
tmp = 4 - 1;
} else {
@@ -218,14 +218,21 @@ void AGOSEngine::vc62_fastFadeOut() {
}
}
- // Allow one section of Simon the Sorcerer 1 introduction to be displayed
- // in lower half of screen
- if ((getGameType() == GType_SIMON1) && (_subroutine == 2923 || _subroutine == 2926)) {
- clearSurfaces(200);
- } else if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
clearSurfaces(480);
+ } else if (getGameType() == GType_WW) {
+ memset(getFrontBuf(), 0, _screenWidth * _screenHeight);
+ } else if (!_oldDrawMethod) {
+ // Allow one section of Simon the Sorcerer 1 introduction to be displayed
+ // in lower half of screen
+ if ((getGameType() == GType_SIMON1) && (_subroutine == 2923 || _subroutine == 2926)) {
+ clearSurfaces(200);
+ } else {
+ clearSurfaces(_windowNum == 4 ? 134 : 200);
+ }
} else {
- clearSurfaces(_windowNum == 4 ? 134 : 200);
+ if (_windowNum != 4)
+ memset(getFrontBuf(), 0, _screenWidth * _screenHeight);
}
}
if (getGameType() == GType_SIMON2) {
diff --git a/engines/agos/window.cpp b/engines/agos/window.cpp
index 909ab97c33..81746f8dc3 100644
--- a/engines/agos/window.cpp
+++ b/engines/agos/window.cpp
@@ -123,6 +123,18 @@ void AGOSEngine::colorWindow(WindowBlock *window) {
dst += _screenWidth;
}
} else {
+ if (getGameType() == GType_ELVIRA2 && window->y == 146) {
+ if (window->fill_color == 1) {
+ _displayPalette[33 * 4 + 0] = 48 * 4;
+ _displayPalette[33 * 4 + 1] = 40 * 4;
+ _displayPalette[33 * 4 + 2] = 32 * 4;
+ } else {
+ _displayPalette[33 * 4 + 0] = 56 * 4;
+ _displayPalette[33 * 4 + 1] = 56 * 4;
+ _displayPalette[33 * 4 + 2] = 40 * 4;
+ }
+ }
+
dst = getFrontBuf() + _dxSurfacePitch * window->y + window->x * 8;
h = window->height * 8;
w = window->width * 8;
@@ -170,7 +182,7 @@ void AGOSEngine::restoreBlock(uint h, uint w, uint y, uint x) {
uint i;
dst = getFrontBuf();
- src = _backGroundBuf;
+ src = getBackGround();
dst += y * _dxSurfacePitch;
src += y * _dxSurfacePitch;