예제 #1
0
파일: script.cpp 프로젝트: rkmarvin/scummvm
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);
}
예제 #2
0
파일: script.cpp 프로젝트: rkmarvin/scummvm
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();

}
예제 #3
0
파일: script.cpp 프로젝트: rkmarvin/scummvm
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)));

}
예제 #4
0
파일: script.cpp 프로젝트: rkmarvin/scummvm
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();
		}

	}

}
예제 #5
0
파일: script.cpp 프로젝트: rkmarvin/scummvm
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);
}
예제 #6
0
파일: script.cpp 프로젝트: rkmarvin/scummvm
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]);
}
예제 #7
0
파일: script.cpp 프로젝트: rkmarvin/scummvm
void ScriptInterpreter::sfWalk() {
	_vm->walk(getSlotData(arg16(5)) + arg16(3));
}
예제 #8
0
파일: script.cpp 프로젝트: rkmarvin/scummvm
void ScriptInterpreter::sfFindPath() {
	_vm->_segmap->findPath((int16*)(getSlotData(arg16(13)) + arg16(11)), arg16(9), arg16(7), arg16(5), arg16(3));
}
예제 #9
0
파일: script.cpp 프로젝트: rkmarvin/scummvm
void ScriptInterpreter::sfLoadScript() {
	int16 codeOfs = _code - getSlotData(_regs.reg4);
	loadScript(arg16(4), arg8(3));
	_code = getSlotData(_regs.reg4) + codeOfs;
	_switchLocalDataNear = true;
}
예제 #10
0
파일: script.cpp 프로젝트: rkmarvin/scummvm
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);
	}

}
예제 #11
0
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;
}