void ScriptInterpreter::sfFindMouseInRectIndex1() { int16 index = -1; if (_vm->_mouseY < _vm->_cameraHeight) { int16 slotIndex = arg16(5); index = _vm->findRectAtPoint(getSlotData(slotIndex) + arg16(3), _vm->_mouseX + _vm->_cameraX, _vm->_mouseY + _vm->_cameraY, arg16(11) + 1, arg16(7), getSlotData(slotIndex) + _slots[slotIndex].size); } localWrite16(arg16(9), index); }
void ScriptInterpreter::loadState(Common::ReadStream *in) { // Load registers _regs.reg0 = in->readUint16LE(); _regs.reg1 = in->readUint16LE(); _regs.reg2 = in->readUint16LE(); _regs.reg3 = in->readUint16LE(); _regs.reg4 = in->readUint16LE(); _regs.reg5 = in->readUint16LE(); _regs.reg6 = in->readUint16LE(); _regs.sp = in->readUint16LE(); _regs.reg8 = in->readUint16LE(); // Load slots for (int slot = 0; slot < kMaxScriptSlots; slot++) { _slots[slot].size = in->readUint32LE(); _slots[slot].resIndex = in->readUint16LE(); _slots[slot].data = NULL; if (_slots[slot].size > 0) { _slots[slot].data = new byte[_slots[slot].size]; in->read(_slots[slot].data, _slots[slot].size); } } // Load stack in->read(_stack, kScriptStackSize); _savedSp = in->readUint16LE(); // Load IP _code = getSlotData(_regs.reg4) + in->readUint16LE(); }
void ScriptInterpreter::saveState(Common::WriteStream *out) { // Save registers out->writeUint16LE(_regs.reg0); out->writeUint16LE(_regs.reg1); out->writeUint16LE(_regs.reg2); out->writeUint16LE(_regs.reg3); out->writeUint16LE(_regs.reg4); out->writeUint16LE(_regs.reg5); out->writeUint16LE(_regs.reg6); out->writeUint16LE(_regs.sp); out->writeUint16LE(_regs.reg8); // Save slots for (int slot = 0; slot < kMaxScriptSlots; slot++) { out->writeUint32LE(_slots[slot].size); out->writeUint16LE(_slots[slot].resIndex); if (_slots[slot].size > 0) out->write(_slots[slot].data, _slots[slot].size); } // Save stack out->write(_stack, kScriptStackSize); out->writeUint16LE(_savedSp); // Save IP out->writeUint16LE((int16)(_code - getSlotData(_regs.reg4))); }
void ScriptInterpreter::runScript() { uint32 lastScreenUpdate = 0; while (!_vm->shouldQuit()) { if (_vm->_movieSceneFlag) _vm->_mouseButton = 0; if (_vm->_saveLoadRequested != 0) { if (_vm->_saveLoadRequested == 1) _vm->loadGameState(_vm->_saveLoadSlot); else if (_vm->_saveLoadRequested == 2) _vm->saveGameState(_vm->_saveLoadSlot, _vm->_saveLoadDescription); _vm->_saveLoadRequested = 0; } if (_switchLocalDataNear) { _switchLocalDataNear = false; _localData = getSlotData(_regs.reg4); } if (_switchLocalDataFar) { _switchLocalDataFar = false; _localData = getSlotData(_regs.reg5); _switchLocalDataNear = true; } if (_switchLocalDataToStack) { _switchLocalDataToStack = false; _localData = _stack + 2; _switchLocalDataNear = true; } byte opcode = readByte(); execOpcode(opcode); // Update the screen at semi-regular intervals, else the mouse // cursor will be jerky. uint32 now = _vm->_system->getMillis(); if (now < lastScreenUpdate || now - lastScreenUpdate > 10) { _vm->_system->updateScreen(); lastScreenUpdate = _vm->_system->getMillis(); } } }
void ScriptInterpreter::setMainScript(uint slotIndex) { _switchLocalDataNear = true; _switchLocalDataFar = false; _switchLocalDataToStack = false; _cmpBitTest = false; _regs.reg0 = 0; _regs.reg1 = 0; _regs.reg2 = 0; _regs.reg3 = 0; _regs.reg4 = slotIndex; _regs.reg5 = 0; _regs.reg6 = 0; _regs.sp = 4096; _regs.reg8 = 0; _code = getSlotData(_regs.reg4); }
void ScriptInterpreter::sfGetRgbModifiertAtPoint() { byte *rgb = getSlotData(arg16(11)) + arg16(9); _vm->_segmap->getRgbModifiertAtPoint(arg16(5), arg16(3), arg16(7), rgb[0], rgb[1], rgb[2]); }
void ScriptInterpreter::sfWalk() { _vm->walk(getSlotData(arg16(5)) + arg16(3)); }
void ScriptInterpreter::sfFindPath() { _vm->_segmap->findPath((int16*)(getSlotData(arg16(13)) + arg16(11)), arg16(9), arg16(7), arg16(5), arg16(3)); }
void ScriptInterpreter::sfLoadScript() { int16 codeOfs = _code - getSlotData(_regs.reg4); loadScript(arg16(4), arg8(3)); _code = getSlotData(_regs.reg4) + codeOfs; _switchLocalDataNear = true; }
void ScriptInterpreter::execOpcode(byte opcode) { int16 ofs; debug(1, "opcode = %d", opcode); switch (opcode) { case 0: { // ok _subCode = _code; byte length = readByte(); debug(1, "length = %d", length); uint16 index = readInt16(); debug(1, "callScriptFunction %d", index); execScriptFunction(index); _code += length - 2; break; } case 1: // ok _regs.reg0 = readInt16(); break; case 2: // ok _regs.reg1 = readInt16(); break; case 3: // ok _regs.reg3 = readInt16(); break; case 4: // ok _regs.reg5 = _regs.reg0; break; case 5: // ok _regs.reg3 = _regs.reg0; break; case 6: // ok _regs.reg1 = _regs.reg0; break; case 7: _regs.reg1 = localRead16(_regs.reg3); break; case 8: localWrite16(_regs.reg3, _regs.reg0); break; case 9: localWrite16(readInt16(), _regs.reg0); break; case 10: localWrite8(readInt16(), _regs.reg0); break; case 11: localWrite16(readInt16(), _regs.reg5); break; case 12: localWrite16(readInt16(), _regs.reg4); break; case 13: localWrite16(readInt16(), _regs.reg3); break; case 14: _regs.reg3 = localRead16(readInt16()); break; case 15: _regs.reg2 = localRead16(_regs.reg1); break; case 16: _regs.reg2 = localRead16(_regs.reg1 + readInt16()); break; case 17: _regs.reg2 = _regs.reg0; break; case 18: _regs.reg0 += readInt16(); break; case 19: localWrite16(_regs.reg3, localRead16(_regs.reg3) + _regs.reg0); break; case 20: _regs.reg0 += _regs.reg2; break; case 21: _regs.reg3 += _regs.sp; break; case 22: _regs.reg1 += _regs.sp; break; case 23: localWrite16(_regs.reg3, localRead16(_regs.reg3) - _regs.reg0); break; case 24: _regs.reg0 /= readInt16(); break; case 25: localWrite16(_regs.reg3, localRead16(_regs.reg3) / _regs.reg0); break; case 26: // NOP break; case 27: _regs.reg0 *= readInt16(); break; case 28: localWrite16(_regs.reg3, localRead16(_regs.reg3) * _regs.reg0); break; case 29: _regs.reg0 *= _regs.reg2; break; case 30: localWrite16(_regs.reg3, localRead16(_regs.reg3) + 1); break; case 31: localWrite16(_regs.reg3, localRead16(_regs.reg3) - 1); break; case 32: _switchLocalDataFar = true; break; case 33: _switchLocalDataToStack = true; break; case 34: pushInt16(_regs.reg0); break; case 35: pushInt16(_regs.reg1); break; case 36: _regs.reg1 = popInt16(); break; case 37: _regs.reg0 = popInt16(); break; case 38: _regs.reg2 = -_regs.reg2; break; case 39: _regs.reg8 = readInt16(); _cmpBitTest = false; break; case 40: _regs.reg8 = _regs.reg0; _cmpBitTest = false; break; case 41: _regs.reg8 = readInt16(); _cmpBitTest = true; break; case 42: _regs.reg8 = _regs.reg0; _cmpBitTest = true; break; case 43: _code = getSlotData(_regs.reg4) + _regs.reg0; break; case 44: _code = getSlotData(_regs.reg5) + _regs.reg0; _regs.reg4 = _regs.reg5; _switchLocalDataNear = true; break; case 45: pushInt16(_code - getSlotData(_regs.reg4)); pushInt16(_regs.reg4); _code = getSlotData(_regs.reg4) + _regs.reg0; break; case 46: pushInt16(_code - getSlotData(_regs.reg4)); pushInt16(_regs.reg4); _code = getSlotData(_regs.reg5) + _regs.reg0; _regs.reg4 = _regs.reg5; _switchLocalDataNear = true; break; case 47: _regs.reg4 = popInt16(); ofs = popInt16(); _code = getSlotData(_regs.reg4) + ofs; _switchLocalDataNear = true; break; case 48: _regs.reg4 = popInt16(); ofs = popInt16(); _code = getSlotData(_regs.reg4) + ofs; _regs.sp += _regs.reg0; _switchLocalDataNear = true; break; case 49: ofs = readByte(); _code += ofs; break; case 50: if (_cmpBitTest) { _regs.reg1 &= _regs.reg8; if (_regs.reg1 == 0) _code += 4; } else { if (_regs.reg1 == _regs.reg8) _code += 4; } _code++; break; case 51: if (_cmpBitTest) { _regs.reg1 &= _regs.reg8; if (_regs.reg1 != 0) _code += 4; } else { if (_regs.reg1 != _regs.reg8) _code += 4; } _code++; break; case 52: if ((uint16)_regs.reg1 >= (uint16)_regs.reg8) _code += 4; _code++; break; case 53: if ((uint16)_regs.reg1 <= (uint16)_regs.reg8) _code += 4; _code++; break; case 54: if ((uint16)_regs.reg1 < (uint16)_regs.reg8) _code += 4; _code++; break; case 55: if ((uint16)_regs.reg1 > (uint16)_regs.reg8) _code += 4; _code++; break; default: error("Invalid opcode %d", opcode); } }
bool SDRdaemonFECBuffer::writeAndRead(uint8_t *array, std::size_t length, uint8_t *data, std::size_t& dataLength) { assert(length == udpSize); bool dataAvailable = false; dataLength = 0; SuperBlock *superBlock = (SuperBlock *) array; int frameIndex = superBlock->header.frameIndex; // std::cerr << "SDRdaemonFECBuffer::writeAndRead:" // << " frameIndex: " << frameIndex // << " decoderIndex: " << decoderIndex // << " blockIndex: " << blockIndex // << " i.q:"; // // for (int i = 0; i < 10; i++) // { // std::cerr << " " << (int) superBlock->protectedBlock.samples[i].i // << "." << (int) superBlock->protectedBlock.samples[i].q; // } // // std::cerr << std::endl; if ( m_frameHead != frameIndex) { getSlotData(data, dataLength); // copy slot data to output buffer dataAvailable = true; initDecodeSlot(); // re-initialize slot m_frameHead = frameIndex; } // decoderIndex should now be correctly set if (m_decoderSlot.m_blockCount < nbOriginalBlocks) // not enough blocks to decode -> store data { int blockCount = m_decoderSlot.m_blockCount; int recoveryCount = m_decoderSlot.m_recoveryCount; int blockIndex = superBlock->header.blockIndex; m_decoderSlot.m_cm256DescriptorBlocks[blockCount].Index = blockIndex; if (blockIndex == 0) // first block with meta { m_decoderSlot.m_metaRetrieved = true; } if (blockIndex < nbOriginalBlocks) // data block { m_decoderSlot.m_frame.m_blocks[blockIndex] = superBlock->protectedBlock; m_decoderSlot.m_cm256DescriptorBlocks[blockCount].Block = (void *) &m_decoderSlot.m_frame.m_blocks[blockIndex]; } else // redundancy block { m_decoderSlot.m_recoveryBlocks[recoveryCount] = superBlock->protectedBlock; m_decoderSlot.m_cm256DescriptorBlocks[blockCount].Block = (void *) &m_decoderSlot.m_recoveryBlocks[recoveryCount]; m_decoderSlot.m_recoveryCount++; } } m_decoderSlot.m_blockCount++; if (m_decoderSlot.m_blockCount == nbOriginalBlocks) // ready to decode { m_decoderSlot.m_decoded = true; if (m_cm256_OK && (m_decoderSlot.m_recoveryCount > 0)) // recovery data used and CM256 decoder available { m_paramsCM256.RecoveryCount = m_decoderSlot.m_recoveryCount; // // debug print // for (int ir = 0; ir < m_decoderSlots[decoderIndex].m_recoveryCount; ir++) // recovery blocks // { // int blockIndex = m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[nbRxOriginalBlocks+ir].Index; // ProtectedBlock *recoveryBlock = (ProtectedBlock *) m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[nbRxOriginalBlocks+ir].Block; // // std::cerr << "SDRdaemonFECBuffer::writeAndRead:" // << " recovery block #" << blockIndex // << " i.q: "; // // for (int i = 0; i < 10; i++) // { // std::cerr << " " << recoveryBlock->samples[i].i // << "." << recoveryBlock->samples[i].q; // } // // std::cerr << std::endl; // } // // end debug print if (cm256_decode(m_paramsCM256, m_decoderSlot.m_cm256DescriptorBlocks)) // failure to decode { std::cerr << "SDRdaemonFECBuffer::writeAndRead: CM256 decode error" << std::endl; } else // success to decode { int nbRxOriginalBlocks = nbOriginalBlocks - m_decoderSlot.m_recoveryCount; std::cerr << "SDRdaemonFECBuffer::writeAndRead: CM256 decode success:" << " nb recovery blocks: " << m_decoderSlot.m_recoveryCount << std::endl; for (int ir = 0; ir < m_decoderSlot.m_recoveryCount; ir++) // recover lost blocks { int recoveryIndex = nbOriginalBlocks - m_decoderSlot.m_recoveryCount + ir; int blockIndex = m_decoderSlot.m_cm256DescriptorBlocks[recoveryIndex].Index; ProtectedBlock *recoveredBlock = (ProtectedBlock *) m_decoderSlot.m_cm256DescriptorBlocks[recoveryIndex].Block; m_decoderSlot.m_frame.m_blocks[blockIndex] = *recoveredBlock; // if (blockIndex == 0) // { // m_decoderSlots[decoderIndex].m_metaRetrieved = true; // } // debug print std::cerr << "SDRdaemonFECBuffer::writeAndRead:" << " recovered block #" << blockIndex << " i.q: "; for (int i = 0; i < 10; i++) { std::cerr << " " << recoveredBlock->samples[i].i << "." << recoveredBlock->samples[i].q; } std::cerr << std::endl; // end debug print } // recover } // success to decode } // recovery data used if (m_decoderSlot.m_metaRetrieved) // meta data retrieved { MetaDataFEC *metaData = (MetaDataFEC *) &m_decoderSlot.m_frame.m_blocks[0]; if (!(*metaData == m_currentMeta)) { m_currentMeta = *metaData; printMeta(metaData); } } } // decode frame return dataAvailable; }