From b6672f37a97f30298e51b1d4574eeb75a31da1a6 Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Sun, 13 May 2007 08:46:48 +0000 Subject: Fix bugs #941074 and #828860, by switching to graphics renderer code used by earlier (non-Windows) versions of Simon the Sorcerer 1/2. svn-id: r26825 --- engines/agos/agos.cpp | 37 +++--- engines/agos/agos.h | 17 +-- engines/agos/charset.cpp | 6 + engines/agos/draw.cpp | 295 ++++++++++++++++++++++---------------------- engines/agos/event.cpp | 70 ++++++----- engines/agos/gfx.cpp | 111 ++++++----------- engines/agos/icons.cpp | 4 +- engines/agos/input.cpp | 4 - engines/agos/saveload.cpp | 5 - engines/agos/script.cpp | 19 +++ engines/agos/subroutine.cpp | 10 -- engines/agos/vga.cpp | 36 +++--- engines/agos/vga_e2.cpp | 1 + engines/agos/vga_ww.cpp | 46 ++----- 14 files changed, 298 insertions(+), 363 deletions(-) (limited to 'engines/agos') diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index b3e615bfec..68d8f08c51 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -192,6 +192,7 @@ AGOSEngine::AGOSEngine(OSystem *syst) _beardLoaded = 0; _litBoxFlag = 0; _mortalFlag = 0; + _displayScreen = false; _updateScreen = false; _syncFlag2 = 0; _inCallBack = 0; @@ -200,7 +201,6 @@ AGOSEngine::AGOSEngine(OSystem *syst) _fastMode = 0; _useBackGround = 0; - _oldDrawMethod = 0; _backFlag = 0; _debugMode = 0; @@ -208,7 +208,6 @@ AGOSEngine::AGOSEngine(OSystem *syst) _continousMainScript = false; _startVgaScript = false; _continousVgaScript = false; - _drawImagesDebug = false; _dumpImages = false; _copyProtection = false; @@ -330,6 +329,7 @@ AGOSEngine::AGOSEngine(OSystem *syst) _showPreposition = 0; _showMessageFlag = 0; + _copyScnFlag = 0; _vgaSpriteChanged = 0; _block = 0; @@ -526,12 +526,6 @@ 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; @@ -585,22 +579,19 @@ int AGOSEngine::init() { _frontBuf = (byte *)calloc(_screenWidth * _screenHeight, 1); if (getGameType() == GType_FF || getGameType() == GType_PP) { + _backBuf = (byte *)calloc(_screenWidth * _screenHeight, 1); _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); - } + 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(); @@ -948,6 +939,10 @@ int AGOSEngine::go() { vc34_setMouseOff(); + if (getGameType() != GType_PP && getGameType() != GType_FF) { + addVgaEvent(_frameRate, NULL, 0, 0, 2); + } + if (getGameType() == GType_ELVIRA1 && getPlatform() == Common::kPlatformAtariST && (getFeatures() & GF_DEMO)) { int i; diff --git a/engines/agos/agos.h b/engines/agos/agos.h index af28cd2729..964c8c758b 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -105,6 +105,7 @@ struct VgaTimerEntry { const byte *script_pointer; uint16 sprite_id; uint16 cur_vga_file; + uint8 type; VgaTimerEntry() { memset(this, 0, sizeof(*this)); } }; @@ -265,6 +266,7 @@ protected: bool _beardLoaded; bool _litBoxFlag; bool _mortalFlag; + bool _displayScreen; bool _updateScreen; bool _syncFlag2; bool _inCallBack; @@ -273,7 +275,6 @@ protected: bool _fastMode; bool _useBackGround; - bool _oldDrawMethod; bool _backFlag; uint16 _debugMode; @@ -284,7 +285,6 @@ protected: bool _continousMainScript; bool _startVgaScript; bool _continousVgaScript; - bool _drawImagesDebug; bool _dumpImages; bool _speech; bool _subtitles; @@ -408,7 +408,7 @@ protected: bool _showPreposition; bool _showMessageFlag; - uint _vgaSpriteChanged; + uint _copyScnFlag, _vgaSpriteChanged; byte *_block, *_blockEnd; byte *_vgaMemPtr, *_vgaMemEnd, *_vgaMemBase; @@ -1086,7 +1086,7 @@ protected: bool isVgaQueueEmpty(); void haltAnimation(); void restartAnimation(); - void addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum); + void addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum, uint8 type = 0); void deleteVgaEvent(VgaTimerEntry * vte); void processVgaEvents(); void animateEvent(const byte *code_ptr, uint16 curZoneNum, uint16 cur_sprite); @@ -1127,9 +1127,7 @@ protected: void timer_callback(); void timer_proc1(); - void animateSprites(); - void animateSpritesDebug(); - void animateSpritesByY(); + virtual void animateSprites(); void dirtyClips(); void dirtyBackGround(); @@ -1137,7 +1135,7 @@ protected: void saveBackGround(VgaSprite *vsp); void clearSurfaces(uint num_lines); - void updateScreen(); + void displayScreen(); void dumpVideoScript(const byte *src, bool one_opcode_only); void dumpVgaFile(const byte *vga); @@ -1559,6 +1557,9 @@ protected: void drawMousePart(int image, byte x, byte y); virtual void drawMousePointer(); + virtual void animateSprites(); + void animateSpritesByY(); + virtual void addArrows(WindowBlock *window); virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); diff --git a/engines/agos/charset.cpp b/engines/agos/charset.cpp index 2dbf8277af..2d37d33aa5 100644 --- a/engines/agos/charset.cpp +++ b/engines/agos/charset.cpp @@ -602,6 +602,12 @@ void AGOSEngine::openTextWindow() { void AGOSEngine::windowPutChar(WindowBlock *window, byte c, byte b) { byte width = 6; + if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) { + if (!(window->flags & 1)) { + haltAnimation(); + } + } + if (c == 12) { clearWindow(window); } else if (c == 13 || c == 10) { diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp index c2183bffc2..afc879a839 100644 --- a/engines/agos/draw.cpp +++ b/engines/agos/draw.cpp @@ -31,6 +31,9 @@ namespace AGOS { byte *AGOSEngine::getFrontBuf() { + if (getGameType() != GType_PP && getGameType() != GType_FF) + _updateScreen = true; + _dxSurfacePitch = _screenWidth; return _frontBuf; } @@ -50,35 +53,138 @@ byte *AGOSEngine::getScaleBuf() { return _scaleBuf; } -void AGOSEngine::animateSprites() { +void AGOSEngine_Feeble::animateSpritesByY() { + VgaSprite *vsp; + VgaPointersEntry *vpe; + int16 spriteTable[180][2]; + + byte *src; + int height, slot, y; + uint i, numSprites = 0; + + vsp = _vgaSprites; + while (vsp->id) { + if (vsp->flags & kDFScaled) { + y = vsp->y; + } else if (vsp->flags & kDFMasked) { + vpe = &_vgaBufferPointers[vsp->zoneNum]; + src = vpe->vgaFile2 + vsp->image * 8; + height = READ_LE_UINT16(src + 4) & 0x7FFF; + y = vsp->y + height; + } else { + y = vsp->priority; + } + + spriteTable[numSprites][0] = y; + spriteTable[numSprites][1] = numSprites; + numSprites++; + vsp++; + } + + while (1) { + y = spriteTable[0][0]; + slot = spriteTable[0][1]; + + for (i = 0; i < numSprites; i++) { + if (y >= spriteTable[i][0]) { + y = spriteTable[i][0]; + slot = spriteTable[i][1]; + } + } + + if (y == 9999) + break; + + for (i = 0; i < numSprites; i++) { + if (slot == spriteTable[i][1]) { + spriteTable[i][0] = 9999; + break; + } + } + + vsp = &_vgaSprites[slot]; + + vsp->windowNum &= 0x7FFF; + + vpe = &_vgaBufferPointers[vsp->zoneNum]; + _curVgaFile1 = vpe->vgaFile1; + _curVgaFile2 = vpe->vgaFile2; + _curSfxFile = vpe->sfxFile; + _windowNum = vsp->windowNum; + _vgaCurSpriteId = vsp->id; + _vgaCurSpritePriority = vsp->priority; + + drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags); + } + + _displayScreen = true; +} + +void AGOSEngine_Feeble::animateSprites() { VgaSprite *vsp; VgaPointersEntry *vpe; if (_paletteFlag == 2) _paletteFlag = 1; - if (getGameType() == GType_FF && _scrollCount) { + if (_scrollCount) { scrollEvent(); } - if (getGameType() == GType_SIMON2 && _scrollFlag) { - scrollScreen(); - } - if (getGameType() == GType_FF && getBitFlag(84)) { + if (getBitFlag(84)) { animateSpritesByY(); return; } - if (_oldDrawMethod) { - if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - dirtyClips(); - } + vsp = _vgaSprites; + while (vsp->id) { + vsp->windowNum &= 0x7FFF; + + vpe = &_vgaBufferPointers[vsp->zoneNum]; + _curVgaFile1 = vpe->vgaFile1; + _curVgaFile2 = vpe->vgaFile2; + _curSfxFile = vpe->sfxFile; + _windowNum = vsp->windowNum; + _vgaCurSpriteId = vsp->id; + _vgaCurSpritePriority = vsp->priority; + + drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags); + vsp++; + } - restoreBackGround(); + _displayScreen = true; +} + +void AGOSEngine::animateSprites() { + VgaSprite *vsp; + VgaPointersEntry *vpe; + + if (_copyScnFlag) { + _copyScnFlag--; + _vgaSpriteChanged++; + } + + if (!_scrollFlag && !_vgaSpriteChanged) { + return; + } + + _vgaSpriteChanged = 0; + + if (_paletteFlag == 2) + _paletteFlag = 1; + + if (getGameType() == GType_SIMON2 && _scrollFlag) { + scrollScreen(); } + if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { + dirtyClips(); + } + + restoreBackGround(); + vsp = _vgaSprites; - while (vsp->id != 0) { + while (vsp->id) { vsp->windowNum &= 0x7FFF; vpe = &_vgaBufferPointers[vsp->zoneNum]; @@ -89,24 +195,19 @@ void AGOSEngine::animateSprites() { _vgaCurSpriteId = vsp->id; _vgaCurSpritePriority = vsp->priority; - if (_oldDrawMethod) { - saveBackGround(vsp); - } + 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; + _displayScreen = true; } void AGOSEngine::dirtyClips() { @@ -202,103 +303,6 @@ void AGOSEngine::saveBackGround(VgaSprite *vsp) { animTable->id = vsp->id; } -void AGOSEngine::animateSpritesDebug() { - VgaSprite *vsp; - VgaPointersEntry *vpe; - - if (_paletteFlag == 2) - _paletteFlag = 1; - - vsp = _vgaSprites; - while (vsp->id != 0) { - vsp->windowNum &= 0x7FFF; - - vpe = &_vgaBufferPointers[vsp->zoneNum]; - _curVgaFile1 = vpe->vgaFile1; - _curVgaFile2 = vpe->vgaFile2; - _curSfxFile = vpe->sfxFile; - _windowNum = vsp->windowNum; - _vgaCurSpriteId = vsp->id; - - if (vsp->image) - printf("id:%5d image:%3d base-color:%3d x:%3d y:%3d flags:%x\n", - vsp->id, vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags); - - drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags); - - vsp++; - } - - _updateScreen = true; -} - -void AGOSEngine::animateSpritesByY() { - VgaSprite *vsp; - VgaPointersEntry *vpe; - int16 spriteTable[180][2]; - - byte *src; - int height, slot, y; - uint i, numSprites = 0; - - vsp = _vgaSprites; - while (vsp->id != 0) { - if (vsp->flags & kDFScaled) { - y = vsp->y; - } else if (vsp->flags & kDFMasked) { - vpe = &_vgaBufferPointers[vsp->zoneNum]; - src = vpe->vgaFile2 + vsp->image * 8; - height = READ_LE_UINT16(src + 4) & 0x7FFF; - y = vsp->y + height; - } else { - y = vsp->priority; - } - - spriteTable[numSprites][0] = y; - spriteTable[numSprites][1] = numSprites; - numSprites++; - vsp++; - } - - while (1) { - y = spriteTable[0][0]; - slot = spriteTable[0][1]; - - for (i = 0; i < numSprites; i++) { - if (y >= spriteTable[i][0]) { - y = spriteTable[i][0]; - slot = spriteTable[i][1]; - } - } - - if (y == 9999) - break; - - for (i = 0; i < numSprites; i++) { - if (slot == spriteTable[i][1]) { - spriteTable[i][0] = 9999; - break; - } - } - - vsp = &_vgaSprites[slot]; - - vsp->windowNum &= 0x7FFF; - - vpe = &_vgaBufferPointers[vsp->zoneNum]; - _curVgaFile1 = vpe->vgaFile1; - _curVgaFile2 = vpe->vgaFile2; - _curSfxFile = vpe->sfxFile; - _windowNum = vsp->windowNum; - _vgaCurSpriteId = vsp->id; - _vgaCurSpritePriority = vsp->priority; - - drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags); - } - - _updateScreen = true; -} - void AGOSEngine::displayBoxStars() { HitArea *ha, *dha; uint count; @@ -306,21 +310,19 @@ void AGOSEngine::displayBoxStars() { byte *dst; uint b, color; - _lockWord |= 0x8000; + o_haltAnimation(); if (getGameType() == GType_SIMON2) color = 236; else color = 225; - uint limit = (getGameType() == GType_SIMON2) ? 200 : 134; + uint curHeight = (getGameType() == GType_SIMON2) ? _boxStarHeight : 134; for (int i = 0; i < 5; i++) { ha = _hitAreas; count = ARRAYSIZE(_hitAreas); - animateSprites(); - do { if (ha->id != 0 && ha->flags & kBFBoxInUse && !(ha->flags & kBFBoxDead)) { @@ -338,7 +340,7 @@ void AGOSEngine::displayBoxStars() { continue; } - if (ha->y >= limit || ((getGameType() == GType_SIMON2) && ha->y >= _boxStarHeight)) + if (ha->y >= curHeight) continue; y_ = (ha->height / 2) - 4 + ha->y; @@ -348,7 +350,7 @@ void AGOSEngine::displayBoxStars() { if (x_ >= 311) continue; - dst = getBackBuf(); + dst = getFrontBuf(); dst += (((_dxSurfacePitch / 4) * y_) * 4) + x_; @@ -387,14 +389,16 @@ void AGOSEngine::displayBoxStars() { } } while (ha++, --count); - updateScreen(); delay(100); - animateSprites(); - updateScreen(); + + setMoveRect(0, 0, 320, curHeight); + _window4Flag = 2; + + displayScreen(); delay(100); } - _lockWord &= ~0x8000; + o_restartAnimation(); } void AGOSEngine::scrollScreen() { @@ -402,10 +406,10 @@ void AGOSEngine::scrollScreen() { const byte *src; uint x, y; - if (!_oldDrawMethod) { - dst = getFrontBuf(); - } else { + if (getGameType() == GType_SIMON2) { dst = getBackGround(); + } else { + dst = getFrontBuf(); } if (_scrollXMax == 0) { @@ -455,11 +459,11 @@ void AGOSEngine::scrollScreen() { _scrollX += _scrollFlag; vcWriteVar(251, _scrollX); - if (!_oldDrawMethod) { + if (getGameType() == GType_SIMON2) { + memcpy(_window4BackScn, _backGroundBuf, _scrollHeight * _screenWidth); + } else { memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight); memcpy(_backGroundBuf, _backBuf, _scrollHeight * _screenWidth); - } else { - memcpy(_window4BackScn, _backGroundBuf, _scrollHeight * _screenWidth); } setMoveRect(0, 0, 320, _scrollHeight); @@ -527,7 +531,7 @@ void AGOSEngine::setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height) { _moveYMax = height; } -void AGOSEngine::updateScreen() { +void AGOSEngine::displayScreen() { if (_fastFadeInFlag == 0 && _paletteFlag == 1) { _paletteFlag = 0; if (memcmp(_displayPalette, _currentPalette, 1024)) { @@ -536,7 +540,13 @@ void AGOSEngine::updateScreen() { } } - if (_oldDrawMethod) { + if (getGameType() == GType_PP || getGameType() == GType_FF) { + _system->copyRectToScreen(getBackBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight); + _system->updateScreen(); + + if (getGameId() != GID_DIMP) + memcpy(getBackBuf(), getFrontBuf(), _screenWidth * _screenHeight); + } else { if (_window4Flag == 2) { _window4Flag = 0; @@ -571,7 +581,7 @@ void AGOSEngine::updateScreen() { _moveYMax = 0; } - if (_window6Flag == 2) { + if (_window6Flag == 2) { _window6Flag = 0; byte *src = _window6BackScn; @@ -581,17 +591,10 @@ void AGOSEngine::updateScreen() { 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) { @@ -599,10 +602,6 @@ void AGOSEngine::updateScreen() { } if (_fastFadeInFlag) { - if (getGameType() == GType_SIMON1 && _usePaletteDelay) { - delay(100); - _usePaletteDelay = false; - } fastFadeIn(); } } diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp index 43468d35f8..457e07ce35 100644 --- a/engines/agos/event.cpp +++ b/engines/agos/event.cpp @@ -170,9 +170,9 @@ void AGOSEngine::haltAnimation() { _lockWord |= 0x10; - if (_updateScreen != false) { - updateScreen(); - _updateScreen = false; + if (_displayScreen) { + displayScreen(); + _displayScreen = false; } } @@ -181,16 +181,16 @@ void AGOSEngine::restartAnimation() { return; _window4Flag = 2; - + setMoveRect(0, 0, 224, 127); - updateScreen(); + displayScreen(); _lockWord &= ~0x10; // Check picture queue } -void AGOSEngine::addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum) { +void AGOSEngine::addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum, uint8 type) { VgaTimerEntry *vte; _lockWord |= 1; @@ -202,6 +202,7 @@ void AGOSEngine::addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite vte->script_pointer = code_ptr; vte->sprite_id = cur_sprite; vte->cur_vga_file = curZoneNum; + vte->type = type; _lockWord &= ~1; } @@ -232,16 +233,29 @@ void AGOSEngine::processVgaEvents() { uint16 curZoneNum = vte->cur_vga_file; uint16 cur_sprite = vte->sprite_id; const byte *script_ptr = vte->script_pointer; + uint8 type = vte->type; + + if (type == 2) { + vte->delay = (getGameType() == GType_SIMON2) ? 5 : _frameRate; - _nextVgaTimerToProcess = vte + 1; - deleteVgaEvent(vte); + animateSprites(); + + vte++; + } else if (type == 1) { + _nextVgaTimerToProcess = vte + 1; + deleteVgaEvent(vte); - if (getGameType() == GType_SIMON2 && script_ptr == NULL) { scrollEvent(); - } else { + + vte = _nextVgaTimerToProcess; + } else if (type == 0) { + _nextVgaTimerToProcess = vte + 1; + deleteVgaEvent(vte); + animateEvent(script_ptr, curZoneNum, cur_sprite); + + vte = _nextVgaTimerToProcess; } - vte = _nextVgaTimerToProcess; } else { vte++; } @@ -297,7 +311,7 @@ void AGOSEngine::scrollEvent() { } } - addVgaEvent(6, NULL, 0, 0); /* scroll event */ + addVgaEvent(6, NULL, 0, 0, 1); /* scroll event */ } } @@ -444,6 +458,8 @@ void AGOSEngine::timer_proc1() { _lockWord |= 2; + handleMouseMoved(); + if (!(_lockWord & 0x10)) { if (getGameType() == GType_PP) { _syncFlag2 ^= 1; @@ -481,29 +497,26 @@ void AGOSEngine::timer_proc1() { return; } } - } + } - if (getGameType() == GType_FF) + if (getGameType() == GType_FF) { _moviePlay->nextFrame(); - - animateSprites(); - if (_drawImagesDebug) - animateSpritesDebug(); - - if (_copyPartialMode == 1) { - fillBackFromFront(80, 46, 208 - 80, 94 - 46); + animateSprites(); } if (_copyPartialMode == 2) { - if (getGameType() == GType_FF || getGameType() == GType_PP) { - fillFrontFromBack(0, 0, _screenWidth, _screenHeight); - } else { - fillFrontFromBack(176, 61, _screenWidth - 176, 134 - 61); - } + fillFrontFromBack(0, 0, _screenWidth, _screenHeight); _copyPartialMode = 0; } if (_updateScreen) { + _system->copyRectToScreen(getFrontBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight); + _system->updateScreen(); + + _updateScreen = false; + } + + if (_displayScreen) { if (getGameType() == GType_FF) { if (!getBitFlag(78)) { oracleLogo(); @@ -512,9 +525,8 @@ void AGOSEngine::timer_proc1() { swapCharacterLogo(); } } - handleMouseMoved(); - updateScreen(); - _updateScreen = false; + displayScreen(); + _displayScreen = false; } _lockWord &= ~2; diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp index b1bf3d12e4..3aa18dd5ec 100644 --- a/engines/agos/gfx.cpp +++ b/engines/agos/gfx.cpp @@ -215,13 +215,11 @@ bool AGOSEngine::drawImage_clip(VC10_state *state) { } while (--cur); } - assert(state->draw_width != 0 && state->draw_height != 0); - if (getGameType() != GType_FF && getGameType() != GType_PP) { state->draw_width *= 4; } - return 1; + return (state->draw_width != 0 && state->draw_height != 0); } void AGOSEngine_Feeble::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) { @@ -357,7 +355,7 @@ void AGOSEngine_Feeble::drawImage(VC10_state *state) { scaleClip(_scaleHeight, _scaleWidth, _scaleY, _scaleX, _scaleY + _scrollY); } } else { - if (drawImage_clip(state) == 0) + if (!drawImage_clip(state)) return; state->surf_addr += state->x + state->y * state->surf_pitch; @@ -423,7 +421,7 @@ void AGOSEngine_Feeble::drawImage(VC10_state *state) { } } } else { - if (drawImage_clip(state) == 0) + if (!drawImage_clip(state)) return; state->surf_addr += state->x + state->y * state->surf_pitch; @@ -452,6 +450,10 @@ void AGOSEngine_Feeble::drawImage(VC10_state *state) { } void AGOSEngine_Simon1::drawMaskedImage(VC10_state *state) { + if (getGameType() == GType_SIMON1 && (_windowNum == 3 || _windowNum == 4 || _windowNum >= 10)) { + state->surf2_addr += _videoWindows[17] * 320; + } + if (getFeatures() & GF_32COLOR) { const byte *mask = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8); byte *src = state->surf2_addr; @@ -622,24 +624,14 @@ void AGOSEngine_Simon1::draw32ColorImage(VC10_state *state) { void AGOSEngine_Simon1::drawImage(VC10_state *state) { const uint16 *vlut = &_videoWindows[_windowNum * 4]; - if (drawImage_clip(state) == 0) + if (!drawImage_clip(state)) return; if (getFeatures() & GF_32COLOR) state->palette = 0xC0; uint16 xoffs = 0, yoffs = 0; - 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) { + if (getGameType() == GType_SIMON2) { state->surf2_addr = getBackGround(); state->surf2_pitch = _screenWidth; @@ -724,12 +716,6 @@ void AGOSEngine::drawBackGroundImage(VC10_state *state) { } 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 (state->flags & kDFCompressed) { uint w, h; byte *src, *dst, *dstPtr; @@ -793,7 +779,7 @@ void AGOSEngine::drawVertImage(VC10_state *state) { void AGOSEngine::drawImage(VC10_state *state) { const uint16 *vlut = &_videoWindows[_windowNum * 4]; - if (drawImage_clip(state) == 0) + if (!drawImage_clip(state)) return; uint16 xoffs = 0, yoffs = 0; @@ -850,7 +836,6 @@ void AGOSEngine::drawImage(VC10_state *state) { xoffs = (vlut[0] * 2 + state->x) * 8; yoffs = vlut[1] + state->y; - } else { state->surf_addr = _window4BackScn; state->surf_pitch = _videoWindows[18] * 16; @@ -900,10 +885,10 @@ void AGOSEngine::horizontalScroll(VC10_state *state) { vcWriteVar(251, _scrollX); - if (!_oldDrawMethod) { - dst = getBackBuf(); - } else { + if (getGameType() == GType_SIMON2) { dst = _window4BackScn; + } else { + dst = getBackBuf(); } if (getGameType() == GType_FF) @@ -1153,7 +1138,7 @@ void AGOSEngine::setImage(uint16 vga_res_id, bool vgaScript) { } assert(READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == vga_res_id); - if (!vgaScript && _oldDrawMethod) + if (!vgaScript) clearVideoWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_Simon *) b)->color)); } else { b = bb + READ_BE_UINT16(bb + 10); @@ -1220,35 +1205,34 @@ void AGOSEngine::setWindowImageEx(uint16 mode, uint16 vga_res) { if (_lockWord & 0x10) error("setWindowImageEx: _lockWord & 0x10"); - setWindowImage(mode, vga_res); + if (getGameType() != GType_PP && getGameType() != GType_FF) { + if (getGameType() == GType_WW && (mode == 6 || mode == 8 || mode == 9)) { + setWindowImage(mode, vga_res); + } else { + while (_copyScnFlag) + delay(1); + + setWindowImage(mode, vga_res); + } + } else { + setWindowImage(mode, vga_res); + } } void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) { - uint num_lines; uint16 updateWindow; _windowNum = updateWindow = mode; _lockWord |= 0x20; + VgaTimerEntry *vte = _vgaTimerList; + vte->delay = 2; + if (getGameType() == GType_FF || getGameType() == GType_PP) { vc27_resetSprite(); } - if (!vga_res_id) { - if (getGameType() == GType_SIMON1) { - _unkPalFlag = true; - } else if (getGameType() == GType_SIMON2 && !_oldDrawMethod) { - _useBackGround = true; - _restoreWindow6 = true; - } - } - - if (getGameType() == GType_SIMON1) { - if (vga_res_id == 16300) { - clearBackFromTop(134); - _usePaletteDelay = true; - } - } else if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) { + if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) { _scrollX = 0; _scrollY = 0; _scrollXMax = 0; @@ -1270,28 +1254,10 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) { fillFrontFromBack(0, 0, _screenWidth, _screenHeight); fillBackGroundFromBack(_screenHeight); _syncFlag2 = 1; - } else if (getGameType() == GType_SIMON2 && !_oldDrawMethod) { - if (!_useBackGround) { - num_lines = _windowNum == 4 ? 134 : 200; - _boxStarHeight = num_lines; - fillFrontFromBack(0, 0, _screenWidth, num_lines); - fillBackGroundFromBack(num_lines); - _syncFlag2 = 1; - } - _useBackGround = false; - } 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) - num_lines = 200; - else - num_lines = _windowNum == 4 ? 134 : 200; - - fillFrontFromBack(0, 0, _screenWidth, num_lines); - fillBackGroundFromBack(num_lines); - _syncFlag2 = 1; - _timer5 = 0; } else { + _copyScnFlag = 2; + _vgaSpriteChanged++; + if (_window3Flag == 1) { clearVideoBackGround(3, 0); // (window, color) } @@ -1358,6 +1324,8 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) { } } + _boxStarHeight = height; + for (; height > 0; height--) { memcpy(dst, src, width); dst += _screenWidth; @@ -1379,15 +1347,6 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) { } _lockWord &= ~0x20; - - if (getGameType() == GType_SIMON1) { - if (_unkPalFlag) { - _unkPalFlag = false; - while (_fastFadeInFlag != 0) { - delay(10); - } - } - } } } // End of namespace AGOS diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp index ba79f08508..d01d42a367 100644 --- a/engines/agos/icons.cpp +++ b/engines/agos/icons.cpp @@ -787,7 +787,9 @@ void AGOSEngine::removeArrows(WindowBlock *window, uint num) { if (getFeatures() & GF_32COLOR) { // TODO: Manually removes arrows } else { - stopAnimate(128); + stopAnimate(129); + uint8 palette = (getPlatform() == Common::kPlatformAmiga) ? 15: 14; + animate(0, 1, 129, 0, 0, palette); } } else if (getGameType() == GType_WW) { setBitFlag(22, false); diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp index d0fab120f5..d04d4a783e 100644 --- a/engines/agos/input.cpp +++ b/engines/agos/input.cpp @@ -576,10 +576,6 @@ bool AGOSEngine::processSpecialKeys() { if (_debugMode) _continousVgaScript ^= 1; break; - case 'i': - if (_debugMode) - _drawImagesDebug ^= 1; - break; case 'd': if (_debugMode) _dumpImages ^=1; diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp index 40960c0cbe..5ec62ac01a 100644 --- a/engines/agos/saveload.cpp +++ b/engines/agos/saveload.cpp @@ -224,8 +224,6 @@ void AGOSEngine::userGame(bool load) { save_time = time(NULL); - _copyPartialMode = 1; - number_of_savegames = countSaveGames(); if (!load) number_of_savegames++; @@ -375,9 +373,6 @@ get_out:; disableFileBoxes(); _gameStoppedClock = time(NULL) - save_time + _gameStoppedClock; - _copyPartialMode = 0; - - restoreBlock(94, 208, 46, 80); i = _timer4; do { diff --git a/engines/agos/script.cpp b/engines/agos/script.cpp index ecc43038c1..9961a3ff0b 100644 --- a/engines/agos/script.cpp +++ b/engines/agos/script.cpp @@ -447,6 +447,18 @@ void AGOSEngine::o_comment() { void AGOSEngine::o_haltAnimation() { // 88: stop animation _lockWord |= 0x10; + + if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { + VgaTimerEntry *vte = _vgaTimerList; + while (vte->delay) { + if (vte->type == 0) + vte->delay += 10; + vte++; + } + + _scrollCount = 0; + _scrollFlag = 0; + } } void AGOSEngine::o_restartAnimation() { @@ -511,6 +523,13 @@ void AGOSEngine::o_loadZone() { } loadZone(vga_res); + + if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || + getGameType() == GType_WW) { + _copyScnFlag = 0; + _vgaSpriteChanged = 0; + } + _lockWord &= ~0x80; } diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp index 8bff4e43f8..8ab0c49110 100644 --- a/engines/agos/subroutine.cpp +++ b/engines/agos/subroutine.cpp @@ -519,16 +519,6 @@ int AGOSEngine::startSubroutine(Subroutine *sub) { int result = -1; SubroutineLine *sl = (SubroutineLine *)((byte *)sub + sub->first); - // 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 && !_oldDrawMethod) { - if (sub->id == 13020) - setBitFlag(171, true); - if (sub->id == 13021) - setBitFlag(171, false); - } - const byte *old_code_ptr = _codePtr; Subroutine *old_currentTable = _currentTable; SubroutineLine *old_currentLine = _currentLine; diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index 5b8bbafd54..c96ad6afdd 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -708,7 +708,6 @@ void AGOSEngine::drawImage_init(int16 image, uint16 palette, uint16 x, uint16 y, } void AGOSEngine::vc12_delay() { - VgaSprite *vsp = findCurSprite(); uint16 num; if (getGameType() == GType_FF || getGameType() == GType_PP) { @@ -719,12 +718,7 @@ void AGOSEngine::vc12_delay() { num = vcReadVarOrWord() * _frameRate; } - // Work around to allow inventory arrows to be shown - // in non-Windows versions of Simon the Sorcerer 1 - if ((getGameType() == GType_SIMON1) && vsp->id == 128) - num = 0; - else - num += _vgaBaseDelay; + num += _vgaBaseDelay; addVgaEvent(num, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum); _vcPtr = (byte *)&_vc_get_out_of_code; @@ -1012,8 +1006,8 @@ void AGOSEngine::vc27_resetSprite() { vsp = _vgaSprites; while (vsp->id) { - if ((getGameType() == GType_SIMON1 && vsp->id == 128) || - (getGameType() == GType_ELVIRA2 && vsp->id == 100)) { + // For animated heart in Elvira 2 + if (getGameType() == GType_ELVIRA2 && vsp->id == 100) { memcpy(&bak, vsp, sizeof(VgaSprite)); } vsp->id = 0; @@ -1037,8 +1031,11 @@ void AGOSEngine::vc27_resetSprite() { vte = _vgaTimerList; while (vte->delay) { - if ((getGameType() == GType_SIMON1 && vte->sprite_id == 128) || - (getGameType() == GType_ELVIRA2 && vte->sprite_id == 100)) { + // Skip the animateSprites event in earlier games + if (vte->type == 2) { + vte++; + // For animated heart in Elvira 2 + } else if (getGameType() == GType_ELVIRA2 && vte->sprite_id == 100) { vte++; } else { vte2 = vte; @@ -1225,6 +1222,7 @@ void AGOSEngine::vc35_clearWindow() { // Clear video window clearVideoWindow(num, color); + _vgaSpriteChanged++; // Clear video background if (getGameType() == GType_ELVIRA1) { @@ -1242,18 +1240,12 @@ void AGOSEngine::vc35_clearWindow() { } void AGOSEngine::vc36_setWindowImage() { - _updateScreen = false; + _displayScreen = false; uint16 vga_res = vcReadNextWord(); uint16 windowNum = vcReadNextWord(); if (getGameType() == GType_FF || getGameType() == GType_PP) { _copyPartialMode = 2; - } else if (getGameType() == GType_SIMON1) { - if (windowNum == 16 && !_oldDrawMethod) { - _copyPartialMode = 2; - } else { - setWindowImage(windowNum, vga_res); - } } else { setWindowImage(windowNum, vga_res); } @@ -1299,7 +1291,7 @@ void AGOSEngine::vc40() { uint16 var = vcReadNextWord(); int16 value = vcReadVar(var) + vcReadNextWord(); - if ((getGameType() == GType_SIMON2) && var == 15 && !getBitFlag(80)) { + if (getGameType() == GType_SIMON2 && var == 15 && !getBitFlag(80)) { int16 tmp; if (_scrollCount != 0) { @@ -1316,7 +1308,7 @@ void AGOSEngine::vc40() { tmp = _scrollXMax - _scrollX; if (tmp < 20) _scrollCount = tmp; - addVgaEvent(6, NULL, 0, 0); /* scroll event */ + addVgaEvent(6, NULL, 0, 0, 1); /* scroll event */ } } no_scroll:; @@ -1328,7 +1320,7 @@ void AGOSEngine::vc41() { uint16 var = vcReadNextWord(); int16 value = vcReadVar(var) - vcReadNextWord(); - if ((getGameType() == GType_SIMON2) && var == 15 && !getBitFlag(80)) { + if (getGameType() == GType_SIMON2 && var == 15 && !getBitFlag(80)) { if (_scrollCount != 0) { if (_scrollCount < 0) goto no_scroll; @@ -1342,7 +1334,7 @@ void AGOSEngine::vc41() { _scrollCount = -20; if (_scrollX < 20) _scrollCount = -_scrollX; - addVgaEvent(6, NULL, 0, 0); /* scroll event */ + addVgaEvent(6, NULL, 0, 0, 1); /* scroll event */ } } no_scroll:; diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp index 2c40037b40..05a7f9fc76 100644 --- a/engines/agos/vga_e2.cpp +++ b/engines/agos/vga_e2.cpp @@ -230,6 +230,7 @@ void AGOSEngine::vc56_fullScreen() { byte *dst = getFrontBuf(); memcpy(dst, src + 768, _screenHeight * _screenWidth); + //fullFade(); uint8 palette[1024]; diff --git a/engines/agos/vga_ww.cpp b/engines/agos/vga_ww.cpp index f9995fc715..087623e1cc 100644 --- a/engines/agos/vga_ww.cpp +++ b/engines/agos/vga_ww.cpp @@ -72,8 +72,11 @@ void AGOSEngine::vcStopAnimation(uint file, uint sprite) { vc25_halt_sprite(); vte = _vgaTimerList; - while (vte->delay != 0) { - if (vte->sprite_id == _vgaCurSpriteId && ((getGameType() == GType_SIMON1) || vte->cur_vga_file == _vgaCurZoneNum)) { + while (vte->delay) { + // Skip the animateSprites event in earlier games + if (vte->type == 2) { + vte++; + } else if (vte->sprite_id == _vgaCurSpriteId && (getGameType() == GType_SIMON1 || vte->cur_vga_file == _vgaCurZoneNum)) { deleteVgaEvent(vte); break; } @@ -190,49 +193,14 @@ void AGOSEngine::vc62_fastFadeOut() { delay(5); } - if (getGameType() == GType_SIMON1) { - VgaSprite *vsp; - VgaPointersEntry *vpe; - VC10_state state; - - vsp = _vgaSprites; - while (vsp->id != 0) { - if (vsp->id == 128) { - byte *old_file_1 = _curVgaFile1; - byte *old_file_2 = _curVgaFile2; - uint palmode = _windowNum; - - vpe = &_vgaBufferPointers[vsp->zoneNum]; - _curVgaFile1 = vpe->vgaFile1; - _curVgaFile2 = vpe->vgaFile2; - _windowNum = vsp->windowNum; - - drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags); - - _windowNum = palmode; - _curVgaFile1 = old_file_1; - _curVgaFile2 = old_file_2; - break; - } - vsp++; - } - } - 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 { - if (_windowNum != 4) + if (_windowNum != 4) { memset(getFrontBuf(), 0, _screenWidth * _screenHeight); + } } } if (getGameType() == GType_SIMON2) { -- cgit v1.2.3