diff options
| author | Max Horn | 2006-02-11 22:45:04 +0000 |
|---|---|---|
| committer | Max Horn | 2006-02-11 22:45:04 +0000 |
| commit | 26ee630756ebdd7c96bccede0881a8c8b98e8f2b (patch) | |
| tree | 26e378d5cf990a2b81c2c96e9e683a7f333b62e8 /simon/vga.cpp | |
| parent | 2a9a0d4211b1ea5723f1409d91cb95de8984429e (diff) | |
| download | scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.gz scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.bz2 scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.zip | |
Moved engines to the new engines/ directory
svn-id: r20582
Diffstat (limited to 'simon/vga.cpp')
| -rw-r--r-- | simon/vga.cpp | 2299 |
1 files changed, 0 insertions, 2299 deletions
diff --git a/simon/vga.cpp b/simon/vga.cpp deleted file mode 100644 index d7d0731539..0000000000 --- a/simon/vga.cpp +++ /dev/null @@ -1,2299 +0,0 @@ -/* ScummVM - Scumm Interpreter - * 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 "simon/simon.h" -#include "simon/intern.h" -#include "simon/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_wakeup_id, - &SimonEngine::vc16_sleep_on_id, - &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_clear_hitarea_bit_0x40, - &SimonEngine::vc52_playSound, - &SimonEngine::vc53_no_op, - &SimonEngine::vc54_no_op, - &SimonEngine::vc55_offset_hit_area, - &SimonEngine::vc56_delay, - &SimonEngine::vc57_no_op, - &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::run_vga_script() { - for (;;) { - uint opcode; - - if (_continousVgaScript) { - if (_vcPtr != (const byte *)&_vc_get_out_of_code) { - fprintf(_dumpFile, "%.5d %.5X: %5d %4d ", _vgaTickCounter, _vcPtr - _curVgaFile1, _vgaCurSpriteId, _vgaCurFileId); - dump_video_script(_vcPtr, true); - } - } - - if (getGameType() == GType_SIMON1) { - opcode = READ_BE_UINT16(_vcPtr); - _vcPtr += 2; - } else { - opcode = *_vcPtr++; - } - - if (opcode >= NUM_VIDEO_OP_CODES) - error("Invalid VGA opcode '%d' encountered", opcode); - - if (opcode == 0) - return; - - (this->*_vga_opcode_table[opcode]) (); - } -} - -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++; -} - -void SimonEngine::vcSkipNextInstruction() { - 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 - }; - - if (getGameType() == GType_FF) { - uint opcode = vcReadNextByte(); - _vcPtr += opcodeParamLenFeebleFiles[opcode]; - } else if (getGameType() == GType_SIMON2) { - uint opcode = vcReadNextByte(); - _vcPtr += opcodeParamLenSimon2[opcode]; - } else { - uint opcode = vcReadNextWord(); - _vcPtr += opcodeParamLenSimon1[opcode]; - } - - if (_continousVgaScript) - fprintf(_dumpFile, "; skipped\n"); -} - -void SimonEngine::o_unloadBeard() { - // Simon1 Only - if (_beardLoaded == true) { - _beardLoaded = false; - _lockWord |= 0x8000; - read_vga_from_datfile_1(23); - _lockWord &= ~0x8000; - } -} - -void SimonEngine::o_loadBeard() { - // Simon1 Only - if (_beardLoaded == false) { - _beardLoaded = true; - _lockWord |= 0x8000; - read_vga_from_datfile_1(328); - _lockWord &= ~0x8000; - } -} - -// VGA Script commands -void SimonEngine::vc1_fadeOut() { - /* dummy opcode */ - _vcPtr += 6; -} - -void SimonEngine::vc2_call() { - VgaPointersEntry *vpe; - uint num; - uint res; - byte *old_file_1, *old_file_2; - byte *b, *bb; - const byte *vc_ptr_org; - - 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 (_vgaCurFile2 != res) - _videoVar7 = _vgaCurFile2; - - loadZone(res); - _videoVar7 = 0xFFFF; - } - - - bb = _curVgaFile1; - if (getGameType() == GType_FF) { - b = bb + READ_LE_UINT16(&((VgaFileHeader_Feeble *) bb)->hdr2_start); - b = bb + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageTable); - - while (READ_LE_UINT16(&((ImageHeader_Feeble *) b)->id) != num) - b += sizeof(ImageHeader_Feeble); - } else { - b = bb + READ_BE_UINT16(&((VgaFileHeader_Simon *) bb)->hdr2_start); - b = bb + READ_BE_UINT16(&((VgaFileHeader2_Simon *) b)->imageTable); - - while (READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) != num) - b += sizeof(ImageHeader_Simon); - } - - vc_ptr_org = _vcPtr; - - if (getGameType() == GType_FF) { - _vcPtr = _curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble *) b)->scriptOffs); - } else { - _vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon *) b)->scriptOffs); - } - - //dump_vga_script(_vcPtr, res, num); - run_vga_script(); - - _curVgaFile1 = old_file_1; - _curVgaFile2 = old_file_2; - - _vcPtr = vc_ptr_org; -} - -void SimonEngine::vc3_loadSprite() { - uint16 windowNum, fileId, palette, x, y, vgaSpriteId; - uint16 res; - VgaSprite *vsp; - VgaPointersEntry *vpe; - byte *p, *pp; - byte *old_file_1; - - windowNum = vcReadNextWord(); /* 0 */ - - if (getGameType() == GType_SIMON1) { - vgaSpriteId = vcReadNextWord(); /* 2 */ - fileId = vgaSpriteId / 100; - } else { - fileId = vcReadNextWord(); /* 0 */ - vgaSpriteId = vcReadNextWord(); /* 2 */ - } - - x = vcReadNextWord(); /* 4 */ - y = vcReadNextWord(); /* 6 */ - palette = vcReadNextWord(); /* 8 */ - - /* 2nd param ignored with simon1 */ - if (isSpriteLoaded(vgaSpriteId, fileId)) - return; - - vsp = _vgaSprites; - while (vsp->id) - vsp++; - - 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->fileId = res = fileId; - - old_file_1 = _curVgaFile1; - for (;;) { - vpe = &_vgaBufferPointers[res]; - _curVgaFile1 = vpe->vgaFile1; - - if (vpe->vgaFile1 != NULL) - break; - if (_vgaCurFile2 != res) - _videoVar7 = _vgaCurFile2; - - loadZone(res); - _videoVar7 = 0xFFFF; - } - - pp = _curVgaFile1; - if (getGameType() == GType_FF) { - p = pp + READ_LE_UINT16(&((VgaFileHeader_Feeble *) pp)->hdr2_start); - p = pp + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationTable); - - while (READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) != vgaSpriteId) - p += sizeof(AnimationHeader_Feeble); - } else { - p = pp + READ_BE_UINT16(&((VgaFileHeader_Simon *) pp)->hdr2_start); - p = pp + READ_BE_UINT16(&((VgaFileHeader2_Simon *) p)->animationTable); - - while (READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) != vgaSpriteId) - p += sizeof(AnimationHeader_Simon); - } - -#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) { - dump_vga_script(_curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), res, vgaSpriteId); - } else { - dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon*)p)->scriptOffs), res, vgaSpriteId); - - } - } - - if (getGameType() == GType_FF) { - add_vga_timer(VGA_DELAY_BASE, _curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->scriptOffs), vgaSpriteId, res); - } else { - add_vga_timer(VGA_DELAY_BASE, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon *) p)->scriptOffs), vgaSpriteId, res); - } - - _curVgaFile1 = old_file_1; -} - -void SimonEngine::vc4_fadeIn() { - /* dummy opcode */ - _vcPtr += 6; -} - -void SimonEngine::vc5_skip_if_neq() { - uint var = vcReadNextWord(); - uint 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() { - uint a = vcReadNextWord(); - uint b = vcReadNextWord(); - if (!itemIsParentOf(a, b)) - vcSkipNextInstruction(); -} - -void SimonEngine::vc9_skip_if_unk3_is() { - uint a = vcReadNextWord(); - uint b = vcReadNextWord(); - if (!vc_maybe_skip_proc_1(a, b)) - vcSkipNextInstruction(); -} - -byte *vc10_depack_column(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) { - vs->depack_cont = -0x80; - while (vs->x_skip) { - vc10_depack_column(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 -}; - -/* simon2 specific */ -void SimonEngine::decodeStripA(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::vc10_draw() { - byte *p2; - uint width, height; - uint maxWidth, maxHeight; - byte flags; - const uint16 *vlut; - VC10_state state; - - int cur; - - state.image = (int16)vcReadNextWord(); - if (state.image == 0) - return; - - if (getGameType() == GType_FF) { - state.palette = (_vcPtr[0] * 16); - } else { - state.palette = (_vcPtr[1] * 16); - } - _vcPtr += 2; - state.x = (int16)vcReadNextWord(); - - if (getGameType() == GType_SIMON2) { - state.x -= _scrollX; - } - state.y = (int16)vcReadNextWord(); - - if (getGameType() == GType_SIMON1) { - state.flags = vcReadNextWord(); - } else { - state.flags = vcReadNextByte(); - } - - if (state.image < 0) - state.image = vcReadVar(-state.image); - - debug(1, "vc10_draw: image %d palette %d x %d y %d flags 0x0%x\n", state.image, state.palette, state.x, state.y, state.flags); - - p2 = _curVgaFile2 + state.image * 8; - if (getGameType() == GType_FF) { - state.depack_src = _curVgaFile2 + READ_LE_UINT32(p2); - width = READ_LE_UINT16(p2 + 6); - height = READ_LE_UINT16(p2 + 4) & 0x7FFF; - flags = p2[5]; - - debug(1, "Width %d Height %d Flags 0x%x", width, height, flags); - } else { - state.depack_src = _curVgaFile2 + READ_BE_UINT32(p2); - width = READ_BE_UINT16(p2 + 6) / 16; - height = p2[5]; - flags = p2[4]; - } - - if (height == 0 || width == 0) - return; - - if (_dumpImages) - dump_single_bitmap(_vgaCurFileId, state.image, state.depack_src, width * 16, height, - state.palette); - // TODO::Add support for image overlay and scaling in Feeble Files - - if (flags & 0x80 && !(state.flags & 0x10)) { - if (state.flags & 1) { - state.flags &= ~1; - state.flags |= 0x10; - } else { - state.flags |= 0x8; - } - } - - if (getGameType() == GType_FF) { - if (width > 640) { - debug(0, "Horizontal scrolling not supported"); - return; - } - if (height > 480) { - debug(0, "Vertical scrolling not supported"); - return; - } - } - if (getGameType() == GType_SIMON2 && width > 20) { - const byte *src; - byte *dst; - uint w; - - _scrollXMax = width * 2 - 40; - _scrollImage = state.depack_src; - _scrollHeight = height; - if (_variableArray[34] == -1) - state.x = _variableArray[251]; - - _scrollX = state.x; - - vcWriteVar(251, _scrollX); - - dst = dx_lock_attached(); - src = state.depack_src + _scrollX * 4; - - for (w = 0; w < 40; w++) { - decodeStripA(dst, src + READ_BE_UINT32(src), height); - dst += 8; - src += 4; - } - - dx_unlock_attached(); - - return; - } - - if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - if (state.flags & 0x10) { - state.depack_src = vc10_uncompressFlip(state.depack_src, width, height); - } else if (state.flags & 1) { - state.depack_src = vc10_flip(state.depack_src, width, height); - } - } - - vlut = &_video_windows[_windowNum * 4]; - - state.width = state.draw_width = width; /* cl */ - state.height = state.draw_height = height; /* ch */ - - if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - state.draw_width = width * 2; - } - - state.x_skip = 0; /* colums to skip = bh */ - state.y_skip = 0; /* rows to skip = bl */ - - cur = state.x; - if (cur < 0) { - do { - if (!--state.draw_width) - return; - state.x_skip++; - } while (++cur); - } - state.x = cur; - - maxWidth = (getGameType() == GType_FF) ? 640 : (vlut[2] * 2); - cur += state.draw_width - maxWidth; - if (cur > 0) { - do { - if (!--state.draw_width) - return; - } while (--cur); - } - - cur = state.y; - if (cur < 0) { - do { - if (!--state.draw_height) - return; - state.y_skip++; - } while (++cur); - } - state.y = cur; - - maxHeight = (getGameType() == GType_FF) ? 480 : vlut[3]; - cur += state.draw_height - maxHeight; - if (cur > 0) { - do { - if (!--state.draw_height) - return; - } while (--cur); - } - - assert(state.draw_width != 0 && state.draw_height != 0); - - if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - state.draw_width *= 4; - } - - state.surf2_addr = dx_lock_2(); - state.surf2_pitch = _dxSurfacePitch; - - state.surf_addr = dx_lock_attached(); - state.surf_pitch = _dxSurfacePitch; - - if (getGameType() == GType_FF) { - drawImages_Feeble(&state); - } else { - drawImages(&state); - } - - dx_unlock_2(); - dx_unlock_attached(); -} - -void SimonEngine::drawImages_Feeble(VC10_state *state) { - state->surf2_addr += state->x + state->y * state->surf2_pitch; - state->surf_addr += state->x + state->y * state->surf_pitch; - - if (state->flags & 0x20) { - if (vcGetBit(81) == false) { - // TODO: Compare Feeble rect - } - - uint w, h; - byte *src, *dst, *dst_org; - - state->dl = state->width; - state->dh = state->height; - - vc10_skip_cols(state); - - dst_org = state->surf_addr; - w = 0; - do { - byte color; - - src = vc10_depack_column(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 { - if (state->flags & 0x8) { - uint w, h; - byte *src, *dst, *dst_org; - - state->dl = state->width; - state->dh = state->height; - - vc10_skip_cols(state); - - if (state->flags & 2) { - dst_org = state->surf_addr; - w = 0; - do { - src = vc10_depack_column(state); - dst = dst_org; - - h = 0; - do { - *dst = *src; - 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_depack_column(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 { - const byte *src; - byte *dst; - uint count; - - src = state->depack_src + state->width * state->y_skip; - dst = state->surf_addr; - if (state->flags & 0x80) { - do { - for (count = 0; count != state->draw_width; count++) { - byte color; - color = src[count + state->x_skip]; - if (color) { - if (color == 220) - color = 244; - - dst[count] = color; - } - } - dst += _screenWidth; - src += state->width; - } while (--state->draw_height); - } else { - do { - for (count = 0; count != state->draw_width; count++) { - byte color; - color = src[count + state->x_skip]; - if (color) - 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]; - - uint offs, offs2; - // Allow one section of Simon the Sorcerer 1 introduction to be displayed - // in lower half of screen - if ((getGameType() == GType_SIMON1) && _subroutine == 2926) { - 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); - } - - state->surf2_addr += offs + offs2 * state->surf2_pitch; - state->surf_addr += offs + offs2 * state->surf_pitch; - - if (state->flags & 0x20) { - 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_depack_column(state); /* esi */ - src = state->surf2_addr + w * 2; /* ebx */ - dst = state->surf_addr + w * 2; /* edi */ - - h = state->draw_height; - if ((getGameType() == GType_SIMON1) && vcGetBit(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) { - const byte *src; - byte *dst; - uint h, i; - - if (!(state->flags & 8)) { - src = state->depack_src + (state->width * state->y_skip * 16) + (state->x_skip * 8); - dst = state->surf_addr; - - state->draw_width *= 2; - - if (state->flags & 2) { - /* no transparency */ - h = state->draw_height; - do { - memcpy(dst, src, state->draw_width); - dst += _screenWidth; - src += state->width * 16; - } while (--h); - } else { - /* transparency */ - h = state->draw_height; - do { - for (i = 0; i != state->draw_width; i++) - if (src[i]) - dst[i] = src[i]; - dst += _screenWidth; - src += state->width * 16; - } while (--h); - } - - } else { - byte *dst_org = state->surf_addr; - src = state->depack_src; - /* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE - * aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh - */ - - if (state->flags & 2) { - /* no transparency */ - do { - uint count = state->draw_width / 4; - - dst = dst_org; - do { - uint32 bits = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | (src[3]); - - dst[0] = (byte)((bits >> (32 - 5)) & 31); - dst[1] = (byte)((bits >> (32 - 10)) & 31); - dst[2] = (byte)((bits >> (32 - 15)) & 31); - dst[3] = (byte)((bits >> (32 - 20)) & 31); - dst[4] = (byte)((bits >> (32 - 25)) & 31); - dst[5] = (byte)((bits >> (32 - 30)) & 31); - - bits = (bits << 8) | src[4]; - - dst[6] = (byte)((bits >> (40 - 35)) & 31); - dst[7] = (byte)((bits) & 31); - - dst += 8; - src += 5; - } while (--count); - dst_org += _screenWidth; - } while (--state->draw_height); - } else { - /* transparency */ - 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 tmp; - - tmp = (byte)((bits >> (32 - 5)) & 31); - if (tmp) - dst[0] = tmp; - tmp = (byte)((bits >> (32 - 10)) & 31); - if (tmp) - dst[1] = tmp; - tmp = (byte)((bits >> (32 - 15)) & 31); - if (tmp) - dst[2] = tmp; - tmp = (byte)((bits >> (32 - 20)) & 31); - if (tmp) - dst[3] = tmp; - tmp = (byte)((bits >> (32 - 25)) & 31); - if (tmp) - dst[4] = tmp; - tmp = (byte)((bits >> (32 - 30)) & 31); - if (tmp) - dst[5] = tmp; - - bits = (bits << 8) | src[4]; - - tmp = (byte)((bits >> (40 - 35)) & 31); - if (tmp) - dst[6] = tmp; - tmp = (byte)((bits) & 31); - if (tmp) - dst[7] = tmp; - - dst += 8; - src += 5; - } while (--count); - dst_org += _screenWidth; - } while (--state->draw_height); - } - } - /* vc10_helper_4 */ - } else { - if (getGameType() == GType_SIMON2 && state->flags & 0x4 && _bitArray[10] & 0x800) { - state->surf_addr = state->surf2_addr; - state->surf_pitch = state->surf2_pitch; - } - - if (state->flags & 0x8) { - 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); - - if (state->flags & 2) { - dst_org = state->surf_addr; - w = 0; - do { - src = vc10_depack_column(state); - dst = dst_org; - - h = 0; - do { - dst[0] = (*src / 16) | state->palette; - dst[1] = (*src & 15) | state->palette; - dst += _screenWidth; - src++; - } while (++h != state->draw_height); - dst_org += 2; - } while (++w != state->draw_width); - } else { - dst_org = state->surf_addr; - if (state->flags & 0x40) { /* reached */ - dst_org += vcReadVar(252); - } - w = 0; - do { - byte color; - - src = vc10_depack_column(state); - dst = dst_org; - - h = 0; - do { - color = (*src / 16); - if (color) - dst[0] = color | state->palette; - color = (*src & 15); - if (color) - 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; - if (state->flags & 2) { - do { - for (count = 0; count != state->draw_width; count++) { - dst[count * 2] = (src[count + state->x_skip] / 16) | state->palette; - dst[count * 2 + 1] = (src[count + state->x_skip] & 15) | state->palette; - } - dst += _screenWidth; - src += state->width * 8; - } while (--state->draw_height); - } else { - do { - for (count = 0; count != state->draw_width; count++) { - byte color; - color = (src[count + state->x_skip] / 16); - if (color) - dst[count * 2] = color | state->palette; - color = (src[count + state->x_skip] & 15); - if (color) - dst[count * 2 + 1] = color | state->palette; - } - dst += _screenWidth; - src += state->width * 8; - } while (--state->draw_height); - - } - - /* vc10_helper_7 */ - } - } - -} - -void SimonEngine::vc11_clearPathFinder() { - memset(&_pathFindArray, 0, sizeof(_pathFindArray)); -} - -void SimonEngine::vc12_delay() { - VgaSprite *vsp = findCurSprite(); - uint num; - - if (getGameType() == GType_SIMON1) { - num = vcReadVarOrWord(); - } else { - num = vcReadNextByte() * _frameRate; - } - - // 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 += VGA_DELAY_BASE; - - add_vga_timer(num, _vcPtr, _vgaCurSpriteId, _vgaCurFileId); - _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_wakeup_id() { - VgaSleepStruct *vfs = _vgaSleepStructs, *vfs_tmp; - uint16 id = vcReadNextWord(); - while (vfs->ident != 0) { - if (vfs->ident == id) { - add_vga_timer(VGA_DELAY_BASE, 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++; - } - } - - /* clear a wait event */ - if (id == _vgaWaitFor) - _vgaWaitFor = 0; -} - -void SimonEngine::vc16_sleep_on_id() { - VgaSleepStruct *vfs = _vgaSleepStructs; - while (vfs->ident) - vfs++; - - vfs->ident = vcReadNextWord(); - vfs->code_ptr = _vcPtr; - vfs->sprite_id = _vgaCurSpriteId; - vfs->cur_vga_file = _vgaCurFileId; - - _vcPtr = (byte *)&_vc_get_out_of_code; -} - -void SimonEngine::vc17_setPathfinderItem() { - uint a = vcReadNextWord(); - _pathFindArray[a - 1] = (const uint16 *)_vcPtr; - - int end = (getGameType() == GType_FF) ? 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) - 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() { - uint a = vcReadNextWord(); - uint b = vcReadNextWord(); - uint num = a == 0 ? 32 : 16; - uint palSize = 96; - byte *palptr, *src; - - if (getGameType() == GType_FF) { - a = 0; - num = 256; - palSize = 768; - } - - palptr = &_palette[(a * 64)]; - src = _curVgaFile1 + 6 + 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 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) { - 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; - - 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) && vsp->id == 128) { - vte++; - } else { - vte2 = vte; - while (vte2->delay) { - memcpy(vte2, vte2 + 1, sizeof(VgaTimerEntry)); - vte2++; - } - } - } - - vcWriteVar(254, 0); - - _lockWord &= ~8; -} - -void SimonEngine::vc28_dummy_op() { - /* unused */ - _vcPtr += 8; -} - -void SimonEngine::vc29_stopAllSounds() { - _sound->stopAll(); -} - -void SimonEngine::vc30_setFrameRate() { - _frameRate = vcReadNextWord(); -} - -void SimonEngine::vc31_setWindow() { - _windowNum = vcReadNextWord(); -} - -uint SimonEngine::vcReadVar(uint var) { - assert(var < 255); - return (uint16)_variableArray[var]; -} - -void SimonEngine::vcWriteVar(uint var, int16 value) { - _variableArray[var] = value; -} - -void SimonEngine::vc32_copyVar() { - 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; - uint vga_res = vcReadNextWord(); - uint windowNum = vcReadNextWord(); - - if (getGameType() == GType_SIMON1) { - if (windowNum == 16) { - _copyPartialMode = 2; - } else { - set_video_mode_internal(windowNum, vga_res); - } - } else { - set_video_mode_internal(windowNum, vga_res); - } -} - -void SimonEngine::vc37_addToSpriteY() { - VgaSprite *vsp = findCurSprite(); - vsp->y += vcReadVar(vcReadNextWord()); - _vgaSpriteChanged++; -} - -void SimonEngine::vc38_skipIfVarZero() { - uint var = vcReadNextWord(); - if (vcReadVar(var) == 0) - vcSkipNextInstruction(); -} - -void SimonEngine::vc39_setVar() { - uint var = vcReadNextWord(); - int16 value = vcReadNextWord(); - vcWriteVar(var, value); -} - -void SimonEngine::vc40() { - uint var = vcReadNextWord(); - int16 value = vcReadVar(var) + vcReadNextWord(); - - if ((getGameType() == GType_SIMON2) && var == 15 && !(_bitArray[5] & 1)) { - 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; - add_vga_timer(6, NULL, 0, 0); /* special timer */ - } - } -no_scroll:; - - vcWriteVar(var, value); -} - -void SimonEngine::vc41() { - uint var = vcReadNextWord(); - int16 value = vcReadVar(var) - vcReadNextWord(); - - if ((getGameType() == GType_SIMON2) && var == 15 && !(_bitArray[5] & 1)) { - int16 tmp; - - 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; - tmp = _scrollXMax - _scrollX; - if (_scrollX < 20) - _scrollCount = -_scrollX; - add_vga_timer(6, NULL, 0, 0); /* special timer */ - } - } -no_scroll:; - - vcWriteVar(var, value); -} - -void SimonEngine::vc42_delayIfNotEQ() { - uint val = vcReadVar(vcReadNextWord()); - if (val != vcReadNextWord()) { - - add_vga_timer(_frameRate + 1, _vcPtr - 4, _vgaCurSpriteId, _vgaCurFileId); - _vcPtr = (byte *)&_vc_get_out_of_code; - } -} - -void SimonEngine::vc43_skipIfBitClear() { - if (!vcGetBit(vcReadNextWord())) { - vcSkipNextInstruction(); - } -} - -void SimonEngine::vc44_skipIfBitSet() { - if (vcGetBit(vcReadNextWord())) { - vcSkipNextInstruction(); - } -} - -void SimonEngine::vc45_setSpriteX() { - VgaSprite *vsp = findCurSprite(); - vsp->x = vcReadVar(vcReadNextWord()); - _vgaSpriteChanged++; -} - -void SimonEngine::vc46_setSpriteY() { - VgaSprite *vsp = findCurSprite(); - vsp->y = vcReadVar(vcReadNextWord()); - _vgaSpriteChanged++; -} - -void SimonEngine::vc47_addToVar() { - uint var = vcReadNextWord(); - vcWriteVar(var, vcReadVar(var) + vcReadVar(vcReadNextWord())); -} - -void SimonEngine::vc48_setPathFinder() { - uint a = (uint16)_variableArray[12]; - const uint16 *p = _pathFindArray[a - 1]; - - if (getGameType() == GType_FF) { - VgaSprite *vsp = findCurSprite(); - int16 x, x2, y, y1, y2, ydiff; - uint pos = 0; - - while(vsp->x > readUint16Wrapper(p + 2)) { - p += 2; - pos++; - } - - 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(y, diff); - - _variableArray[11] = readUint16Wrapper(p); - _variableArray[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::vcSetBitTo(uint bit, bool value) { - uint16 *bits = &_bitArray[bit >> 4]; - *bits = (*bits & ~(1 << (bit & 15))) | (value << (bit & 15)); -} - -bool SimonEngine::vcGetBit(uint bit) { - uint16 *bits = &_bitArray[bit >> 4]; - return (*bits & (1 << (bit & 15))) != 0; -} - -void SimonEngine::vc49_setBit() { - vcSetBitTo(vcReadNextWord(), true); -} - -void SimonEngine::vc50_clearBit() { - vcSetBitTo(vcReadNextWord(), false); -} - -void SimonEngine::vc51_clear_hitarea_bit_0x40() { - clear_hitarea_bit_0x40(vcReadNextWord()); -} - -void SimonEngine::vc52_playSound() { - bool ambient = false; - - uint16 sound = vcReadNextWord(); - if (sound >= 0x8000) { - ambient = true; - sound = -sound; - } - - if (getGameType() == GType_FF) { - uint16 pan = vcReadNextWord(); - uint16 vol = vcReadNextWord(); - _sound->playSoundData(_curSfxFile, sound, pan, vol, ambient); - } 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_no_op() { - // Start sound effect, panning it with the animation - int snd = vcReadNextWord(); - int xoffs = vcReadNextWord(); - int vol = vcReadNextWord(); - debug(0, "STUB: vc53_no_op: snd %d xoffs %d vol %d", snd, xoffs, vol); -} - -void SimonEngine::vc54_no_op() { - /* unused */ - _vcPtr += 6; -} - -void SimonEngine::vc55_offset_hit_area() { - 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() { - uint num = vcReadVarOrWord() * _frameRate; - - add_vga_timer(num + VGA_DELAY_BASE, _vcPtr, _vgaCurSpriteId, _vgaCurFileId); - _vcPtr = (byte *)&_vc_get_out_of_code; -} - -void SimonEngine::vc59() { - if (getGameType() == GType_SIMON1) { - if (!_sound->isVoiceActive()) - vcSkipNextInstruction(); - } else { - uint file = vcReadNextWord(); - uint start = vcReadNextWord(); - uint end = vcReadNextWord() + 1; - - do { - vc_kill_sprite(file, start); - } while (++start != end); - } -} - -void SimonEngine::vc58() { - uint sprite = _vgaCurSpriteId; - uint file = _vgaCurFileId; - const byte *vc_ptr_org; - uint16 tmp; - - _vgaCurFileId = vcReadNextWord(); - _vgaCurSpriteId = vcReadNextWord(); - - tmp = to16Wrapper(vcReadNextWord()); - - vc_ptr_org = _vcPtr; - _vcPtr = (byte *)&tmp; - vc23_setSpritePriority(); - - _vcPtr = vc_ptr_org; - _vgaCurSpriteId = sprite; - _vgaCurFileId = file; -} - -void SimonEngine::vc57_no_op() { - /* unused */ -} - -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 *vc_ptr_org; - - old_sprite_id = _vgaCurSpriteId; - old_cur_file_id = _vgaCurFileId; - vc_ptr_org = _vcPtr; - - _vgaCurFileId = file; - _vgaCurSpriteId = sprite; - - vfs = _vgaSleepStructs; - while (vfs->ident != 0) { - if (vfs->sprite_id == _vgaCurSpriteId && ((getGameType() == GType_SIMON1) || vfs->cur_vga_file == _vgaCurFileId)) { - 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 == _vgaCurFileId)) { - delete_vga_timer(vte); - break; - } - vte++; - } - } - - _vgaCurFileId = old_cur_file_id; - _vgaCurSpriteId = old_sprite_id; - _vcPtr = vc_ptr_org; -} - -void SimonEngine::vc60_killSprite() { - uint file; - - if (getGameType() == GType_SIMON1) { - file = _vgaCurFileId; - } else { - file = vcReadNextWord(); - } - uint sprite = vcReadNextWord(); - vc_kill_sprite(file, sprite); -} - -void SimonEngine::vc61_setMaskImage() { - VgaSprite *vsp = findCurSprite(); - - vsp->image = vcReadVarOrWord(); - - vsp->x += vcReadNextWord(); - vsp->y += vcReadNextWord(); - vsp->flags = 0x24; - - _vgaSpriteChanged++; -} - -void SimonEngine::vc62_fastFadeOut() { - uint i; - - vc29_stopAllSounds(); - - if (!_fastFadeOutFlag) { - _fastFadeOutFlag = true; - - _videoNumPalColors = 256; - if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - if (_windowNum == 4) - _videoNumPalColors = 208; - } - - memcpy(_videoBuf1, _paletteBackup, _videoNumPalColors * 4); - for (i = NUM_PALETTE_FADEOUT; i != 0; --i) { - palette_fadeout((uint32 *)_videoBuf1, _videoNumPalColors); - _system->setPalette(_videoBuf1, 0, _videoNumPalColors); - if (_fade) - _system->updateScreen(); - delay(5); - } - - if (getGameType() == GType_SIMON1) { - uint16 params[5]; /* parameters to vc10_draw */ - VgaSprite *vsp; - VgaPointersEntry *vpe; - const byte *vc_ptr_org = _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->fileId]; - _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 = vc_ptr_org; - } - - // 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) { - 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) { - _paletteColorCount = 256; - } else { - _paletteColorCount = 208; - if (_windowNum != 4) { - _paletteColorCount = 256; - } - } - _fastFadeOutFlag = false; -} - -void SimonEngine::vc64_skipIfSpeechEnded() { - if (!_sound->isVoiceActive() || (_subtitles && _language != Common::HB_ISR)) - vcSkipNextInstruction(); -} - -void SimonEngine::vc65_slowFadeIn() { - _paletteColorCount = 624; - _videoNumPalColors = 208; - if (_windowNum != 4) { - _paletteColorCount = 768; - _videoNumPalColors = 256; - } - _paletteColorCount |= 0x8000; - _fastFadeOutFlag = false; -} - -void SimonEngine::vc66_skipIfNotEqual() { - uint a = vcReadNextWord(); - uint b = vcReadNextWord(); - - if (vcReadVar(a) != vcReadVar(b)) - vcSkipNextInstruction(); -} - -void SimonEngine::vc67_skipIfGE() { - uint a = vcReadNextWord(); - uint b = vcReadNextWord(); - - if (vcReadVar(a) >= vcReadVar(b)) - vcSkipNextInstruction(); -} - -void SimonEngine::vc68_skipIfLE() { - uint a = vcReadNextWord(); - uint 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() { - vcReadNextByte(); - _marks |= 1 << vcReadNextByte(); -} - -void SimonEngine::vc74_clearMark() { - vcReadNextByte(); - _marks &= ~(1 << vcReadNextByte()); -} - -int SimonEngine::getScale(int y, int x) { - int z; - - if (y > _baseY) { - return((int)(x * (1 + ((y - _baseY) * _scale)))); - } else { - if (x == 0) - return(0); - if (x < 0) { - z = ((int)((x * (1 - ((_baseY - y)* _scale))) - 0.5)); - if (z >- 2) - return(-2); - return(z); - } - - z=((int)((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(); - int var = vcReadNextWord(); - - vsp->x += getScale(vsp->y, x); - _variableArray[var] = vsp->x; - - if (_scrollXMax) { - // TODO: Scroll check - } - - vsp->flags = 0x40; -} - -void SimonEngine::vc77_setScaleYOffs() { - VgaSprite *vsp = findCurSprite(); - - vsp->image = vcReadNextWord(); - int16 x = vcReadNextWord(); - int var = vcReadNextWord(); - - vsp->y += getScale(vsp->y, x); - _variableArray[var] = vsp->y; - vsp->flags = 0x40; -} - -void SimonEngine::vc78_computeXY() { - VgaSprite *vsp = findCurSprite(); - - uint a = (uint16)_variableArray[12]; - uint b = (uint16)_variableArray[13]; - - const uint16 *p = _pathFindArray[a - 1]; - p += b * 2; - - uint16 posx = readUint16Wrapper(p); - _variableArray[15] = posx; - vsp->x = posx; - - uint16 posy = readUint16Wrapper(p + 1); - _variableArray[16] = posy; - vsp->y = posy; - - vcSetBitTo(85, false); - if (vcGetBit(74) == true) { - //centreScroll(); - } -} - -void SimonEngine::vc79_computePosNum() { - uint a = (uint16)_variableArray[12]; - const uint16 *p = _pathFindArray[a - 1]; - uint pos = 0; - - int16 y = _variableArray[16]; - while(y > readUint16Wrapper(p + 1)) { - p += 2; - pos++; - } - - _variableArray[13] = pos; -} - -void SimonEngine::vc80_setOverlayImage() { - VgaSprite *vsp = findCurSprite(); - - vsp->image = vcReadVarOrWord(); - - vsp->x += vcReadNextWord(); - vsp->y += vcReadNextWord(); - vsp->flags = 0x10; - - _vgaSpriteChanged++; -} - -void SimonEngine::vc81_setRandom() { - uint var = vcReadNextWord(); - uint value = vcReadNextWord(); - writeVariable(var, _rnd.getRandomNumber(value - 1)); -} - -void SimonEngine::vc82_getPathValue() { - uint8 val; - - uint16 var = vcReadNextWord(); - - if (vcGetBit(82) == true) { - val = _pathValues1[_GPVCount1++]; - } else { - val = _pathValues[_GPVCount++]; - } - - writeVariable(var, val); -} - -void SimonEngine::vc83_playSoundLoop() { - // Start looping sound effect - int snd = vcReadNextWord(); - int vol = vcReadNextWord(); - int pan = vcReadNextWord(); - debug(0, "STUB: vc83_playSoundLoop: snd %d vol %d pan %d", snd, vol, pan); -} - -void SimonEngine::vc84_stopSoundLoop() { - // Stop looping sound effect - debug(0, "STUB: vc84_stopSoundLoop"); -} - -} // End of namespace Simon |
