diff options
Diffstat (limited to 'engines/simon/vga.cpp')
| -rw-r--r-- | engines/simon/vga.cpp | 2788 |
1 files changed, 0 insertions, 2788 deletions
diff --git a/engines/simon/vga.cpp b/engines/simon/vga.cpp deleted file mode 100644 index d7deb2fbc0..0000000000 --- a/engines/simon/vga.cpp +++ /dev/null @@ -1,2788 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -// Video script opcodes for Simon1/Simon2 -#include "common/stdafx.h" - -#include "agos/agos.h" -#include "agos/intern.h" -#include "agos/vga.h" - -#include "common/system.h" - -namespace Simon { - -// Opcode tables -void SimonEngine::setupVgaOpcodes() { - static const VgaOpcodeProc vga_opcode_table[] = { - NULL, - &SimonEngine::vc1_fadeOut, - &SimonEngine::vc2_call, - &SimonEngine::vc3_loadSprite, - &SimonEngine::vc4_fadeIn, - &SimonEngine::vc5_skip_if_neq, - &SimonEngine::vc6_skip_ifn_sib_with_a, - &SimonEngine::vc7_skip_if_sib_with_a, - &SimonEngine::vc8_skip_if_parent_is, - &SimonEngine::vc9_skip_if_unk3_is, - &SimonEngine::vc10_draw, - &SimonEngine::vc11_clearPathFinder, - &SimonEngine::vc12_delay, - &SimonEngine::vc13_addToSpriteX, - &SimonEngine::vc14_addToSpriteY, - &SimonEngine::vc15_sync, - &SimonEngine::vc16_waitSync, - &SimonEngine::vc17_setPathfinderItem, - &SimonEngine::vc18_jump, - &SimonEngine::vc19_chain_to_script, - &SimonEngine::vc20_setRepeat, - &SimonEngine::vc21_endRepeat, - &SimonEngine::vc22_setSpritePalette, - &SimonEngine::vc23_setSpritePriority, - &SimonEngine::vc24_setSpriteXY, - &SimonEngine::vc25_halt_sprite, - &SimonEngine::vc26_setSubWindow, - &SimonEngine::vc27_resetSprite, - &SimonEngine::vc28_dummy_op, - &SimonEngine::vc29_stopAllSounds, - &SimonEngine::vc30_setFrameRate, - &SimonEngine::vc31_setWindow, - &SimonEngine::vc32_copyVar, - &SimonEngine::vc33_setMouseOn, - &SimonEngine::vc34_setMouseOff, - &SimonEngine::vc35_clearWindow, - &SimonEngine::vc36_setWindowImage, - &SimonEngine::vc37_addToSpriteY, - &SimonEngine::vc38_skipIfVarZero, - &SimonEngine::vc39_setVar, - &SimonEngine::vc40, - &SimonEngine::vc41, - &SimonEngine::vc42_delayIfNotEQ, - &SimonEngine::vc43_skipIfBitClear, - &SimonEngine::vc44_skipIfBitSet, - &SimonEngine::vc45_setSpriteX, - &SimonEngine::vc46_setSpriteY, - &SimonEngine::vc47_addToVar, - &SimonEngine::vc48_setPathFinder, - &SimonEngine::vc49_setBit, - &SimonEngine::vc50_clearBit, - &SimonEngine::vc51_enableBox, - &SimonEngine::vc52_playSound, - &SimonEngine::vc53_panSFX, - &SimonEngine::vc54_no_op, - &SimonEngine::vc55_moveBox, - &SimonEngine::vc56_delay, - &SimonEngine::vc57_blackPalette, - &SimonEngine::vc58, - &SimonEngine::vc59, - &SimonEngine::vc60_killSprite, - &SimonEngine::vc61_setMaskImage, - &SimonEngine::vc62_fastFadeOut, - &SimonEngine::vc63_fastFadeIn, - &SimonEngine::vc64_skipIfSpeechEnded, - &SimonEngine::vc65_slowFadeIn, - &SimonEngine::vc66_skipIfNotEqual, - &SimonEngine::vc67_skipIfGE, - &SimonEngine::vc68_skipIfLE, - &SimonEngine::vc69_playTrack, - &SimonEngine::vc70_queueMusic, - &SimonEngine::vc71_checkMusicQueue, - &SimonEngine::vc72_play_track_2, - &SimonEngine::vc73_setMark, - &SimonEngine::vc74_clearMark, - &SimonEngine::vc75_setScale, - &SimonEngine::vc76_setScaleXOffs, - &SimonEngine::vc77_setScaleYOffs, - &SimonEngine::vc78_computeXY, - &SimonEngine::vc79_computePosNum, - &SimonEngine::vc80_setOverlayImage, - &SimonEngine::vc81_setRandom, - &SimonEngine::vc82_getPathValue, - &SimonEngine::vc83_playSoundLoop, - &SimonEngine::vc84_stopSoundLoop, - }; - - _vga_opcode_table = vga_opcode_table; -} - -// Script parser -void SimonEngine::runVgaScript() { - for (;;) { - uint opcode; - - if (_continousVgaScript) { - if (_vcPtr != (const byte *)&_vc_get_out_of_code) { - printf("%.5d %.5X: %5d %4d ", _vgaTickCounter, (unsigned int)(_vcPtr - _curVgaFile1), _vgaCurSpriteId, _vgaCurZoneNum); - dump_video_script(_vcPtr, true); - } - } - - if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) { - opcode = READ_BE_UINT16(_vcPtr); - _vcPtr += 2; - } else { - opcode = *_vcPtr++; - } - - if (opcode >= _numVideoOpcodes) - error("Invalid VGA opcode '%d' encountered", opcode); - - if (opcode == 0) - return; - - (this->*_vga_opcode_table[opcode]) (); - } -} - -bool SimonEngine::itemIsSiblingOf(uint16 a) { - Item *item; - - CHECK_BOUNDS(a, _objectArray); - - item = _objectArray[a]; - if (item == NULL) - return true; - - return me()->parent == item->parent; -} - -bool SimonEngine::itemIsParentOf(uint16 a, uint16 b) { - Item *item_a, *item_b; - - CHECK_BOUNDS(a, _objectArray); - CHECK_BOUNDS(b, _objectArray); - - item_a = _objectArray[a]; - item_b = _objectArray[b]; - - if (item_a == NULL || item_b == NULL) - return true; - - return derefItem(item_a->parent) == item_b; -} - -bool SimonEngine::vc_maybe_skip_proc_1(uint16 a, int16 b) { - Item *item; - - CHECK_BOUNDS(a, _objectArray); - - item = _objectArray[a]; - if (item == NULL) - return true; - return item->state == b; -} - -VgaSprite *SimonEngine::findCurSprite() { - VgaSprite *vsp = _vgaSprites; - while (vsp->id) { - if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) { - if (vsp->id == _vgaCurSpriteId) - break; - } else { - if (vsp->id == _vgaCurSpriteId && vsp->zoneNum == _vgaCurZoneNum) - break; - } - vsp++; - } - return vsp; -} - -int SimonEngine::vcReadVarOrWord() { - int16 var = vcReadNextWord(); - if (var < 0) - var = vcReadVar(-var); - return var; -} - -uint SimonEngine::vcReadNextWord() { - uint a; - a = readUint16Wrapper(_vcPtr); - _vcPtr += 2; - return a; -} - -uint SimonEngine::vcReadNextByte() { - return *_vcPtr++; -} - -uint SimonEngine::vcReadVar(uint var) { - assert(var < _numVars); - return (uint16)_variableArrayPtr[var]; -} - -void SimonEngine::vcWriteVar(uint var, int16 value) { - assert(var < _numVars); - _variableArrayPtr[var] = value; -} - -void SimonEngine::vcSkipNextInstruction() { - static const byte opcodeParamLenWW[] = { - 0, 6, 2, 10, 6, 4, 2, 2, - 4, 4, 8, 2, 2, 2, 2, 2, - 2, 2, 2, 0, 4, 2, 2, 2, - 8, 0, 10, 0, 8, 0, 2, 2, - 0, 0, 0, 4, 4, 4, 2, 4, - 4, 4, 4, 2, 2, 4, 2, 2, - 2, 2, 2, 2, 2, 4, 6, 6, - 0, 0, 0, 0, 2, 2, 0, 0, - }; - - static const byte opcodeParamLenSimon1[] = { - 0, 6, 2, 10, 6, 4, 2, 2, - 4, 4, 10, 0, 2, 2, 2, 2, - 2, 0, 2, 0, 4, 2, 4, 2, - 8, 0, 10, 0, 8, 0, 2, 2, - 4, 0, 0, 4, 4, 2, 2, 4, - 4, 4, 4, 2, 2, 2, 2, 4, - 0, 2, 2, 2, 2, 4, 6, 6, - 0, 0, 0, 0, 2, 6, 0, 0, - }; - - static const byte opcodeParamLenSimon2[] = { - 0, 6, 2, 12, 6, 4, 2, 2, - 4, 4, 9, 0, 1, 2, 2, 2, - 2, 0, 2, 0, 4, 2, 4, 2, - 7, 0, 10, 0, 8, 0, 2, 2, - 4, 0, 0, 4, 4, 2, 2, 4, - 4, 4, 4, 2, 2, 2, 2, 4, - 0, 2, 2, 2, 2, 4, 6, 6, - 2, 0, 6, 6, 4, 6, 0, 0, - 0, 0, 4, 4, 4, 4, 4, 0, - 4, 2, 2 - }; - - static const byte opcodeParamLenFeebleFiles[] = { - 0, 6, 2, 12, 6, 4, 2, 2, - 4, 4, 9, 0, 1, 2, 2, 2, - 2, 0, 2, 0, 4, 2, 4, 2, - 7, 0, 10, 0, 8, 0, 2, 2, - 4, 0, 0, 4, 4, 2, 2, 4, - 4, 4, 4, 2, 2, 2, 2, 4, - 0, 2, 2, 2, 6, 6, 6, 6, - 2, 0, 6, 6, 4, 6, 0, 0, - 0, 0, 4, 4, 4, 4, 4, 0, - 4, 2, 2, 4, 6, 6, 0, 0, - 6, 4, 2, 6, 0 - }; - - uint16 opcode; - if (getGameType() == GType_FF || getGameType() == GType_PP) { - opcode = vcReadNextByte(); - _vcPtr += opcodeParamLenFeebleFiles[opcode]; - } else if (getGameType() == GType_SIMON2) { - opcode = vcReadNextByte(); - _vcPtr += opcodeParamLenSimon2[opcode]; - } else if (getGameType() == GType_SIMON1) { - opcode = vcReadNextWord(); - _vcPtr += opcodeParamLenSimon1[opcode]; - } else { - opcode = vcReadNextWord(); - _vcPtr += opcodeParamLenWW[opcode]; - } - - if (_continousVgaScript) - printf("; skipped\n"); -} - -// VGA Script commands -void SimonEngine::vc1_fadeOut() { - /* dummy opcode */ - _vcPtr += 6; -} - -void SimonEngine::vc2_call() { - VgaPointersEntry *vpe; - uint16 count, num, res; - byte *old_file_1, *old_file_2; - byte *b, *bb; - const byte *vcPtrOrg; - - num = vcReadVarOrWord(); - - old_file_1 = _curVgaFile1; - old_file_2 = _curVgaFile2; - - for (;;) { - res = num / 100; - vpe = &_vgaBufferPointers[res]; - - _curVgaFile1 = vpe->vgaFile1; - _curVgaFile2 = vpe->vgaFile2; - if (vpe->vgaFile1 != NULL) - break; - if (_zoneNumber != res) - _noOverWrite = _zoneNumber; - - loadZone(res); - _noOverWrite = 0xFFFF; - } - - - bb = _curVgaFile1; - if (getGameType() == GType_FF || getGameType() == GType_PP) { - b = bb + READ_LE_UINT16(&((VgaFileHeader_Feeble *) bb)->hdr2_start); - 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) == num) - break; - b += sizeof(ImageHeader_Feeble); - } - assert(READ_LE_UINT16(&((ImageHeader_Feeble *) b)->id) == num); - } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - b = bb + READ_BE_UINT16(&((VgaFileHeader_Simon *) bb)->hdr2_start); - count = READ_BE_UINT16(&((VgaFileHeader2_Simon *) b)->imageCount); - b = bb + READ_BE_UINT16(&((VgaFileHeader2_Simon *) b)->imageTable); - - while (count--) { - if (READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == num) - break; - b += sizeof(ImageHeader_Simon); - } - assert(READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == num); - } else { - b = bb + READ_BE_UINT16(bb + 10); - b += 20; - - count = READ_BE_UINT16(&((VgaFileHeader2_WW *) b)->imageCount); - b = bb + READ_BE_UINT16(&((VgaFileHeader2_WW *) b)->imageTable); - - while (count--) { - if (READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == num) - break; - b += sizeof(ImageHeader_WW); - } - assert(READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == num); - } - - vcPtrOrg = _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); - } - - //dump_vga_script(_vcPtr, res, num); - runVgaScript(); - - _curVgaFile1 = old_file_1; - _curVgaFile2 = old_file_2; - - _vcPtr = vcPtrOrg; -} - -void SimonEngine::vc3_loadSprite() { - uint16 windowNum, zoneNum, palette, x, y, vgaSpriteId; - uint16 count, res; - VgaSprite *vsp; - VgaPointersEntry *vpe; - byte *p, *pp; - byte *old_file_1; - - windowNum = vcReadNextWord(); /* 0 */ - - if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) { - vgaSpriteId = vcReadNextWord(); /* 2 */ - zoneNum = vgaSpriteId / 100; - } else { - zoneNum = vcReadNextWord(); /* 0 */ - vgaSpriteId = vcReadNextWord(); /* 2 */ - } - - x = vcReadNextWord(); /* 4 */ - y = vcReadNextWord(); /* 6 */ - palette = vcReadNextWord(); /* 8 */ - - if (isSpriteLoaded(vgaSpriteId, zoneNum)) - return; - - vsp = _vgaSprites; - while (vsp->id) - vsp++; - - if (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(&((VgaFileHeader_Feeble *) pp)->hdr2_start); - 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(&((VgaFileHeader_Simon *) pp)->hdr2_start); - count = READ_BE_UINT16(&((VgaFileHeader2_Simon *) p)->animationCount); - p = pp + READ_BE_UINT16(&((VgaFileHeader2_Simon *) 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_WW *) p)->animationCount); - p = pp + READ_BE_UINT16(&((VgaFileHeader2_WW *) 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); - } - - _curVgaFile1 = old_file_1; -} - -void SimonEngine::vc4_fadeIn() { - /* dummy opcode */ - _vcPtr += 6; -} - -void SimonEngine::vc5_skip_if_neq() { - uint16 var = vcReadNextWord(); - uint16 value = vcReadNextWord(); - if (vcReadVar(var) != value) - vcSkipNextInstruction(); -} - -void SimonEngine::vc6_skip_ifn_sib_with_a() { - if (!itemIsSiblingOf(vcReadNextWord())) - vcSkipNextInstruction(); -} - -void SimonEngine::vc7_skip_if_sib_with_a() { - if (itemIsSiblingOf(vcReadNextWord())) - vcSkipNextInstruction(); -} - -void SimonEngine::vc8_skip_if_parent_is() { - uint16 a = vcReadNextWord(); - uint16 b = vcReadNextWord(); - if (!itemIsParentOf(a, b)) - vcSkipNextInstruction(); -} - -void SimonEngine::vc9_skip_if_unk3_is() { - uint16 a = vcReadNextWord(); - uint16 b = vcReadNextWord(); - if (!vc_maybe_skip_proc_1(a, b)) - 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 *SimonEngine::vc10_uncompressFlip(const byte *src, uint w, uint h) { - w *= 8; - - byte *src_org, *dst_org; - byte color; - int8 cur = -0x80; - uint i, w_cur = w; - - dst_org = _videoBuf1 + w; - - do { - byte *dst = dst_org; - uint h_cur = h; - - if (cur == -0x80) - cur = *src++; - - for (;;) { - if (cur >= 0) { - /* rle_same */ - color = *src++; - do { - *dst = color; - dst += w; - if (!--h_cur) { - if (--cur < 0) - cur = -0x80; - else - src--; - goto next_line; - } - } while (--cur >= 0); - } else { - /* rle_diff */ - do { - *dst = *src++; - dst += w; - if (!--h_cur) { - if (++cur == 0) - cur = -0x80; - goto next_line; - } - } while (++cur != 0); - } - cur = *src++; - } - next_line: - dst_org++; - } while (--w_cur); - - - src_org = dst_org = _videoBuf1 + w; - - do { - byte *dst = dst_org; - for (i = 0; i != w; ++i) { - byte b = src_org[i]; - b = (b >> 4) | (b << 4); - *--dst = b; - } - - src_org += w; - dst_org += w; - } while (--h); - - return _videoBuf1; -} - -byte *SimonEngine::vc10_flip(const byte *src, uint w, uint h) { - if (src == _vc10BasePtrOld) - return _videoBuf1; - - _vc10BasePtrOld = src; - - byte *dst_org, *src_org; - uint i; - - w *= 8; - src_org = dst_org = _videoBuf1 + w; - - do { - byte *dst = dst_org; - for (i = 0; i != w; ++i) { - byte b = src_org[i]; - b = (b >> 4) | (b << 4); - *--dst = b; - } - - src_org += w; - dst_org += w; - } while (--h); - - return _videoBuf1; -} - -/* must not be const */ -static uint16 _video_windows[128] = { - 0, 0, 20, 200, - 0, 0, 3, 136, - 17, 0, 3, 136, - 0, 0, 20, 200, - 0, 0, 20, 134 -}; - -/* Elvira 1/2 & Waxworks -static uint16 _video_windows[128] = { - 3, 0, 14, 136, - 0, 0, 3, 136, - 17, 0, 3, 136, - 0, 0, 20, 200, - 3, 3, 14, 127, -}; - */ - -void SimonEngine::decodeColumn(byte *dst, const byte *src, int height) { - const uint pitch = _dxSurfacePitch; - int8 reps = (int8)0x80; - byte color; - byte *dst_org = 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 = ++dst_org; - h = height; - } - } while (--reps >= 0); - } else { - - do { - *dst = *src++; - dst += pitch; - - /* reached bottom? */ - if (--h == 0) { - /* reached right edge? */ - if (--w == 0) - return; - dst = ++dst_org; - h = height; - } - } while (++reps != 0); - } - } -} - -void SimonEngine::decodeRow(byte *dst, const byte *src, int width) { - const uint pitch = _dxSurfacePitch; - int8 reps = (int8)0x80; - byte color; - byte *dst_org = 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; - dst_org += pitch; - dst = dst_org; - w = width; - } - } while (--reps >= 0); - } else { - - do { - *dst++ = *src++; - - /* reached right edge? */ - if (--w == 0) { - /* reached bottom? */ - if (--h == 0) - return; - dst_org += pitch; - dst = dst_org; - w = width; - } - } while (++reps != 0); - } - } -} - -void SimonEngine::vc10_draw() { - byte *p2; - uint width, height; - byte flags; - VC10_state state; - - state.image = (int16)vcReadNextWord(); - if (state.image == 0) - return; - - if (getGameType() == GType_FF || getGameType() == GType_PP) { - state.palette = (_vcPtr[0] * 16); - _vcPtr += 2; - } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - state.palette = (_vcPtr[1] * 16); - _vcPtr += 2; - } else { - state.palette = 0; - } - - state.x = (int16)vcReadNextWord(); - state.x -= _scrollX; - - state.y = (int16)vcReadNextWord(); - state.y -= _scrollY; - - if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) { - state.flags = vcReadNextWord(); - } else { - state.flags = vcReadNextByte(); - } - - if (state.image < 0) - state.image = vcReadVar(-state.image); - - p2 = _curVgaFile2 + state.image * 8; - state.depack_src = _curVgaFile2 + readUint32Wrapper(p2); - if (getGameType() == GType_FF || getGameType() == GType_PP) { - width = READ_LE_UINT16(p2 + 6); - height = READ_LE_UINT16(p2 + 4) & 0x7FFF; - flags = p2[5]; - } else { - width = READ_BE_UINT16(p2 + 6) / 16; - height = p2[5]; - flags = p2[4]; - } - - if (height == 0 || width == 0) - return; - - if (_dumpImages) - dump_single_bitmap(_vgaCurZoneNum, state.image, state.depack_src, width, height, - state.palette); - // Check if image is compressed - if (getGameType() == GType_FF || getGameType() == GType_PP) { - if (flags & 0x80) { - state.flags |= kDFCompressed; - } - } else { - if (flags & 0x80 && !(state.flags & kDFCompressedFlip)) { - if (state.flags & kDFFlip) { - state.flags &= ~kDFFlip; - state.flags |= kDFCompressedFlip; - } else { - state.flags |= kDFCompressed; - } - } - } - - state.width = state.draw_width = width; /* cl */ - state.height = state.draw_height = height; /* ch */ - - state.depack_cont = -0x80; - - state.x_skip = 0; /* colums to skip = bh */ - state.y_skip = 0; /* rows to skip = bl */ - - uint maxWidth = (getGameType() == GType_FF || getGameType() == GType_PP) ? 640 : 20; - if ((getGameType() == GType_SIMON2 || getGameType() == GType_FF) && width > maxWidth) { - horizontalScroll(&state); - return; - } - if (getGameType() == GType_FF && height > 480) { - verticalScroll(&state); - return; - } - - if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2 || getGameType() == GType_WW) { - if (state.flags & kDFCompressedFlip) { - state.depack_src = vc10_uncompressFlip(state.depack_src, width, height); - } else if (state.flags & kDFFlip) { - state.depack_src = vc10_flip(state.depack_src, width, height); - } - } - - state.surf2_addr = getFrontBuf(); - state.surf2_pitch = _dxSurfacePitch; - - state.surf_addr = getBackBuf(); - state.surf_pitch = _dxSurfacePitch; - - if (getGameType() == GType_FF || getGameType() == GType_PP) { - drawImages_Feeble(&state); - } else { - drawImages(&state); - } -} - -bool SimonEngine::drawImages_clip(VC10_state *state) { - const uint16 *vlut; - uint maxWidth, maxHeight; - int cur; - - vlut = &_video_windows[_windowNum * 4]; - - if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2 || getGameType() == GType_WW) { - 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_SIMON1 || getGameType() == GType_SIMON2 || getGameType() == GType_WW) { - state->draw_width *= 4; - } - - return 1; -} - -void SimonEngine::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, *dst_org; - - state->dl = state->width; - state->dh = state->height; - - dst_org = state->surf_addr; - w = 0; - do { - src = vc10_depackColumn(state); - dst = dst_org; - - h = 0; - do { - *dst = *src; - dst += _screenWidth; - src++; - } while (++h != state->draw_height); - dst_org++; - } 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, *dst_org; - - state->dl = state->width; - state->dh = state->height; - - dst_org = state->surf_addr; - w = 0; - do { - byte color; - - src = vc10_depackColumn(state); - dst = dst_org; - - h = 0; - do { - color = *src; - if (color != 0) - *dst = color; - dst += _screenWidth; - src++; - } while (++h != state->draw_height); - dst_org++; - } 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, *dst_org; - - 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; - } - - dst_org = state->surf_addr; - w = 0; - do { - byte color; - - src = vc10_depackColumn(state); - dst = dst_org; - - h = 0; - do { - color = *src; - if (color) - *dst = color; - dst += _screenWidth; - src++; - } while (++h != state->draw_height); - dst_org++; - } while (++w != state->draw_width); - } else { - dst_org = state->surf_addr; - w = 0; - do { - byte color; - - src = vc10_depackColumn(state); - dst = dst_org; - - h = 0; - do { - color = *src; - if ((state->flags & kDFNonTrans) || color != 0) - *dst = color; - dst += _screenWidth; - src++; - } while (++h != state->draw_height); - dst_org++; - } 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 SimonEngine::drawImages(VC10_state *state) { - const uint16 *vlut = &_video_windows[_windowNum * 4]; - - if (drawImages_clip(state) == 0) - return; - - uint offs, offs2; - // Allow one section of Simon the Sorcerer 1 introduction to be displayed - // in lower half of screen - if (getGameType() == GType_WW) { - //if (_windowNum == 4 || _windowNum >= 10) { - offs = state->x * 8; - offs2 = state->y; - //} else { - // offs = ((vlut[0] - _video_windows[16]) * 2 + state->x) * 8; - // offs2 = (vlut[1] - _video_windows[17] + state->y); - //} - } else if (getGameType() == GType_SIMON1) { - if (_windowNum != 2 || _windowNum != 3) { - offs = ((vlut[0]) * 2 + state->x) * 8; - offs2 = (vlut[1] + state->y); - } else { - offs = ((vlut[0] - _video_windows[16]) * 2 + state->x) * 8; - offs2 = (vlut[1] - _video_windows[17] + state->y); - } - } else { - offs = ((vlut[0] - _video_windows[16]) * 2 + state->x) * 8; - offs2 = (vlut[1] - _video_windows[17] + state->y); - } - - state->surf2_addr += offs + offs2 * state->surf2_pitch; - state->surf_addr += offs + offs2 * state->surf_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); - - /* vc10_helper_5 */ - } else if ((((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) && - getGameType() != GType_WW) { - const byte *src; - byte *dst; - uint h, i; - - if (state->flags & kDFCompressed) { - byte *dst_org = 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 = dst_org; - 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); - dst_org += _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); - } - /* vc10_helper_4 */ - } else { - if (getGameType() == GType_SIMON2 && state->flags & kDFUseFrontBuf && getBitFlag(171)) { - state->surf_addr = state->surf2_addr; - state->surf_pitch = state->surf2_pitch; - } - - if (state->flags & kDFCompressed) { - uint w, h; - byte *src, *dst, *dst_org; - - state->x_skip *= 4; /* reached */ - - state->dl = state->width; - state->dh = state->height; - - vc10_skip_cols(state); - - dst_org = state->surf_addr; - if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */ - dst_org += vcReadVar(252); - } - w = 0; - do { - byte color; - - src = vc10_depackColumn(state); - dst = dst_org; - - 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); - dst_org += 2; - } while (++w != state->draw_width); - /* vc10_helper_6 */ - } 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); - /* vc10_helper_7 */ - } - } -} - -void SimonEngine::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 SimonEngine::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 SimonEngine::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 SimonEngine::vc11_clearPathFinder() { - if (getGameType() == GType_WW) { - // FIXME - vcReadNextWord(); - } else { - memset(&_pathFindArray, 0, sizeof(_pathFindArray)); - } -} - -void SimonEngine::vc12_delay() { - VgaSprite *vsp = findCurSprite(); - uint16 num; - - if (getGameType() == GType_FF || getGameType() == GType_PP) { - num = vcReadNextByte(); - } else if (getGameType() == GType_SIMON2) { - num = vcReadNextByte() * _frameRate; - } else { - num = vcReadVarOrWord(); - } - - // Work around to allow inventory arrows to be - // shown in some versions of Simon the Sorcerer 1 - if ((getGameType() == GType_SIMON1) && vsp->id == 128) - num = 0; - else - num += _vgaBaseDelay; - - addVgaEvent(num, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum); - _vcPtr = (byte *)&_vc_get_out_of_code; -} - -void SimonEngine::vc13_addToSpriteX() { - VgaSprite *vsp = findCurSprite(); - vsp->x += (int16)vcReadNextWord(); - _vgaSpriteChanged++; -} - -void SimonEngine::vc14_addToSpriteY() { - VgaSprite *vsp = findCurSprite(); - vsp->y += (int16)vcReadNextWord(); - _vgaSpriteChanged++; -} - -void SimonEngine::vc15_sync() { - VgaSleepStruct *vfs = _vgaSleepStructs, *vfs_tmp; - uint16 id = vcReadNextWord(); - while (vfs->ident != 0) { - if (vfs->ident == id) { - addVgaEvent(_vgaBaseDelay, vfs->code_ptr, vfs->sprite_id, vfs->cur_vga_file); - vfs_tmp = vfs; - do { - memcpy(vfs_tmp, vfs_tmp + 1, sizeof(VgaSleepStruct)); - vfs_tmp++; - } while (vfs_tmp->ident != 0); - } else { - vfs++; - } - } - - _lastVgaWaitFor = id; - /* clear a wait event */ - if (id == _vgaWaitFor) - _vgaWaitFor = 0; -} - -void SimonEngine::vc16_waitSync() { - VgaSleepStruct *vfs = _vgaSleepStructs; - while (vfs->ident) - vfs++; - - vfs->ident = vcReadNextWord(); - vfs->code_ptr = _vcPtr; - vfs->sprite_id = _vgaCurSpriteId; - vfs->cur_vga_file = _vgaCurZoneNum; - - _vcPtr = (byte *)&_vc_get_out_of_code; -} - -void SimonEngine::vc17_setPathfinderItem() { - if (getGameType() == GType_WW) { - // FIXME - vcReadNextWord(); - } else { - 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 SimonEngine::vc18_jump() { - int16 offs = vcReadNextWord(); - _vcPtr += offs; -} - -/* chain to script? */ -void SimonEngine::vc19_chain_to_script() { - /* unused */ - error("vc19_chain_to_script: not implemented"); -} - -/* helper routines */ - -void SimonEngine::vc20_setRepeat() { - /* FIXME: This opcode is somewhat strange: it first reads a BE word from - * the script (advancing the script pointer in doing so); then it writes - * back the same word, this time as LE, into the script. - */ - uint16 a = vcReadNextWord(); - WRITE_LE_UINT16(const_cast<byte *>(_vcPtr), a); - _vcPtr += 2; -} - -void SimonEngine::vc21_endRepeat() { - int16 a = vcReadNextWord(); - const byte *tmp = _vcPtr + a; - if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) - tmp += 4; - else - tmp += 3; - - uint16 val = READ_LE_UINT16(tmp); - if (val != 0) { - // Decrement counter - WRITE_LE_UINT16(const_cast<byte *>(tmp), val - 1); - _vcPtr = tmp + 2; - } -} - -void SimonEngine::vc22_setSpritePalette() { - byte *offs, *palptr, *src; - uint16 a, b, num, palSize; - - if (getGameType() != GType_WW) - a = vcReadNextWord(); - b = vcReadNextWord(); - - if (getGameType() == GType_FF || getGameType() == GType_PP) { - num = 256; - palSize = 768; - - palptr = _displayPalette; - offs = _curVgaFile1 + 6; - } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - num = a == 0 ? 32 : 16; - palSize = 96; - - palptr = &_displayPalette[(a * 64)]; - offs = _curVgaFile1 + 6; - } else { - num = 16; - palSize = 32; - palptr = _displayPalette; - offs = _curVgaFile1 + READ_BE_UINT16(_curVgaFile1 + 6); - } - - src = offs + b * palSize; - - do { - if (getGameType() == GType_WW) { - uint16 color = READ_BE_UINT16(src); - palptr[2] = ((color & 0x00f) >> 0) * 32; - palptr[1] = ((color & 0x0f0) >> 4) * 32; - palptr[0] = ((color & 0xf00) >> 8) * 32; - } else { - palptr[0] = src[0] * 4; - palptr[1] = src[1] * 4; - palptr[2] = src[2] * 4; - } - palptr[3] = 0; - - palptr += 4; - src += (getGameType() == GType_WW) ? 2 : 3; - } while (--num); - - _paletteFlag = 2; - _vgaSpriteChanged++; -} - -void SimonEngine::vc23_setSpritePriority() { - VgaSprite *vsp = findCurSprite(), *vus2; - uint16 pri = vcReadNextWord(); - VgaSprite bak; - - if (vsp->id == 0) - return; - - memcpy(&bak, vsp, sizeof(bak)); - bak.priority = pri; - bak.windowNum |= 0x8000; - - vus2 = vsp; - - if (vsp != _vgaSprites && pri < vsp[-1].priority) { - do { - vsp--; - } while (vsp != _vgaSprites && pri < vsp[-1].priority); - do { - memcpy(vus2, vus2 - 1, sizeof(VgaSprite)); - } while (--vus2 != vsp); - memcpy(vus2, &bak, sizeof(VgaSprite)); - } else if (vsp[1].id != 0 && pri >= vsp[1].priority) { - do { - vsp++; - } while (vsp[1].id != 0 && pri >= vsp[1].priority); - do { - memcpy(vus2, vus2 + 1, sizeof(VgaSprite)); - } while (++vus2 != vsp); - memcpy(vus2, &bak, sizeof(VgaSprite)); - } else { - vsp->priority = pri; - } - _vgaSpriteChanged++; -} - -void SimonEngine::vc24_setSpriteXY() { - VgaSprite *vsp = findCurSprite(); - vsp->image = vcReadVarOrWord(); - - vsp->x += (int16)vcReadNextWord(); - vsp->y += (int16)vcReadNextWord(); - if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) { - vsp->flags = vcReadNextWord(); - } else { - vsp->flags = vcReadNextByte(); - } - - _vgaSpriteChanged++; -} - -void SimonEngine::vc25_halt_sprite() { - VgaSprite *vsp = findCurSprite(); - while (vsp->id != 0) { - memcpy(vsp, vsp + 1, sizeof(VgaSprite)); - vsp++; - } - _vcPtr = (byte *)&_vc_get_out_of_code; - _vgaSpriteChanged++; -} - -void SimonEngine::vc26_setSubWindow() { - uint16 *as = &_video_windows[vcReadNextWord() * 4]; // number - as[0] = vcReadNextWord(); // x - as[1] = vcReadNextWord(); // y - as[2] = vcReadNextWord(); // width - as[3] = vcReadNextWord(); // height -} - -void SimonEngine::vc27_resetSprite() { - VgaSprite bak, *vsp; - VgaSleepStruct *vfs; - VgaTimerEntry *vte, *vte2; - - _lockWord |= 8; - - _lastVgaWaitFor = 0; - - memset(&bak, 0, sizeof(bak)); - - vsp = _vgaSprites; - while (vsp->id) { - if ((getGameType() == GType_SIMON1) && vsp->id == 128) { - memcpy(&bak, vsp, sizeof(VgaSprite)); - } - vsp->id = 0; - vsp++; - } - - if (bak.id != 0) - memcpy(_vgaSprites, &bak, sizeof(VgaSprite)); - - vfs = _vgaSleepStructs; - while (vfs->ident) { - vfs->ident = 0; - vfs++; - } - - vte = _vgaTimerList; - while (vte->delay) { - if ((getGameType() == GType_SIMON1) && vte->sprite_id == 128) { - vte++; - } else { - vte2 = vte; - while (vte2->delay) { - memcpy(vte2, vte2 + 1, sizeof(VgaTimerEntry)); - vte2++; - } - } - } - - vcWriteVar(254, 0); - - if (getGameType() == GType_FF) - setBitFlag(42, true); - - _lockWord &= ~8; -} - -void SimonEngine::vc28_dummy_op() { - /* unused */ - _vcPtr += 8; -} - -void SimonEngine::vc29_stopAllSounds() { - if (getGameType() != GType_PP) - _sound->stopVoice(); - - _sound->stopAllSfx(); -} - -void SimonEngine::vc30_setFrameRate() { - _frameRate = vcReadNextWord(); -} - -void SimonEngine::vc31_setWindow() { - _windowNum = vcReadNextWord(); -} - -void SimonEngine::vc32_copyVar() { - if (getGameType() == GType_WW) { - // FIXME - } else { - uint16 a = vcReadVar(vcReadNextWord()); - vcWriteVar(vcReadNextWord(), a); - } -} - -void SimonEngine::vc33_setMouseOn() { - if (_mouseHideCount != 0) { - _mouseHideCount = 1; - mouseOn(); - } -} - -void SimonEngine::vc34_setMouseOff() { - mouseOff(); - _mouseHideCount = 200; - _leftButtonDown = 0; -} - -void SimonEngine::vc35_clearWindow() { - /* unused */ - _vcPtr += 4; - _vgaSpriteChanged++; -} - -void SimonEngine::vc36_setWindowImage() { - _updateScreen = false; - uint16 vga_res = vcReadNextWord(); - uint16 windowNum = vcReadNextWord(); - - if (getGameType() == GType_FF || getGameType() == GType_PP) { - _copyPartialMode = 2; - } else if (getGameType() == GType_SIMON2) { - set_video_mode_internal(windowNum, vga_res); - } else if (getGameType() == GType_SIMON1) { - if (windowNum == 16) { - _copyPartialMode = 2; - } else { - set_video_mode_internal(windowNum, vga_res); - } - } -} - -void SimonEngine::vc37_addToSpriteY() { - if (getGameType() == GType_WW) { - // FIXME - vcReadNextWord(); - vcReadNextWord(); - } else { - VgaSprite *vsp = findCurSprite(); - vsp->y += vcReadVar(vcReadNextWord()); - _vgaSpriteChanged++; - } -} - -void SimonEngine::vc38_skipIfVarZero() { - uint16 var = vcReadNextWord(); - if (vcReadVar(var) == 0) - vcSkipNextInstruction(); -} - -void SimonEngine::vc39_setVar() { - uint16 var = vcReadNextWord(); - int16 value = vcReadNextWord(); - vcWriteVar(var, value); -} - -void SimonEngine::vc40() { - uint16 var = vcReadNextWord(); - int16 value = vcReadVar(var) + vcReadNextWord(); - - if ((getGameType() == GType_SIMON2) && var == 15 && !getBitFlag(80)) { - int16 tmp; - - if (_scrollCount != 0) { - if (_scrollCount >= 0) - goto no_scroll; - _scrollCount = 0; - } else { - if (_scrollFlag != 0) - goto no_scroll; - } - - if (value - _scrollX >= 30) { - _scrollCount = 20; - tmp = _scrollXMax - _scrollX; - if (tmp < 20) - _scrollCount = tmp; - addVgaEvent(6, NULL, 0, 0); /* scroll event */ - } - } -no_scroll:; - - vcWriteVar(var, value); -} - -void SimonEngine::vc41() { - uint16 var = vcReadNextWord(); - int16 value = vcReadVar(var) - vcReadNextWord(); - - if ((getGameType() == GType_SIMON2) && var == 15 && !getBitFlag(80)) { - if (_scrollCount != 0) { - if (_scrollCount < 0) - goto no_scroll; - _scrollCount = 0; - } else { - if (_scrollFlag != 0) - goto no_scroll; - } - - if ((uint16)(value - _scrollX) < 11) { - _scrollCount = -20; - if (_scrollX < 20) - _scrollCount = -_scrollX; - addVgaEvent(6, NULL, 0, 0); /* scroll event */ - } - } -no_scroll:; - - vcWriteVar(var, value); -} - -void SimonEngine::vc42_delayIfNotEQ() { - uint16 val = vcReadVar(vcReadNextWord()); - if (val != vcReadNextWord()) { - - addVgaEvent(_frameRate + 1, _vcPtr - 4, _vgaCurSpriteId, _vgaCurZoneNum); - _vcPtr = (byte *)&_vc_get_out_of_code; - } -} - -void SimonEngine::vc43_skipIfBitClear() { - if (!getBitFlag(vcReadNextWord())) { - vcSkipNextInstruction(); - } -} - -void SimonEngine::vc44_skipIfBitSet() { - if (getBitFlag(vcReadNextWord())) { - vcSkipNextInstruction(); - } -} - -void SimonEngine::vc45_setSpriteX() { - if (getGameType() == GType_WW) { - //FIXME - vcReadNextWord(); - vcReadNextWord(); - } else { - VgaSprite *vsp = findCurSprite(); - vsp->x = vcReadVar(vcReadNextWord()); - _vgaSpriteChanged++; - } -} - -void SimonEngine::vc46_setSpriteY() { - VgaSprite *vsp = findCurSprite(); - vsp->y = vcReadVar(vcReadNextWord()); - _vgaSpriteChanged++; -} - -void SimonEngine::vc47_addToVar() { - if (getGameType() == GType_WW) { - //FIXME - vcReadNextWord(); - } else { - uint16 var = vcReadNextWord(); - vcWriteVar(var, vcReadVar(var) + vcReadVar(vcReadNextWord())); - } -} - -void SimonEngine::vc48_setPathFinder() { - uint16 a = (uint16)_variableArrayPtr[12]; - const uint16 *p = _pathFindArray[a - 1]; - - if (getGameType() == GType_WW) { - //FIXME - vcReadNextWord(); - } else 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 SimonEngine::setBitFlag(uint bit, bool value) { - uint16 *bits = &_bitArray[bit / 16]; - *bits = (*bits & ~(1 << (bit & 15))) | (value << (bit & 15)); -} - -bool SimonEngine::getBitFlag(uint bit) { - uint16 *bits = &_bitArray[bit / 16]; - return (*bits & (1 << (bit & 15))) != 0; -} - -void SimonEngine::vc49_setBit() { - uint16 bit = vcReadNextWord(); - if (getGameType() == GType_FF && bit == 82) { - _variableArrayPtr = _variableArray2; - } - setBitFlag(bit, true); -} - -void SimonEngine::vc50_clearBit() { - uint16 bit = vcReadNextWord(); - if (getGameType() == GType_FF && bit == 82) { - _variableArrayPtr = _variableArray; - } - setBitFlag(bit, false); -} - -void SimonEngine::vc51_enableBox() { - enableBox(vcReadNextWord()); -} - -void SimonEngine::vc52_playSound() { - bool ambient = false; - - uint16 sound = vcReadNextWord(); - if (sound >= 0x8000) { - ambient = true; - sound = -sound; - } - - if (getGameType() == GType_FF || getGameType() == GType_PP) { - int16 pan = vcReadNextWord(); - int16 vol = vcReadNextWord(); - - if (ambient) - loadSound(sound, pan, vol, 2); - else - loadSound(sound, pan, vol, 1); - } else if (getGameType() == GType_SIMON2) { - if (ambient) - _sound->playAmbient(sound); - else - _sound->playEffects(sound); - } else if (getFeatures() & GF_TALKIE) { - _sound->playEffects(sound); - } else if (getGameId() == GID_SIMON1DOS) { - playSting(sound); - } -} - -void SimonEngine::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 SimonEngine::vc54_no_op() { - /* unused */ - _vcPtr += 6; -} - -void SimonEngine::vc55_moveBox() { - HitArea *ha = _hitAreas; - uint count = ARRAYSIZE(_hitAreas); - uint16 id = vcReadNextWord(); - int16 x = vcReadNextWord(); - int16 y = vcReadNextWord(); - - for (;;) { - if (ha->id == id) { - ha->x += x; - ha->y += y; - break; - } - ha++; - if (!--count) - break; - } - - _needHitAreaRecalc++; -} - -void SimonEngine::vc56_delay() { - if (getGameType() == GType_WW) { - byte *src = _curVgaFile2 + 32; - byte *dst = getBackBuf(); - - uint8 palette[1024]; - for (int i = 0; i < 256; i++) { - palette[i * 4 + 0] = *src++ * 4; - palette[i * 4 + 1] = *src++ * 4; - palette[i * 4 + 2] = *src++ * 4; - palette[i * 4 + 3] = 0; - } - - _system->setPalette(palette, 0, 256); - memcpy(dst, src, _screenHeight * _screenWidth); - } else { - uint16 num = vcReadVarOrWord() * _frameRate; - - addVgaEvent(num + _vgaBaseDelay, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum); - _vcPtr = (byte *)&_vc_get_out_of_code; - } -} - -void SimonEngine::vc57_blackPalette() { - if (getGameType() == GType_WW) { - uint8 palette[1024]; - memset(palette, 0, sizeof(palette)); - _system->setPalette(palette, 0, 256); - } -} - -void SimonEngine::vc58() { - if (getGameType() == GType_WW) - return; - - uint16 sprite = _vgaCurSpriteId; - uint16 file = _vgaCurZoneNum; - const byte *vcPtrOrg; - uint16 tmp; - - _vgaCurZoneNum = vcReadNextWord(); - _vgaCurSpriteId = vcReadNextWord(); - - tmp = to16Wrapper(vcReadNextWord()); - - vcPtrOrg = _vcPtr; - _vcPtr = (byte *)&tmp; - vc23_setSpritePriority(); - - _vcPtr = vcPtrOrg; - _vgaCurSpriteId = sprite; - _vgaCurZoneNum = file; -} - -void SimonEngine::vc59() { - if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) { - uint16 file = vcReadNextWord(); - uint16 start = vcReadNextWord(); - uint16 end = vcReadNextWord() + 1; - - do { - vc_kill_sprite(file, start); - } while (++start != end); - } else if (getGameType() == GType_SIMON1) { - if (!_sound->isVoiceActive()) - vcSkipNextInstruction(); - } else { - // Skip if not EGA - vcSkipNextInstruction(); - } -} - -void SimonEngine::vc_kill_sprite(uint file, uint sprite) { - uint16 old_sprite_id, old_cur_file_id; - VgaSleepStruct *vfs; - VgaSprite *vsp; - VgaTimerEntry *vte; - const byte *vcPtrOrg; - - old_sprite_id = _vgaCurSpriteId; - old_cur_file_id = _vgaCurZoneNum; - vcPtrOrg = _vcPtr; - - _vgaCurZoneNum = file; - _vgaCurSpriteId = sprite; - - vfs = _vgaSleepStructs; - while (vfs->ident != 0) { - if (vfs->sprite_id == _vgaCurSpriteId && ((getGameType() == GType_SIMON1) || vfs->cur_vga_file == _vgaCurZoneNum)) { - while (vfs->ident != 0) { - memcpy(vfs, vfs + 1, sizeof(VgaSleepStruct)); - vfs++; - } - break; - } - vfs++; - } - - vsp = findCurSprite(); - if (vsp->id) { - vc25_halt_sprite(); - - vte = _vgaTimerList; - while (vte->delay != 0) { - if (vte->sprite_id == _vgaCurSpriteId && ((getGameType() == GType_SIMON1) || vte->cur_vga_file == _vgaCurZoneNum)) { - deleteVgaEvent(vte); - break; - } - vte++; - } - } - - _vgaCurZoneNum = old_cur_file_id; - _vgaCurSpriteId = old_sprite_id; - _vcPtr = vcPtrOrg; -} - -void SimonEngine::vc60_killSprite() { - uint16 zoneNum; - - if (getGameType() == GType_SIMON1) { - zoneNum = _vgaCurZoneNum; - } else { - zoneNum = vcReadNextWord(); - } - uint16 sprite = vcReadNextWord(); - vc_kill_sprite(zoneNum, sprite); -} - -void SimonEngine::vc61_setMaskImage() { - if (getGameType() == GType_WW) { - // FIXME - vcReadVarOrWord(); - } else { - VgaSprite *vsp = findCurSprite(); - - vsp->image = vcReadVarOrWord(); - vsp->x += vcReadNextWord(); - vsp->y += vcReadNextWord(); - vsp->flags = kDFMasked | kDFUseFrontBuf; - - _vgaSpriteChanged++; - } -} - -void SimonEngine::vc62_fastFadeOut() { - vc29_stopAllSounds(); - - if (!_fastFadeOutFlag) { - uint i, fadeSize, fadeCount; - - if (getGameType() != GType_WW) - _fastFadeOutFlag = true; - - _fastFadeCount = 256; - if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - if (_windowNum == 4) - _fastFadeCount = 208; - } - - memcpy(_videoBuf1, _currentPalette, _fastFadeCount * 4); - - if ((getGameType() == GType_FF || getGameType() == GType_PP) && !getBitFlag(75)) { - fadeCount = 32; - fadeSize = 8; - } else { - fadeCount = 4; - fadeSize = 64; - } - - for (i = fadeCount; i != 0; --i) { - paletteFadeOut(_videoBuf1, _fastFadeCount, fadeSize); - _system->setPalette(_videoBuf1, 0, _fastFadeCount); - delay(5); - } - - if (getGameType() == GType_SIMON1) { - uint16 params[5]; /* parameters to vc10_draw */ - VgaSprite *vsp; - VgaPointersEntry *vpe; - const byte *vcPtrOrg = _vcPtr; - - 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; - - params[0] = READ_BE_UINT16(&vsp->image); - params[1] = READ_BE_UINT16(&vsp->palette); - params[2] = READ_BE_UINT16(&vsp->x); - params[3] = READ_BE_UINT16(&vsp->y); - params[4] = READ_BE_UINT16(&vsp->flags); - _vcPtr = (byte *)params; - vc10_draw(); - - _windowNum = palmode; - _curVgaFile1 = old_file_1; - _curVgaFile2 = old_file_2; - break; - } - vsp++; - } - _vcPtr = vcPtrOrg; - } - - // 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)) { - dx_clear_surfaces(200); - } else if (getGameType() == GType_FF || getGameType() == GType_PP) { - dx_clear_surfaces(480); - } else { - dx_clear_surfaces(_windowNum == 4 ? 134 : 200); - } - } - if (getGameType() == GType_SIMON2) { - if (_nextMusicToPlay != -1) - loadMusic(_nextMusicToPlay); - } -} - -void SimonEngine::vc63_fastFadeIn() { - if (getGameType() == GType_FF || getGameType() == GType_PP) { - _fastFadeInFlag = 256; - } else { - _fastFadeInFlag = 208; - if (_windowNum != 4) { - _fastFadeInFlag = 256; - } - } - _fastFadeOutFlag = false; -} - -void SimonEngine::vc64_skipIfSpeechEnded() { - if ((getGameType() == GType_SIMON2 && _subtitles && _language != Common::HB_ISR) || - !_sound->isVoiceActive()) { - vcSkipNextInstruction(); - } -} - -void SimonEngine::vc65_slowFadeIn() { - _fastFadeInFlag = 624; - _fastFadeCount = 208; - if (_windowNum != 4) { - _fastFadeInFlag = 768; - _fastFadeCount = 256; - } - _fastFadeInFlag |= 0x8000; - _fastFadeOutFlag = false; -} - -void SimonEngine::vc66_skipIfNotEqual() { - uint16 a = vcReadNextWord(); - uint16 b = vcReadNextWord(); - - if (vcReadVar(a) != vcReadVar(b)) - vcSkipNextInstruction(); -} - -void SimonEngine::vc67_skipIfGE() { - uint16 a = vcReadNextWord(); - uint16 b = vcReadNextWord(); - - if (vcReadVar(a) >= vcReadVar(b)) - vcSkipNextInstruction(); -} - -void SimonEngine::vc68_skipIfLE() { - uint16 a = vcReadNextWord(); - uint16 b = vcReadNextWord(); - - if (vcReadVar(a) <= vcReadVar(b)) - vcSkipNextInstruction(); -} - -void SimonEngine::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 SimonEngine::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); - else - midi.setLoop(loop != 0); -} - -void SimonEngine::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 SimonEngine::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. - - // 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. - - int16 track = vcReadNextWord(); - int16 loop = vcReadNextWord(); - - if (track == -1 || track == 999) { - midi.stop(); - } else { - midi.setLoop (loop != 0); - midi.startTrack (track); - } -} - -void SimonEngine::vc73_setMark() { - _marks |= (1 << vcReadNextWord()); -} - -void SimonEngine::vc74_clearMark() { - _marks &= ~(1 << vcReadNextWord()); -} - -int SimonEngine::getScale(int16 y, int16 x) { - int16 z; - - 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); - } - - z = ((int16)((x * (1 - ((_baseY - y) * _scale))) + 0.5)); - if (z < 2) - return(2); - - return(z); - } -} - -void SimonEngine::vc75_setScale() { - _baseY = vcReadNextWord(); - _scale = (float)vcReadNextWord() / 1000000.; -} - -void SimonEngine::vc76_setScaleXOffs() { - 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; -} - -void SimonEngine::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 SimonEngine::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; - - uint16 posy = readUint16Wrapper(p + 1); - _variableArrayPtr[16] = posy; - vsp->y = posy; - - setBitFlag(85, false); - if (getBitFlag(74)) { - centreScroll(); - } -} - -void SimonEngine::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++; - } - - _variableArrayPtr[13] = pos; -} - -void SimonEngine::vc80_setOverlayImage() { - VgaSprite *vsp = findCurSprite(); - - vsp->image = vcReadVarOrWord(); - - vsp->x += vcReadNextWord(); - vsp->y += vcReadNextWord(); - vsp->flags = kDFOverlayed; - - _vgaSpriteChanged++; -} - -void SimonEngine::vc81_setRandom() { - uint16 var = vcReadNextWord(); - uint16 value = vcReadNextWord(); - - _variableArray[var] = _rnd.getRandomNumber(value - 1); -} - -void SimonEngine::vc82_getPathValue() { - uint8 val; - - uint16 var = vcReadNextWord(); - - if (getBitFlag(82)) { - val = _pathValues1[_GPVCount1++]; - } else { - val = _pathValues[_GPVCount++]; - } - - vcWriteVar(var, val); -} - -void SimonEngine::vc83_playSoundLoop() { - uint16 sound = vcReadNextWord(); - int16 vol = vcReadNextWord(); - int16 pan = vcReadNextWord(); - - loadSound(sound, pan, vol, 3); -} - -void SimonEngine::vc84_stopSoundLoop() { - _sound->stopSfx5(); -} - -// Scrolling functions for Feeble Files -void SimonEngine::checkScrollX(int16 x, int16 xpos) { - if (_scrollXMax == 0 || getBitFlag(80) || getBitFlag(82) || x == 0) - return; - - int16 tmp; - if (x > 0) { - if (_scrollCount != 0) { - if (_scrollCount >= 0) - return; - _scrollCount = 0; - } else { - if (_scrollFlag != 0) - return; - } - - 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 (xpos - _scrollX < 161) { - _scrollCount = -320; - if (_scrollX < 320) - _scrollCount = -_scrollX; - } - } -} - -void SimonEngine::checkScrollY(int16 y, int16 ypos) { - if (_scrollYMax == 0 || getBitFlag(80)) - return; - - int16 tmp; - if (y >= 0) { - if (_scrollCount != 0) { - if (_scrollCount >= 0) - return; - } else { - if (_scrollFlag != 0) - return; - } - - if (ypos - _scrollY >= 440) { - _scrollCount = 240; - tmp = _scrollYMax - _scrollY; - if (tmp < 240) - _scrollCount = tmp; - } - } else { - if (_scrollCount != 0) { - if (_scrollCount < 0) - return; - } else { - if (_scrollFlag != 0) - return; - } - - if (ypos - _scrollY < 100) { - _scrollCount = -240; - if (_scrollY < 240) - _scrollCount = -_scrollY; - } - } -} - -void SimonEngine::centreScroll() { - int16 x, y, tmp; - - 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; - } - } -} - -} // End of namespace Simon |
