aboutsummaryrefslogtreecommitdiff
path: root/engines/agos
diff options
context:
space:
mode:
authorTravis Howell2007-05-13 08:46:48 +0000
committerTravis Howell2007-05-13 08:46:48 +0000
commitb6672f37a97f30298e51b1d4574eeb75a31da1a6 (patch)
tree67e64d391ee29aabbb8ce92fe8d91b120043b375 /engines/agos
parentaa89759a5521bc58cad5375865e0650bced30daf (diff)
downloadscummvm-rg350-b6672f37a97f30298e51b1d4574eeb75a31da1a6.tar.gz
scummvm-rg350-b6672f37a97f30298e51b1d4574eeb75a31da1a6.tar.bz2
scummvm-rg350-b6672f37a97f30298e51b1d4574eeb75a31da1a6.zip
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
Diffstat (limited to 'engines/agos')
-rw-r--r--engines/agos/agos.cpp37
-rw-r--r--engines/agos/agos.h17
-rw-r--r--engines/agos/charset.cpp6
-rw-r--r--engines/agos/draw.cpp295
-rw-r--r--engines/agos/event.cpp70
-rw-r--r--engines/agos/gfx.cpp111
-rw-r--r--engines/agos/icons.cpp4
-rw-r--r--engines/agos/input.cpp4
-rw-r--r--engines/agos/saveload.cpp5
-rw-r--r--engines/agos/script.cpp19
-rw-r--r--engines/agos/subroutine.cpp10
-rw-r--r--engines/agos/vga.cpp36
-rw-r--r--engines/agos/vga_e2.cpp1
-rw-r--r--engines/agos/vga_ww.cpp46
14 files changed, 298 insertions, 363 deletions
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) {