diff options
author | Travis Howell | 2006-10-20 02:10:51 +0000 |
---|---|---|
committer | Travis Howell | 2006-10-20 02:10:51 +0000 |
commit | ff574a63ee368cdb4889dd0e17966b4a1ae1f117 (patch) | |
tree | 40f477be1667843709f794e9628870ac3e3258cc /engines/agos/vga.cpp | |
parent | e26954bcdb0a0277b5c6df4e785d1909d9865c7f (diff) | |
download | scummvm-rg350-ff574a63ee368cdb4889dd0e17966b4a1ae1f117.tar.gz scummvm-rg350-ff574a63ee368cdb4889dd0e17966b4a1ae1f117.tar.bz2 scummvm-rg350-ff574a63ee368cdb4889dd0e17966b4a1ae1f117.zip |
Split code into more specific files and cleanup
svn-id: r24394
Diffstat (limited to 'engines/agos/vga.cpp')
-rw-r--r-- | engines/agos/vga.cpp | 1812 |
1 files changed, 295 insertions, 1517 deletions
diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index e9dce8f07c..c612e6c1ce 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -159,57 +159,6 @@ void AGOSEngine::setupWaxworksVideoOpcodes(VgaOpcodeProc *op) { op[63] = &AGOSEngine::vc63_fastFadeIn; } -void AGOSEngine::setupSimon1VideoOpcodes(VgaOpcodeProc *op) { - setupCommonVideoOpcodes(op); - - op[11] = &AGOSEngine::vc11_clearPathFinder; - op[17] = &AGOSEngine::vc17_setPathfinderItem; - op[22] = &AGOSEngine::vc22_setPaletteNew; - op[32] = &AGOSEngine::vc32_copyVar; - op[37] = &AGOSEngine::vc37_addToSpriteY; - op[48] = &AGOSEngine::vc48_setPathFinder; - op[59] = &AGOSEngine::vc59_skipIfSpeechEnded; - op[60] = &AGOSEngine::vc60_stopAnimation; - op[61] = &AGOSEngine::vc61_setMaskImage; - op[62] = &AGOSEngine::vc62_fastFadeOut; - op[63] = &AGOSEngine::vc63_fastFadeIn; -} - -void AGOSEngine::setupSimon2VideoOpcodes(VgaOpcodeProc *op) { - setupSimon1VideoOpcodes(op); - - op[56] = &AGOSEngine::vc56_delayLong; - op[58] = &AGOSEngine::vc58_changePriority; - op[59] = &AGOSEngine::vc59_stopAnimations; - op[64] = &AGOSEngine::vc64_skipIfSpeechEnded; - op[65] = &AGOSEngine::vc65_slowFadeIn; - op[66] = &AGOSEngine::vc66_skipIfNotEqual; - op[67] = &AGOSEngine::vc67_skipIfGE; - op[68] = &AGOSEngine::vc68_skipIfLE; - op[69] = &AGOSEngine::vc69_playTrack; - op[70] = &AGOSEngine::vc70_queueMusic; - op[71] = &AGOSEngine::vc71_checkMusicQueue; - op[72] = &AGOSEngine::vc72_play_track_2; - op[73] = &AGOSEngine::vc73_setMark; - op[74] = &AGOSEngine::vc74_clearMark; -} - -void AGOSEngine::setupFeebleVideoOpcodes(VgaOpcodeProc *op) { - setupSimon2VideoOpcodes(op); - - op[53] = &AGOSEngine::vc53_panSFX; - op[75] = &AGOSEngine::vc75_setScale; - op[76] = &AGOSEngine::vc76_setScaleXOffs; - op[77] = &AGOSEngine::vc77_setScaleYOffs; - op[78] = &AGOSEngine::vc78_computeXY; - op[79] = &AGOSEngine::vc79_computePosNum; - op[80] = &AGOSEngine::vc80_setOverlayImage; - op[81] = &AGOSEngine::vc81_setRandom; - op[82] = &AGOSEngine::vc82_getPathValue; - op[83] = &AGOSEngine::vc83_playSoundLoop; - op[84] = &AGOSEngine::vc84_stopSoundLoop; -} - void AGOSEngine::setupVgaOpcodes() { memset(_vga_opcode_table, 0, sizeof(_vga_opcode_table)); @@ -295,6 +244,21 @@ bool AGOSEngine::itemIsParentOf(uint16 a, uint16 b) { return derefItem(item_a->parent) == item_b; } +bool AGOSEngine::isSpriteLoaded(uint16 id, uint16 zoneNum) { + VgaSprite *vsp = _vgaSprites; + while (vsp->id) { + if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) { + if (vsp->id == id && vsp->zoneNum == zoneNum) + return true; + } else { + if (vsp->id == id) + return true; + } + vsp++; + } + return false; +} + bool AGOSEngine::vc_maybe_skip_proc_1(uint16 a, int16 b) { Item *item; @@ -543,10 +507,6 @@ void AGOSEngine::vc2_call() { void AGOSEngine::vc3_loadSprite() { uint16 windowNum, zoneNum, palette, x, y, vgaSpriteId; - uint16 count, res; - VgaSprite *vsp; - VgaPointersEntry *vpe; - byte *p, *pp; byte *old_file_1; if (getGameType() == GType_PP && getBitFlag(100)) { @@ -568,115 +528,7 @@ void AGOSEngine::vc3_loadSprite() { y = vcReadNextWord(); /* 6 */ palette = vcReadNextWord(); /* 8 */ - if (isSpriteLoaded(vgaSpriteId, zoneNum)) - return; - - vsp = _vgaSprites; - while (vsp->id) - vsp++; - - if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) - vsp->palette = 0; - else - vsp->palette = palette; - vsp->windowNum = windowNum; - vsp->priority = 0; - vsp->flags = 0; - vsp->image = 0; - vsp->x = x; - vsp->y = y; - vsp->id = vgaSpriteId; - vsp->zoneNum = res = zoneNum; - - old_file_1 = _curVgaFile1; - for (;;) { - vpe = &_vgaBufferPointers[res]; - _curVgaFile1 = vpe->vgaFile1; - - if (vpe->vgaFile1 != NULL) - break; - if (_zoneNumber != res) - _noOverWrite = _zoneNumber; - - loadZone(res); - _noOverWrite = 0xFFFF; - } - - 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; - dump_vga_file(_curVgaFile1); - } - } -#endif - -#ifdef DUMP_BITMAPS_FILE_NR - { - static bool dumped = false; - if (res == DUMP_BITMAPS_FILE_NR && !dumped) { - dumped = true; - dump_vga_bitmaps(_curVgaFile2, _curVgaFile1, res); - } - } -#endif - - if (_startVgaScript) { - if (getGameType() == GType_FF || getGameType() == GType_PP) { - dump_vga_script(_curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), res, vgaSpriteId); - } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon*)p)->scriptOffs), res, vgaSpriteId); - } else { - dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW*)p)->scriptOffs), res, vgaSpriteId); - } - } - - if (getGameType() == GType_FF || getGameType() == GType_PP) { - addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->scriptOffs), vgaSpriteId, res); - } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon *) p)->scriptOffs), vgaSpriteId, res); - } else { - addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW *) p)->scriptOffs), vgaSpriteId, res); - } + animate(windowNum, zoneNum, vgaSpriteId, x, y, palette, false); _curVgaFile1 = old_file_1; } @@ -723,55 +575,6 @@ void AGOSEngine::vc9_skip_if_unk3_is() { vcSkipNextInstruction(); } -byte *vc10_depackColumn(VC10_state * vs) { - int8 a = vs->depack_cont; - const byte *src = vs->depack_src; - byte *dst = vs->depack_dest; - uint16 dh = vs->dh; - byte color; - - if (a == -0x80) - a = *src++; - - for (;;) { - if (a >= 0) { - color = *src++; - do { - *dst++ = color; - if (!--dh) { - if (--a < 0) - a = -0x80; - else - src--; - goto get_out; - } - } while (--a >= 0); - } else { - do { - *dst++ = *src++; - if (!--dh) { - if (++a == 0) - a = -0x80; - goto get_out; - } - } while (++a != 0); - } - a = *src++; - } - -get_out:; - vs->depack_src = src; - vs->depack_cont = a; - return vs->depack_dest + vs->y_skip; -} - -void vc10_skip_cols(VC10_state *vs) { - while (vs->x_skip) { - vc10_depackColumn(vs); - vs->x_skip--; - } -} - byte *AGOSEngine::vc10_uncompressFlip(const byte *src, uint w, uint h) { w *= 8; @@ -862,94 +665,6 @@ byte *AGOSEngine::vc10_flip(const byte *src, uint w, uint h) { return _videoBuf1; } -void AGOSEngine::decodeColumn(byte *dst, const byte *src, int height) { - const uint pitch = _dxSurfacePitch; - int8 reps = (int8)0x80; - byte color; - byte *dstPtr = dst; - uint h = height, w = 8; - - for (;;) { - reps = *src++; - if (reps >= 0) { - color = *src++; - - do { - *dst = color; - dst += pitch; - - /* reached bottom? */ - if (--h == 0) { - /* reached right edge? */ - if (--w == 0) - return; - dst = ++dstPtr; - h = height; - } - } while (--reps >= 0); - } else { - - do { - *dst = *src++; - dst += pitch; - - /* reached bottom? */ - if (--h == 0) { - /* reached right edge? */ - if (--w == 0) - return; - dst = ++dstPtr; - h = height; - } - } while (++reps != 0); - } - } -} - -void AGOSEngine::decodeRow(byte *dst, const byte *src, int width) { - const uint pitch = _dxSurfacePitch; - int8 reps = (int8)0x80; - byte color; - byte *dstPtr = dst; - uint w = width, h = 8; - - for (;;) { - reps = *src++; - if (reps >= 0) { - color = *src++; - - do { - *dst++ = color; - - /* reached right edge? */ - if (--w == 0) { - /* reached bottom? */ - if (--h == 0) - return; - dstPtr += pitch; - dst = dstPtr; - w = width; - } - } while (--reps >= 0); - } else { - - do { - *dst++ = *src++; - - /* reached right edge? */ - if (--w == 0) { - /* reached bottom? */ - if (--h == 0) - return; - dstPtr += pitch; - dst = dstPtr; - w = width; - } - } while (++reps != 0); - } - } -} - void AGOSEngine::vc10_draw() { byte *p2; uint width, height; @@ -1062,589 +777,11 @@ void AGOSEngine::vc10_draw() { } } -bool AGOSEngine::drawImages_clip(VC10_state *state) { - const uint16 *vlut; - uint maxWidth, maxHeight; - int cur; - - vlut = &_videoWindows[_windowNum * 4]; - - if (getGameType() != GType_FF && getGameType() != GType_PP) { - state->draw_width = state->width * 2; - } - - cur = state->x; - if (cur < 0) { - do { - if (!--state->draw_width) - return 0; - state->x_skip++; - } while (++cur); - } - state->x = cur; - - maxWidth = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenWidth : (vlut[2] * 2); - cur += state->draw_width - maxWidth; - if (cur > 0) { - do { - if (!--state->draw_width) - return 0; - } while (--cur); - } - - cur = state->y; - if (cur < 0) { - do { - if (!--state->draw_height) - return 0; - state->y_skip++; - } while (++cur); - } - state->y = cur; - - maxHeight = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenHeight : vlut[3]; - cur += state->draw_height - maxHeight; - if (cur > 0) { - do { - if (!--state->draw_height) - return 0; - } while (--cur); - } - - assert(state->draw_width != 0 && state->draw_height != 0); - - if (getGameType() != GType_FF && getGameType() != GType_PP) { - state->draw_width *= 4; - } - - return 1; -} - -void AGOSEngine::drawImages_Feeble(VC10_state *state) { - if (state->flags & kDFCompressed) { - if (state->flags & kDFScaled) { - state->surf_addr = getScaleBuf(); - state->surf_pitch = _dxSurfacePitch; - - uint w, h; - byte *src, *dst, *dstPtr; - - state->dl = state->width; - state->dh = state->height; - - dstPtr = state->surf_addr; - w = 0; - do { - src = vc10_depackColumn(state); - dst = dstPtr; - - h = 0; - do { - *dst = *src; - dst += _screenWidth; - src++; - } while (++h != state->draw_height); - dstPtr++; - } while (++w != state->draw_width); - - if (_vgaCurSpritePriority % 10 != 9) { - _scaleX = state->x; - _scaleY = state->y; - _scaleWidth = state->width; - _scaleHeight = state->height; - } else { - scaleClip(state->height, state->width, state->y, state->x, state->y + _scrollY); - } - } else if (state->flags & kDFOverlayed) { - state->surf_addr = getScaleBuf(); - state->surf_pitch = _dxSurfacePitch; - state->surf_addr += (state->x + _scrollX) + (state->y + _scrollY) * state->surf_pitch; - - uint w, h; - byte *src, *dst, *dstPtr; - - state->dl = state->width; - state->dh = state->height; - - dstPtr = state->surf_addr; - w = 0; - do { - byte color; - - src = vc10_depackColumn(state); - dst = dstPtr; - - h = 0; - do { - color = *src; - if (color != 0) - *dst = color; - dst += _screenWidth; - src++; - } while (++h != state->draw_height); - dstPtr++; - } while (++w != state->draw_width); - - if (_vgaCurSpritePriority % 10 == 9) { - scaleClip(_scaleHeight, _scaleWidth, _scaleY, _scaleX, _scaleY + _scrollY); - } - } else { - if (drawImages_clip(state) == 0) - return; - - state->surf_addr += state->x + state->y * state->surf_pitch; - - uint w, h; - byte *src, *dst, *dstPtr; - - state->dl = state->width; - state->dh = state->height; - - vc10_skip_cols(state); - - - if (state->flags & kDFMasked) { - if (getGameType() == GType_FF && !getBitFlag(81)) { - if (state->x > _feebleRect.right) - return; - if (state->y > _feebleRect.bottom) - return; - if (state->x + state->width < _feebleRect.left) - return; - if (state->y + state->height < _feebleRect.top) - return; - } - - dstPtr = state->surf_addr; - w = 0; - do { - byte color; - - src = vc10_depackColumn(state); - dst = dstPtr; - - h = 0; - do { - color = *src; - if (color) - *dst = color; - dst += _screenWidth; - src++; - } while (++h != state->draw_height); - dstPtr++; - } while (++w != state->draw_width); - } else { - dstPtr = state->surf_addr; - w = 0; - do { - byte color; - - src = vc10_depackColumn(state); - dst = dstPtr; - - h = 0; - do { - color = *src; - if ((state->flags & kDFNonTrans) || color != 0) - *dst = color; - dst += _screenWidth; - src++; - } while (++h != state->draw_height); - dstPtr++; - } while (++w != state->draw_width); - } - } - } else { - if (drawImages_clip(state) == 0) - return; - - state->surf_addr += state->x + state->y * state->surf_pitch; - - const byte *src; - byte *dst; - uint count; - - src = state->depack_src + state->width * state->y_skip; - dst = state->surf_addr; - do { - for (count = 0; count != state->draw_width; count++) { - byte color; - color = src[count + state->x_skip]; - if (color) { - if ((state->flags & kDFShaded) && color == 220) - color = 244; - - dst[count] = color; - } - } - dst += _screenWidth; - src += state->width; - } while (--state->draw_height); - } -} - -void AGOSEngine::drawImages(VC10_state *state) { - const uint16 *vlut = &_videoWindows[_windowNum * 4]; - - if (drawImages_clip(state) == 0) - return; - - uint xoffs, yoffs; - 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; - //} - } else 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); - } - - state->surf2_addr += xoffs + yoffs * state->surf_pitch; - state->surf_addr += xoffs + yoffs * state->surf2_pitch; - - if (state->flags & kDFMasked) { - 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; - if ((getGameType() == GType_SIMON1) && getBitFlag(88)) { - /* transparency */ - do { - if (mask[0] & 0xF0) { - if ((dst[0] & 0x0F0) == 0x20) - dst[0] = src[0]; - } - if (mask[0] & 0x0F) { - if ((dst[1] & 0x0F0) == 0x20) - dst[1] = src[1]; - } - mask++; - dst += state->surf_pitch; - src += state->surf2_pitch; - } while (--h); - } else { - /* no transparency */ - do { - 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 if ((((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) && - (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) && - getPlatform() != Common::kPlatformAmiga) { - const byte *src; - byte *dst; - uint h, i; - - if (state->flags & kDFCompressed) { - byte *dstPtr = state->surf_addr; - src = state->depack_src; - /* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE - * aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh - */ - - do { - uint count = state->draw_width / 4; - - 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; - - 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->depack_src + (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); - } - } else { - if (getGameType() == GType_SIMON2 && state->flags & kDFUseFrontBuf && getBitFlag(171)) { - 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; - - state->x_skip *= 4; /* reached */ - - state->dl = state->width; - state->dh = state->height; - - vc10_skip_cols(state); - - dstPtr = state->surf_addr; - if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */ - dstPtr += vcReadVar(252); - } - w = 0; - do { - byte color; - - src = vc10_depackColumn(state); - dst = dstPtr; - - 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); - } else { - const byte *src; - byte *dst; - uint count; - - src = state->depack_src + (state->width * state->y_skip) * 8; - dst = state->surf_addr; - state->x_skip *= 4; - - 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); - } - } -} - -void AGOSEngine::horizontalScroll(VC10_state *state) { - const byte *src; - byte *dst; - int w; - - if (getGameType() == GType_FF) - _scrollXMax = state->width - 640; - else - _scrollXMax = state->width * 2 - 40; - _scrollYMax = 0; - _scrollImage = state->depack_src; - _scrollHeight = state->height; - if (_variableArrayPtr[34] < 0) - state->x = _variableArrayPtr[251]; - - _scrollX = state->x; - - vcWriteVar(251, _scrollX); - - dst = getBackBuf(); - - if (getGameType() == GType_FF) - src = state->depack_src + _scrollX / 2; - else - src = state->depack_src + _scrollX * 4; - - for (w = 0; w < _screenWidth; w += 8) { - decodeColumn(dst, src + readUint32Wrapper(src), state->height); - dst += 8; - src += 4; - } -} - -void AGOSEngine::verticalScroll(VC10_state *state) { - const byte *src; - byte *dst; - int h; - - _scrollXMax = 0; - _scrollYMax = state->height - 480; - _scrollImage = state->depack_src; - _scrollWidth = state->width; - if (_variableArrayPtr[34] < 0) - state->y = _variableArrayPtr[250]; - - _scrollY = state->y; - - vcWriteVar(250, _scrollY); - - dst = getBackBuf(); - src = state->depack_src + _scrollY / 2; - - for (h = 0; h < _screenHeight; h += 8) { - decodeRow(dst, src + READ_LE_UINT32(src), state->width); - dst += 8 * state->width; - src += 4; - } -} - -void AGOSEngine::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::vc11() { uint a = vcReadNextWord(); debug(0, "vc11: stub (%d)", a); } -void AGOSEngine::vc11_clearPathFinder() { - memset(&_pathFindArray, 0, sizeof(_pathFindArray)); -} - void AGOSEngine::vc12_delay() { VgaSprite *vsp = findCurSprite(); uint16 num; @@ -1744,16 +881,6 @@ void AGOSEngine::vc17_waitEnd() { _vcPtr = (byte *)&_vc_get_out_of_code; } -void AGOSEngine::vc17_setPathfinderItem() { - uint16 a = vcReadNextWord(); - _pathFindArray[a - 1] = (const uint16 *)_vcPtr; - - int end = (getGameType() == GType_FF || getGameType() == GType_PP) ? 9999 : 999; - while (readUint16Wrapper(_vcPtr) != end) - _vcPtr += 4; - _vcPtr += 2; -} - void AGOSEngine::vc18_jump() { int16 offs = vcReadNextWord(); _vcPtr += offs; @@ -1861,42 +988,6 @@ void AGOSEngine::vc22_setPaletteOld() { _vgaSpriteChanged++; } -void AGOSEngine::vc22_setPaletteNew() { - byte *offs, *palptr, *src; - uint16 a = 0, b, num, palSize; - - a = vcReadNextWord(); - b = vcReadNextWord(); - - if (getGameType() == GType_FF || getGameType() == GType_PP) { - num = 256; - palSize = 768; - - palptr = _displayPalette; - } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - num = a == 0 ? 32 : 16; - palSize = 96; - - palptr = &_displayPalette[(a * 64)]; - } - - offs = _curVgaFile1 + 6; - src = offs + b * palSize; - - do { - palptr[0] = src[0] * 4; - palptr[1] = src[1] * 4; - palptr[2] = src[2] * 4; - palptr[3] = 0; - - palptr += 4; - src += 3; - } while (--num); - - _paletteFlag = 2; - _vgaSpriteChanged++; -} - void AGOSEngine::vc23_setPriority() { VgaSprite *vsp = findCurSprite(), *vus2; uint16 pri = vcReadNextWord(); @@ -2083,11 +1174,6 @@ void AGOSEngine::vc32_saveScreen() { debug(0, "vc32_saveScreen: stub"); } -void AGOSEngine::vc32_copyVar() { - uint16 a = vcReadVar(vcReadNextWord()); - vcWriteVar(vcReadNextWord(), a); -} - void AGOSEngine::vc33_setMouseOn() { if (_mouseHideCount != 0) { _mouseHideCount = 1; @@ -2154,12 +1240,6 @@ void AGOSEngine::vc37_pokePalette() { debug(0, "vc37_pokePalette: stub (%d, %d)", a, b); } -void AGOSEngine::vc37_addToSpriteY() { - VgaSprite *vsp = findCurSprite(); - vsp->y += vcReadVar(vcReadNextWord()); - _vgaSpriteChanged++; -} - void AGOSEngine::vc38_skipIfVarZero() { uint16 var; if (getGameType() == GType_PP) @@ -2275,12 +1355,6 @@ void AGOSEngine::vc45_setWindowPalette() { } } -void AGOSEngine::vc45_setSpriteX() { - VgaSprite *vsp = findCurSprite(); - vsp->x = vcReadVar(vcReadNextWord()); - _vgaSpriteChanged++; -} - void AGOSEngine::setPaletteSlot(uint srcOffs, uint dstOffs) { byte *offs, *palptr, *src; uint16 num; @@ -2309,100 +1383,16 @@ void AGOSEngine::vc46_setPaletteSlot1() { setPaletteSlot(srcOffs, 1); } -void AGOSEngine::vc46_setSpriteY() { - VgaSprite *vsp = findCurSprite(); - vsp->y = vcReadVar(vcReadNextWord()); - _vgaSpriteChanged++; -} - void AGOSEngine::vc47_setPaletteSlot2() { uint srcOffs = vcReadNextWord(); setPaletteSlot(srcOffs, 2); } -void AGOSEngine::vc47_addToVar() { - uint16 var = vcReadNextWord(); - vcWriteVar(var, vcReadVar(var) + vcReadVar(vcReadNextWord())); -} - void AGOSEngine::vc48_setPaletteSlot3() { uint srcOffs = vcReadNextWord(); setPaletteSlot(srcOffs, 3); } -void AGOSEngine::vc48_setPathFinder() { - uint16 a = (uint16)_variableArrayPtr[12]; - const uint16 *p = _pathFindArray[a - 1]; - - if (getGameType() == GType_FF || getGameType() == GType_PP) { - VgaSprite *vsp = findCurSprite(); - int16 x, y, ydiff; - int16 x1, y1, x2, y2; - uint pos = 0; - - x = vsp->x; - while (x >= (int16)readUint16Wrapper(p + 2)) { - p += 2; - pos++; - } - - x1 = readUint16Wrapper(p); - y1 = readUint16Wrapper(p + 1); - x2 = readUint16Wrapper(p + 2); - y2 = readUint16Wrapper(p + 3); - - if (x2 != 9999) { - ydiff = y2 - y1; - if (ydiff < 0) { - ydiff = -ydiff; - x = vsp->x & 7; - ydiff *= x; - ydiff /= 8; - ydiff = -ydiff; - } else { - x = vsp->x & 7; - ydiff *= x; - ydiff /= 8; - } - y1 += ydiff; - } - - y = vsp->y; - vsp->y = y1; - checkScrollY(y1 - y, y1); - - _variableArrayPtr[11] = x1; - _variableArrayPtr[13] = pos; - } else { - uint b = (uint16)_variableArray[13]; - p += b * 2 + 1; - int c = _variableArray[14]; - - int step; - int y1, y2; - int16 *vp; - - step = 2; - if (c < 0) { - c = -c; - step = -2; - } - - vp = &_variableArray[20]; - - do { - y2 = readUint16Wrapper(p); - p += step; - y1 = readUint16Wrapper(p) - y2; - - vp[0] = y1 / 2; - vp[1] = y1 - (y1 / 2); - - vp += 2; - } while (--c); - } -} - void AGOSEngine::setBitFlag(uint bit, bool value) { uint16 *bits = &_bitArray[bit / 16]; *bits = (*bits & ~(1 << (bit & 15))) | (value << (bit & 15)); @@ -2469,29 +1459,6 @@ void AGOSEngine::vc53_dissolveIn() { debug(0, "vc53_dissolveIn: stub (%d, %d)", num, speed); } -void AGOSEngine::vc53_panSFX() { - VgaSprite *vsp = findCurSprite(); - int pan; - - uint16 sound = vcReadNextWord(); - int16 xoffs = vcReadNextWord(); - int16 vol = vcReadNextWord(); - - pan = (vsp->x - _scrollX + xoffs) * 8 - 2560; - if (pan < -10000) - pan = -10000; - if (pan > 10000) - pan = 10000; - - loadSound(sound, 0, vol, 1); - - if (xoffs != 2) - xoffs |= 0x10; - - addVgaEvent(10, NULL, _vgaCurSpriteId, _vgaCurZoneNum, xoffs); /* pan event */ - debug(0, "vc53_panSFX: snd %d xoffs %d vol %d", sound, xoffs, vol); -} - void AGOSEngine::vc54_dissolveOut() { // TODO uint num = vcReadNextWord(); @@ -2539,13 +1506,6 @@ void AGOSEngine::vc56_fullScreen() { _system->setPalette(palette, 0, 256); } -void AGOSEngine::vc56_delayLong() { - uint16 num = vcReadVarOrWord() * _frameRate; - - addVgaEvent(num + _vgaBaseDelay, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum); - _vcPtr = (byte *)&_vc_get_out_of_code; -} - void AGOSEngine::vc57_blackPalette() { uint8 palette[1024]; memset(palette, 0, sizeof(palette)); @@ -2557,46 +1517,11 @@ void AGOSEngine::vc58_checkCodeWheel() { debug(0, "vc58_checkCodeWheel: stub"); } -void AGOSEngine::vc58_changePriority() { - uint16 sprite = _vgaCurSpriteId; - uint16 file = _vgaCurZoneNum; - const byte *vcPtrOrg; - uint16 tmp; - - _vgaCurZoneNum = vcReadNextWord(); - _vgaCurSpriteId = vcReadNextWord(); - - tmp = to16Wrapper(vcReadNextWord()); - - vcPtrOrg = _vcPtr; - _vcPtr = (byte *)&tmp; - vc23_setPriority(); - - _vcPtr = vcPtrOrg; - _vgaCurSpriteId = sprite; - _vgaCurZoneNum = file; -} - void AGOSEngine::vc59_skipIfNotEGA() { // Skip if not EGA vcSkipNextInstruction(); } -void AGOSEngine::vc59_skipIfSpeechEnded() { - if (!_sound->isVoiceActive()) - vcSkipNextInstruction(); -} - -void AGOSEngine::vc59_stopAnimations() { - uint16 file = vcReadNextWord(); - uint16 start = vcReadNextWord(); - uint16 end = vcReadNextWord() + 1; - - do { - vc_kill_sprite(file, start); - } while (++start != end); -} - void AGOSEngine::vc_kill_sprite(uint file, uint sprite) { uint16 old_sprite_id, old_cur_file_id; VgaSleepStruct *vfs; @@ -2718,17 +1643,6 @@ void AGOSEngine::vc61() { } } -void AGOSEngine::vc61_setMaskImage() { - VgaSprite *vsp = findCurSprite(); - - vsp->image = vcReadVarOrWord(); - vsp->x += vcReadNextWord(); - vsp->y += vcReadNextWord(); - vsp->flags = kDFMasked | kDFUseFrontBuf; - - _vgaSpriteChanged++; -} - void AGOSEngine::vc62_fastFadeOut() { vc29_stopAllSounds(); @@ -2833,493 +1747,357 @@ void AGOSEngine::vc63_fastFadeIn() { _fastFadeOutFlag = false; } -void AGOSEngine::vc64_skipIfSpeechEnded() { - if ((getGameType() == GType_SIMON2 && _subtitles && _language != Common::HB_ISR) || - !_sound->isVoiceActive()) { - vcSkipNextInstruction(); - } -} - -void AGOSEngine::vc65_slowFadeIn() { - _fastFadeInFlag = 624; - _fastFadeCount = 208; - if (_windowNum != 4) { - _fastFadeInFlag = 768; - _fastFadeCount = 256; - } - _fastFadeInFlag |= 0x8000; - _fastFadeOutFlag = false; -} - -void AGOSEngine::vc66_skipIfNotEqual() { - uint16 a = vcReadNextWord(); - uint16 b = vcReadNextWord(); - - if (vcReadVar(a) != vcReadVar(b)) - vcSkipNextInstruction(); -} - -void AGOSEngine::vc67_skipIfGE() { - uint16 a = vcReadNextWord(); - uint16 b = vcReadNextWord(); +void AGOSEngine::animate(uint windowNum, uint zoneNum, uint vgaSpriteId, uint x, uint y, uint palette, bool setZone) { + VgaSprite *vsp; + VgaPointersEntry *vpe; + byte *p, *pp; + uint count; - if (vcReadVar(a) >= vcReadVar(b)) - vcSkipNextInstruction(); -} + if (isSpriteLoaded(vgaSpriteId, zoneNum)) + return; -void AGOSEngine::vc68_skipIfLE() { - uint16 a = vcReadNextWord(); - uint16 b = vcReadNextWord(); + vsp = _vgaSprites; + while (vsp->id != 0) + vsp++; - if (vcReadVar(a) <= vcReadVar(b)) - vcSkipNextInstruction(); -} + vsp->windowNum = windowNum; + vsp->priority = 0; + vsp->flags = 0; -void AGOSEngine::vc69_playTrack() { - int16 track = vcReadNextWord(); - int16 loop = vcReadNextWord(); - - // Jamieson630: - // This is a "play track". The original - // design stored the track to play if one was - // already in progress, so that the next time a - // "fill MIDI stream" event occured, the MIDI - // player would find the change and switch - // tracks. We use a different architecture that - // allows for an immediate response here, but - // we'll simulate the variable changes so other - // scripts don't get thrown off. - // NOTE: This opcode looks very similar in function - // to vc72(), except that vc72() may allow for - // specifying a non-valid track number (999 or -1) - // as a means of stopping what music is currently - // playing. - midi.setLoop(loop != 0); - midi.startTrack(track); -} - -void AGOSEngine::vc70_queueMusic() { - // Simon2 - uint16 track = vcReadNextWord(); - uint16 loop = vcReadNextWord(); - - // Jamieson630: - // This sets the "on end of track" action. - // It specifies whether to loop the current - // track and, if not, whether to switch to - // a different track upon completion. - if (track != 0xFFFF && track != 999) - midi.queueTrack(track, loop != 0); + vsp->y = y; + vsp->x = x; + vsp->image = 0; + if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) + vsp->palette = 0; else - midi.setLoop(loop != 0); -} - -void AGOSEngine::vc71_checkMusicQueue() { - // Jamieson630: - // This command skips the next instruction - // unless (1) there is a track playing, AND - // (2) there is a track queued to play after it. - if (!midi.isPlaying (true)) - vcSkipNextInstruction(); -} - -void AGOSEngine::vc72_play_track_2() { - // Jamieson630: - // This is a "play or stop track". Note that - // this opcode looks very similar in function - // to vc69(), except that this opcode may allow - // for specifying a track of 999 or -1 in order to - // stop the music. We'll code it that way for now. + vsp->palette = palette; + vsp->id = vgaSpriteId; - // NOTE: It's possible that when "stopping" a track, - // we're supposed to just go on to the next queued - // track, if any. Must find out if there is ANY - // case where this is used to stop a track in the - // first place. + if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) + vsp->zoneNum = zoneNum; + else + vsp->zoneNum = zoneNum = vgaSpriteId / 100; - int16 track = vcReadNextWord(); - int16 loop = vcReadNextWord(); + for (;;) { + vpe = &_vgaBufferPointers[zoneNum]; + _curVgaFile1 = vpe->vgaFile1; + if (setZone) { + _zoneNumber = zoneNum; + if (vpe->vgaFile1 != NULL) + break; + loadZone(zoneNum); + } else { + if (vpe->vgaFile1 != NULL) + break; + if (_zoneNumber != zoneNum) + _noOverWrite = _zoneNumber; - if (track == -1 || track == 999) { - midi.stop(); - } else { - midi.setLoop (loop != 0); - midi.startTrack (track); + loadZone(zoneNum); + _noOverWrite = 0xFFFF; + } } -} - -void AGOSEngine::vc73_setMark() { - _marks |= (1 << vcReadNextWord()); -} -void AGOSEngine::vc74_clearMark() { - _marks &= ~(1 << vcReadNextWord()); -} + 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); -int AGOSEngine::getScale(int16 y, int16 x) { - int16 z; + 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); - if (y > _baseY) { - return((int16)(x * (1 + ((y - _baseY) * _scale)))); - } else { - if (x == 0) - return(0); - if (x < 0) { - z = ((int16)((x * (1 - ((_baseY - y)* _scale))) - 0.5)); - if (z >- 2) - return(-2); - return(z); + 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; - z = ((int16)((x * (1 - ((_baseY - y) * _scale))) + 0.5)); - if (z < 2) - return(2); + count = READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationCount); + p = pp + READ_BE_UINT16(&((VgaFileHeader2_Common *) p)->animationTable); - return(z); + 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); } -} - -void AGOSEngine::vc75_setScale() { - _baseY = vcReadNextWord(); - _scale = (float)vcReadNextWord() / 1000000.; -} -void AGOSEngine::vc76_setScaleXOffs() { - if (getGameType() == GType_PP && getBitFlag(120)) { - VgaSprite *vsp1, *vsp2; - uint16 old_file_1, tmp1, tmp2; - - old_file_1 = _vgaCurSpriteId; +#ifdef DUMP_FILE_NR + { + static bool dumped = false; + if (res == DUMP_FILE_NR && !dumped) { + dumped = true; + dump_vga_file(_curVgaFile1); + } + } +#endif - _vgaCurSpriteId = vcReadVar(vcReadNextWord()); - vsp1 = findCurSprite(); - _vgaCurSpriteId = vcReadVar(vcReadNextWord()); - vsp2 = findCurSprite(); +#ifdef DUMP_BITMAPS_FILE_NR + { + static bool dumped = false; + if (res == DUMP_BITMAPS_FILE_NR && !dumped) { + dumped = true; + dump_vga_bitmaps(_curVgaFile2, _curVgaFile1, zoneNum); + } + } +#endif - tmp1 = vsp1->x; - tmp2 = vsp2->x; - vsp1->x = tmp2; - vsp2->x = tmp1; - tmp1 = vsp1->y; - tmp2 = vsp2->y; - vsp1->y = tmp2; - vsp2->y = tmp1; + if (_startVgaScript) { + if (getGameType() == GType_FF || getGameType() == GType_PP) { + dump_vga_script(_curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), zoneNum, vgaSpriteId); + } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { + dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon*)p)->scriptOffs), zoneNum, vgaSpriteId); + } else { + dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW*)p)->scriptOffs), zoneNum, vgaSpriteId); + } + } - _vgaCurSpriteId = old_file_1; - _vcPtr += 2; + 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 { - VgaSprite *vsp = findCurSprite(); - - vsp->image = vcReadNextWord(); - int16 x = vcReadNextWord(); - uint16 var = vcReadNextWord(); - - vsp->x += getScale(vsp->y, x); - _variableArrayPtr[var] = vsp->x; - - checkScrollX(x, vsp->x); - - vsp->flags = kDFScaled; + addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW *) p)->scriptOffs), vgaSpriteId, zoneNum); } } -void AGOSEngine::vc77_setScaleYOffs() { - VgaSprite *vsp = findCurSprite(); - - vsp->image = vcReadNextWord(); - int16 y = vcReadNextWord(); - uint16 var = vcReadNextWord(); - - vsp->y += getScale(vsp->y, y); - _variableArrayPtr[var] = vsp->y; - - if (y != 0) - checkScrollY(y, vsp->y); - - vsp->flags = kDFScaled; -} - -void AGOSEngine::vc78_computeXY() { - VgaSprite *vsp = findCurSprite(); - - uint16 a = (uint16)_variableArrayPtr[12]; - uint16 b = (uint16)_variableArrayPtr[13]; - - const uint16 *p = _pathFindArray[a - 1]; - p += b * 2; - - uint16 posx = readUint16Wrapper(p); - _variableArrayPtr[15] = posx; - vsp->x = posx; +void AGOSEngine::set_video_mode_internal(uint16 mode, uint16 vga_res_id) { + uint num, num_lines; + VgaPointersEntry *vpe; + byte *bb, *b; + uint16 count, updateWindow; + const byte *vc_ptr_org; - uint16 posy = readUint16Wrapper(p + 1); - _variableArrayPtr[16] = posy; - vsp->y = posy; + _windowNum = updateWindow = mode; + _lockWord |= 0x20; - if (getGameType() == GType_FF) { - setBitFlag(85, false); - if (getBitFlag(74)) { - centreScroll(); - } + if (getGameType() == GType_FF || getGameType() == GType_PP) { + vc27_resetSprite(); } -} - -void AGOSEngine::vc79_computePosNum() { - uint a = (uint16)_variableArrayPtr[12]; - const uint16 *p = _pathFindArray[a - 1]; - uint pos = 0; - int16 y = _variableArrayPtr[16]; - while (y >= (int16)readUint16Wrapper(p + 1)) { - p += 2; - pos++; + if (vga_res_id == 0) { + if (getGameType() == GType_SIMON1) { + _unkPalFlag = true; + } else if (getGameType() == GType_SIMON2) { + _useBackGround = true; + _restoreWindow6 = true; + } } - _variableArrayPtr[13] = pos; -} - -void AGOSEngine::vc80_setOverlayImage() { - VgaSprite *vsp = findCurSprite(); + _zoneNumber = num = vga_res_id / 100; - vsp->image = vcReadVarOrWord(); + for (;;) { + vpe = &_vgaBufferPointers[num]; - vsp->x += vcReadNextWord(); - vsp->y += vcReadNextWord(); - vsp->flags = kDFOverlayed; + _curVgaFile1 = vpe->vgaFile1; + _curVgaFile2 = vpe->vgaFile2; + _curSfxFile = vpe->sfxFile; - _vgaSpriteChanged++; -} + if (vpe->vgaFile1 != NULL) + break; -void AGOSEngine::vc81_setRandom() { - uint16 var = vcReadNextWord(); - uint16 value = vcReadNextWord(); + loadZone(num); + } - _variableArray[var] = _rnd.getRandomNumber(value - 1); -} + 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); -void AGOSEngine::vc82_getPathValue() { - uint8 val; + 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); - uint16 var = vcReadNextWord(); + } 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); - if (getGameType() == GType_FF && getBitFlag(82)) { - val = _pathValues1[_GPVCount1++]; + 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 { - val = _pathValues[_GPVCount++]; - } - - vcWriteVar(var, val); -} - -void AGOSEngine::vc83_playSoundLoop() { - uint16 sound = vcReadNextWord(); - int16 vol = vcReadNextWord(); - int16 pan = vcReadNextWord(); - - loadSound(sound, pan, vol, 3); -} + b = bb + READ_BE_UINT16(bb + 10); + b += 20; -void AGOSEngine::vc84_stopSoundLoop() { - _sound->stopSfx5(); -} + count = READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageCount); + b = bb + READ_BE_UINT16(&((VgaFileHeader2_Common *) b)->imageTable); -// Scrolling functions for Feeble Files -void AGOSEngine::checkScrollX(int16 x, int16 xpos) { - if (_scrollXMax == 0 || x == 0) - return; + 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 ((getGameType() == GType_FF) && (getBitFlag(80) || getBitFlag(82))) - return; + clearWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_WW *) b)->color)); + } - int16 tmp; - if (x > 0) { - if (_scrollCount != 0) { - if (_scrollCount >= 0) - return; - _scrollCount = 0; + if (_startVgaScript) { + if (getGameType() == GType_FF || getGameType() == GType_PP) { + dump_vga_script(_curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble*)b)->scriptOffs), num, vga_res_id); + } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { + dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon*)b)->scriptOffs), num, vga_res_id); } else { - if (_scrollFlag != 0) - return; + dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((ImageHeader_WW*)b)->scriptOffs), num, vga_res_id); } + } - if (xpos - _scrollX >= 480) { - _scrollCount = 320; - tmp = _scrollXMax - _scrollX; - if (tmp < 320) - _scrollCount = tmp; - } - } else { - if (_scrollCount != 0) { - if (_scrollCount < 0) - return; - _scrollCount = 0; - } else { - if (_scrollFlag != 0) - return; + if (getGameType() == GType_SIMON1) { + if (vga_res_id == 16300) { + clearBackFromTop(134); + _usePaletteDelay = true; } - - if (xpos - _scrollX < 161) { - _scrollCount = -320; - if (_scrollX < 320) - _scrollCount = -_scrollX; + } 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; } } -} -void AGOSEngine::checkScrollY(int16 y, int16 ypos) { - if (_scrollYMax == 0) - return; + vc_ptr_org = _vcPtr; - if (getGameType() == GType_FF && getBitFlag(80)) - return; + 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); + } - int16 tmp; - if (y >= 0) { - if (_scrollCount != 0) { - if (_scrollCount >= 0) - return; - } else { - if (_scrollFlag != 0) - return; - } + runVgaScript(); + _vcPtr = vc_ptr_org; - if (ypos - _scrollY >= 440) { - _scrollCount = 240; - tmp = _scrollYMax - _scrollY; - if (tmp < 240) - _scrollCount = tmp; - } + 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 (_scrollCount != 0) { - if (_scrollCount < 0) - return; - } else { - if (_scrollFlag != 0) - return; - } + // 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; - if (ypos - _scrollY < 100) { - _scrollCount = -240; - if (_scrollY < 240) - _scrollCount = -_scrollY; - } + fillFrontFromBack(0, 0, _screenWidth, num_lines); + fillBackGroundFromBack(num_lines); + + _syncFlag2 = 1; + _timer5 = 0; } -} -void AGOSEngine::centreScroll() { - int16 x, y, tmp; + if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette != 0) { + byte *dst = getBackBuf() + 42560; + int size = 21440; - if (_scrollXMax != 0) { - _scrollCount = 0; - x = _variableArray[15] - _scrollX; - if (x < 17 || (getBitFlag(85) && x < 320)) { - x -= 320; - if (_scrollX < -x) - x = -_scrollX; - _scrollCount = x; - } else if ((getBitFlag(85) && x >= 320) || x >= 624) { - x -= 320; - tmp = _scrollXMax - _scrollX; - if (tmp < x) - x = tmp; - _scrollCount = x; - } - } else if (_scrollYMax != 0) { - _scrollCount = 0; - y = _variableArray[16] - _scrollY; - if (y < 30) { - y -= 240; - if (_scrollY < -y) - y = -_scrollY; - _scrollCount = y; - } else if (y >= 460) { - y -= 240; - tmp = _scrollYMax - _scrollY; - if (tmp < y) - y = tmp; - _scrollCount = y; + while (size--) { + *dst += 0x10; + dst++; } } -} - -void AGOSEngine::startOverlayAnims() { - VgaSprite *vsp = _vgaSprites; - uint16 zoneNum; - int i; - - zoneNum = _variableArray[999]; - - for (i = 0; i < 600; i++) { - if (_variableArray[1000 + i] < 100) - continue; - while (vsp->id) - vsp++; + _lockWord &= ~0x20; - vsp->windowNum = 4; - vsp->priority = 4; - vsp->flags = 0; - vsp->palette = 0; - vsp->image = _variableArray[1000 + i]; - if (i >= 300) { - vsp->y = ((i - 300) / 20) * 32; - vsp->x = ((i - 300) % 20) * 32; - } else { - vsp->y = (i / 20) * 32; - vsp->x = (i % 20) * 32; + if (getGameType() == GType_SIMON1) { + if (_unkPalFlag) { + _unkPalFlag = false; + while (_fastFadeInFlag != 0) { + delay(10); + } } - vsp->id = 1000 + i; - vsp->zoneNum = zoneNum; } } -void AGOSEngine::startAnOverlayAnim() { - VgaSprite *vsp = _vgaSprites; - const byte *vcPtrOrg; - uint16 a, sprite, file, tmp, zoneNum; - int16 x; - - zoneNum = _variableArray[999]; - - _vcPtr += 4; - a = vcReadNextWord(); - _vcPtr += 6; +void AGOSEngine::waitForSync(uint a) { + const uint maxCount = (getGameType() == GType_SIMON1) ? 500 : 1000; - while (vsp->id) - vsp++; - - vsp->windowNum = 4; - vsp->priority = 20; - vsp->flags = 0; - vsp->palette = 0; - vsp->image = vcReadVar(vcReadVar(a)); - - x = vcReadVar(a) - 1300; - if (x < 0) { - x += 300; - vsp->priority = 10; + if (getGameType() == GType_SIMON1 && (getFeatures() & GF_TALKIE)) { + if (a != 200) { + uint16 tmp = _lastVgaWaitFor; + _lastVgaWaitFor = 0; + if (tmp == a) + return; + } } - vsp->y = x / 20 * 32; - vsp->x = x % 20 * 32;; - vsp->id = vcReadVar(a); - vsp->zoneNum = zoneNum; - - sprite = _vgaCurSpriteId; - file = _vgaCurZoneNum; - - _vgaCurZoneNum = vsp->zoneNum; - _vgaCurSpriteId = vsp->id; + _vgaWaitFor = a; + _syncCount = 0; + _exitCutscene = false; + _rightButtonDown = false; - tmp = to16Wrapper(vsp->priority); + while (_vgaWaitFor != 0) { + if (_rightButtonDown) { + if (_vgaWaitFor == 200 && (getGameType() == GType_FF || !getBitFlag(14))) { + skipSpeech(); + break; + } + } + if (_exitCutscene) { + if (getGameType() == GType_ELVIRA1) { + if (_variableArray[105] == 0) { + _variableArray[105] = 255; + break; + } + } else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) { + if (_vgaWaitFor == 51) { + setBitFlag(244, 1); + break; + } + } else { + if (getBitFlag(9)) { + endCutscene(); + break; + } + } + } + processSpecialKeys(); - vcPtrOrg = _vcPtr; - _vcPtr = (byte *)&tmp; - vc23_setPriority(); + if (_syncCount >= maxCount) { + warning("waitForSync: wait timed out"); + break; + } - _vcPtr = vcPtrOrg; - _vgaCurSpriteId = sprite; - _vgaCurZoneNum = file; + delay(1); + } } } // End of namespace AGOS |