aboutsummaryrefslogtreecommitdiff
path: root/engines/agos/gfx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/agos/gfx.cpp')
-rw-r--r--engines/agos/gfx.cpp352
1 files changed, 352 insertions, 0 deletions
diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp
index cd3b9d09b6..91e720c2ab 100644
--- a/engines/agos/gfx.cpp
+++ b/engines/agos/gfx.cpp
@@ -760,4 +760,356 @@ void AGOSEngine::paletteFadeOut(byte *palPtr, uint num, uint size) {
} while (--num);
}
+void AGOSEngine::animate(uint windowNum, uint zoneNum, uint vgaSpriteId, uint x, uint y, uint palette, bool vgaScript) {
+ VgaSprite *vsp;
+ VgaPointersEntry *vpe;
+ byte *p, *pp;
+ uint count;
+
+ if (isSpriteLoaded(vgaSpriteId, zoneNum))
+ return;
+
+ vsp = _vgaSprites;
+ while (vsp->id != 0)
+ vsp++;
+
+ vsp->windowNum = windowNum;
+ vsp->priority = 0;
+ vsp->flags = 0;
+
+ vsp->y = y;
+ vsp->x = x;
+ vsp->image = 0;
+ if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
+ vsp->palette = 0;
+ else
+ vsp->palette = palette;
+ vsp->id = vgaSpriteId;
+
+ if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP)
+ vsp->zoneNum = zoneNum;
+ else
+ vsp->zoneNum = zoneNum = vgaSpriteId / 100;
+
+ for (;;) {
+ vpe = &_vgaBufferPointers[zoneNum];
+ _curVgaFile1 = vpe->vgaFile1;
+ if (vgaScript) {
+ if (vpe->vgaFile1 != NULL)
+ break;
+ if (_zoneNumber != zoneNum)
+ _noOverWrite = _zoneNumber;
+
+ loadZone(zoneNum);
+ _noOverWrite = 0xFFFF;
+ } else {
+ _zoneNumber = zoneNum;
+ if (vpe->vgaFile1 != NULL)
+ break;
+ loadZone(zoneNum);
+ }
+ }
+
+ pp = _curVgaFile1;
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ p = pp + READ_LE_UINT16(pp + 2);
+ count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationCount);
+ p = pp + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationTable);
+
+ while (count--) {
+ if (READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) == vgaSpriteId)
+ break;
+ p += sizeof(AnimationHeader_Feeble);
+ }
+ assert(READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) == vgaSpriteId);
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ p = pp + READ_BE_UINT16(pp + 4);
+ count = READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationCount);
+ p = pp + READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationTable);
+
+ while (count--) {
+ if (READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) == vgaSpriteId)
+ break;
+ p += sizeof(AnimationHeader_Simon);
+ }
+ assert(READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) == vgaSpriteId);
+ } else {
+ p = pp + READ_BE_UINT16(pp + 10);
+ p += 20;
+
+ count = READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationCount);
+ p = pp + READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationTable);
+
+ while (count--) {
+ if (READ_BE_UINT16(&((AnimationHeader_WW *) p)->id) == vgaSpriteId)
+ break;
+ p += sizeof(AnimationHeader_WW);
+ }
+ assert(READ_BE_UINT16(&((AnimationHeader_WW *) p)->id) == vgaSpriteId);
+ }
+
+#ifdef DUMP_FILE_NR
+ {
+ static bool dumped = false;
+ if (res == DUMP_FILE_NR && !dumped) {
+ dumped = true;
+ dumpVgaFile(_curVgaFile1);
+ }
+ }
+#endif
+
+#ifdef DUMP_BITMAPS_FILE_NR
+ {
+ static bool dumped = false;
+ if (res == DUMP_BITMAPS_FILE_NR && !dumped) {
+ dumped = true;
+ dumpVgaBitmaps(_curVgaFile2, _curVgaFile1, zoneNum);
+ }
+ }
+#endif
+
+ if (_startVgaScript) {
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ dumpVgaScript(_curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), zoneNum, vgaSpriteId);
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ dumpVgaScript(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon*)p)->scriptOffs), zoneNum, vgaSpriteId);
+ } else {
+ dumpVgaScript(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW*)p)->scriptOffs), zoneNum, vgaSpriteId);
+ }
+ }
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->scriptOffs), vgaSpriteId, zoneNum);
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon *) p)->scriptOffs), vgaSpriteId, zoneNum);
+ } else {
+ addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW *) p)->scriptOffs), vgaSpriteId, zoneNum);
+ }
+}
+
+void AGOSEngine::setImage(uint16 vga_res_id, bool vgaScript) {
+ uint zoneNum;
+ VgaPointersEntry *vpe;
+ byte *bb, *b;
+ uint16 count;
+ const byte *vc_ptr_org;
+
+ zoneNum = vga_res_id / 100;
+
+ for (;;) {
+ vpe = &_vgaBufferPointers[zoneNum];
+ _curVgaFile1 = vpe->vgaFile1;
+ _curVgaFile2 = vpe->vgaFile2;
+
+ if (vgaScript) {
+ if (vpe->vgaFile1 != NULL)
+ break;
+ if (_zoneNumber != zoneNum)
+ _noOverWrite = _zoneNumber;
+
+ loadZone(zoneNum);
+ _noOverWrite = 0xFFFF;
+ } else {
+ _curSfxFile = vpe->sfxFile;
+ _zoneNumber = zoneNum;
+
+ if (vpe->vgaFile1 != NULL)
+ break;
+
+ loadZone(zoneNum);
+ }
+ }
+
+ bb = _curVgaFile1;
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ b = bb + READ_LE_UINT16(bb + 2);
+ count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageCount);
+ b = bb + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageTable);
+
+ while (count--) {
+ if (READ_LE_UINT16(&((ImageHeader_Feeble *) b)->id) == vga_res_id)
+ break;
+ b += sizeof(ImageHeader_Feeble);
+ }
+ assert(READ_LE_UINT16(&((ImageHeader_Feeble *) b)->id) == vga_res_id);
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ b = bb + READ_BE_UINT16(bb + 4);
+ count = READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageCount);
+ b = bb + READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageTable);
+
+ while (count--) {
+ if (READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == vga_res_id)
+ break;
+ b += sizeof(ImageHeader_Simon);
+ }
+ assert(READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == vga_res_id);
+ } else {
+ b = bb + READ_BE_UINT16(bb + 10);
+ b += 20;
+
+ count = READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageCount);
+ b = bb + READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageTable);
+
+ while (count--) {
+ if (READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == vga_res_id)
+ break;
+ b += sizeof(ImageHeader_WW);
+ }
+ assert(READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == vga_res_id);
+
+ if (!vgaScript)
+ clearWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_WW *) b)->color));
+ }
+
+ if (_startVgaScript) {
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ dumpVgaScript(_curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble*)b)->scriptOffs), zoneNum, vga_res_id);
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ dumpVgaScript(_curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon*)b)->scriptOffs), zoneNum, vga_res_id);
+ } else {
+ dumpVgaScript(_curVgaFile1 + READ_BE_UINT16(&((ImageHeader_WW*)b)->scriptOffs), zoneNum, vga_res_id);
+ }
+ }
+
+ vc_ptr_org = _vcPtr;
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ _vcPtr = _curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble *) b)->scriptOffs);
+ } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+ _vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon *) b)->scriptOffs);
+ } else {
+ _vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_WW *) b)->scriptOffs);
+ }
+
+ runVgaScript();
+ _vcPtr = vc_ptr_org;
+}
+
+void AGOSEngine::setWindowImageEx(uint16 mode, uint16 vga_res) {
+ if (!_initMouse) {
+ _initMouse = 1;
+ vc33_setMouseOn();
+ }
+
+ if (mode == 4) {
+ vc29_stopAllSounds();
+
+ if (getGameType() == GType_ELVIRA1) {
+ if (_variableArray[299] == 0) {
+ _variableArray[293] = 0;
+ _wallOn = 0;
+ }
+ } else if (getGameType() == GType_ELVIRA2) {
+ if (_variableArray[70] == 0) {
+ _variableArray[71] = 0;
+ _wallOn = 0;
+ }
+ }
+
+ }
+
+ if (_lockWord & 0x10)
+ error("setWindowImageEx: _lockWord & 0x10");
+
+ setWindowImage(mode, vga_res);
+}
+
+void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) {
+ uint num_lines;
+ uint16 updateWindow;
+
+ _windowNum = updateWindow = mode;
+ _lockWord |= 0x20;
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ vc27_resetSprite();
+ }
+
+ if (vga_res_id == 0) {
+ if (getGameType() == GType_SIMON1) {
+ _unkPalFlag = true;
+ } else if (getGameType() == GType_SIMON2) {
+ _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) {
+ _scrollX = 0;
+ _scrollY = 0;
+ _scrollXMax = 0;
+ _scrollYMax = 0;
+ _scrollCount = 0;
+ _scrollFlag = 0;
+ _scrollHeight = 134;
+ _variableArrayPtr = _variableArray;
+ if (_variableArray[34] >= 0) {
+ if (getGameType() == GType_FF)
+ _variableArray[250] = 0;
+ _variableArray[251] = 0;
+ }
+ }
+
+ setImage(vga_res_id);
+
+ if (getGameType() == GType_FF || getGameType() == GType_PP) {
+ fillFrontFromBack(0, 0, _screenWidth, _screenHeight);
+ fillBackGroundFromBack(_screenHeight);
+ _syncFlag2 = 1;
+ } else if (getGameType() == GType_SIMON2) {
+ 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) {
+ // 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 {
+ num_lines = _windowNum == 4 ? 134 : 200;
+ fillFrontFromBack(0, 0, _screenWidth, num_lines);
+ fillBackGroundFromBack(num_lines);
+ _syncFlag2 = 1;
+ _timer5 = 0;
+ }
+
+ if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette != 0) {
+ byte *dst = getBackBuf() + 42560;
+ int size = 21440;
+
+ while (size--) {
+ *dst += 0x10;
+ dst++;
+ }
+ }
+
+ _lockWord &= ~0x20;
+
+ if (getGameType() == GType_SIMON1) {
+ if (_unkPalFlag) {
+ _unkPalFlag = false;
+ while (_fastFadeInFlag != 0) {
+ delay(10);
+ }
+ }
+ }
+}
+
} // End of namespace AGOS