Example #1
0
// Load a value according to the operation
void Expression::loadValue(byte operation, uint32 varBase, const StackFrame &stackFrame) {
	int16 dimCount;
	uint16 temp;
	int16 temp2;
	int16 offset;
	int16 dim;
	byte *arrDescPtr;
	int32 prevPrevVal;
	int32 prevVal;
	int32 curVal;

	switch (operation) {
	case OP_ARRAY_INT8:
	case OP_ARRAY_INT32:
	case OP_ARRAY_INT16:
	case OP_ARRAY_STR:
		*stackFrame.opers = (operation == OP_ARRAY_STR) ? OP_LOAD_IMM_STR : OP_LOAD_IMM_INT16;
		temp = _vm->_game->_script->readInt16();
		dimCount = _vm->_game->_script->readByte();
		arrDescPtr = _vm->_game->_script->getData() + _vm->_game->_script->pos();
		_vm->_game->_script->skip(dimCount);
		offset = 0;
		for (dim = 0; dim < dimCount; dim++) {
			temp2 = parseValExpr(OP_END_MARKER);
			offset = offset * arrDescPtr[dim] + temp2;
		}
		if (operation == OP_ARRAY_INT8)
			*stackFrame.values = (int8) READ_VARO_UINT8(varBase + temp + offset);
		else if (operation == OP_ARRAY_INT32)
			*stackFrame.values = READ_VARO_UINT32(varBase + temp * 4 + offset * 4);
		else if (operation == OP_ARRAY_INT16)
			*stackFrame.values = (int16) READ_VARO_UINT16(varBase + temp * 2 + offset * 2);
		else if (operation == OP_ARRAY_STR) {
			*stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8(
						varBase + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4),
					kInterVar);
			if (_vm->_game->_script->peekByte() == 13) {
				_vm->_game->_script->skip(1);
				temp2 = parseValExpr(OP_END_MARKER);
				*stackFrame.opers = OP_LOAD_IMM_INT16;
				*stackFrame.values = READ_VARO_UINT8(varBase + temp * 4 +
						offset * 4 * _vm->_global->_inter_animDataSize + temp2);
			}
		}
		break;

	case OP_LOAD_VAR_INT16:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readUint16() * 2);
		break;

	case OP_LOAD_VAR_INT8:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = (int8) READ_VARO_UINT8(varBase + _vm->_game->_script->readUint16());
		break;

	case OP_LOAD_IMM_INT32:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = _vm->_game->_script->readInt32();
		break;

	case OP_LOAD_IMM_INT16:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = _vm->_game->_script->readInt16();
		break;

	case OP_LOAD_IMM_INT8:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = _vm->_game->_script->readInt8();
		break;

	case OP_LOAD_IMM_STR:
		*stackFrame.opers = OP_LOAD_IMM_STR;
		*stackFrame.values = encodePtr((byte *)_vm->_game->_script->readString(), kExecPtr);
		break;

	case OP_LOAD_VAR_INT32:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = READ_VARO_UINT32(varBase + _vm->_game->_script->readUint16() * 4);
		break;

	case OP_LOAD_VAR_INT32_AS_INT16:
		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readUint16() * 4);
		break;

	case OP_LOAD_VAR_STR:
		*stackFrame.opers = OP_LOAD_IMM_STR;
		temp = _vm->_game->_script->readUint16() * 4;
		*stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8(varBase + temp), kInterVar);
		if (_vm->_game->_script->peekByte() == 13) {
			_vm->_game->_script->skip(1);
			temp += parseValExpr(OP_END_MARKER);
			*stackFrame.opers = OP_LOAD_IMM_INT16;
			*stackFrame.values = READ_VARO_UINT8(varBase + temp);
		}
		break;

	case OP_FUNC:
		operation = _vm->_game->_script->readByte();
		parseExpr(OP_END_EXPR, 0);

		switch (operation) {
		case FUNC_SQRT1:
		case FUNC_SQRT2:
		case FUNC_SQRT3:
			curVal = 1;
			prevVal = 1;

			do {
				prevPrevVal = prevVal;
				prevVal = curVal;
				curVal = (curVal + _resultInt / curVal) / 2;
			} while ((curVal != prevVal) && (curVal != prevPrevVal));
			_resultInt = curVal;
			break;

		case FUNC_SQR:
			_resultInt =
				_resultInt * _resultInt;
			break;

		case FUNC_ABS:
			if (_resultInt < 0)
				_resultInt = -_resultInt;
			break;

		case FUNC_RAND:
			_resultInt =
				_vm->_util->getRandom(_resultInt);
			break;
		}

		*stackFrame.opers = OP_LOAD_IMM_INT16;
		*stackFrame.values = _resultInt;
		break;
	}
}
Example #2
0
void Map_v2::loadMapObjects(const char *avjFile) {
	uint8 wayPointsCount;
	uint16 var;
	int16 id;
	int16 mapWidth, mapHeight;
	int16 tmp;
	byte *variables;
	uint32 tmpPos;
	uint32 passPos;

	var = _vm->_game->_script->readVarIndex();
	variables = _vm->_inter->_variables->getAddressOff8(var);

	id = _vm->_game->_script->readInt16();

	if (((uint16) id) >= 65520) {
		switch ((uint16) id) {
			case 65530:
				for (int i = 0; i < _mapWidth * _mapHeight; i++)
					_passMap[i] -= READ_VARO_UINT8(var + i);
				break;
			case 65531:
				for (int i = 0; i < _mapWidth * _mapHeight; i++)
					_passMap[i] += READ_VARO_UINT8(var + i);
				break;
			case 65532:
				for (int i = 0; i < _mapWidth * _mapHeight; i++)
					WRITE_VARO_UINT8(var + i, 0x00);
				break;
			case 65533: {
				int index = READ_VARO_UINT16(var);
				// _vm->_mult->_objects[index].field_6E = 0;
				// _vm->_mult->_objects[index].field_6A = variables;
				warning("Map_v2::loadMapObjects(): ID == 65533 (%d)", index);
				break;
			}
			case 65534:
				_tilesWidth     = READ_VARO_UINT8(var);
				_tilesHeight    = READ_VARO_UINT8(var + 1);
				_mapWidth       = READ_VARO_UINT8(var + 2);
				_mapHeight      = READ_VARO_UINT8(var + 3);
				_mapUnknownBool = READ_VARO_UINT8(var + 4) ? true : false;
				if (_mapUnknownBool)
					warning("Map_v2::loadMapObjects(): _mapUnknownBool == true");
				break;
			case 65535:
				_passMap = (int8 *)_vm->_inter->_variables->getAddressOff8(var);
				break;
			default:
				warning("Map_v2::loadMapObjects(): ID == %d", (uint16) id);
				break;
		}
		return;
	}

	Resource *resource = _vm->_game->_resources->getResource(id);
	if (!resource)
		return;

	Common::SeekableReadStream &mapData = *resource->stream();

	_mapVersion = mapData.readByte();
	if (_mapVersion == 4) {
		_screenWidth = 640;
		_screenHeight = 400;
	} else if (_mapVersion == 3) {
		_passWidth = 65;
		_screenWidth = 640;
		_screenHeight = 200;
	} else {
		_passWidth = 40;
		_screenWidth = 320;
		_screenHeight = 200;
	}

	_wayPointCount = mapData.readByte();
	_tilesWidth = mapData.readSint16LE();
	_tilesHeight = mapData.readSint16LE();

	_bigTiles = !(_tilesHeight & 0xFF00);
	_tilesHeight &= 0xFF;

	if (_mapVersion == 4) {
		_screenWidth = mapData.readSint16LE();
		_screenHeight = mapData.readSint16LE();
	}

	_mapWidth = _screenWidth / _tilesWidth;
	_mapHeight = _screenHeight / _tilesHeight;

	passPos = mapData.pos();
	mapData.skip(_mapWidth * _mapHeight);

	if (resource->getData()[0] == 1)
		wayPointsCount = _wayPointCount = 40;
	else
		wayPointsCount = _wayPointCount == 0 ? 1 : _wayPointCount;

	delete[] _wayPoints;
	_wayPoints = new WayPoint[wayPointsCount];
	for (int i = 0; i < _wayPointCount; i++) {
		_wayPoints[i].x = mapData.readSByte();
		_wayPoints[i].y = mapData.readSByte();
		_wayPoints[i].notWalkable = mapData.readSByte();
	}

	if (_mapVersion == 4) {
		_mapWidth  = VAR(17);
		_passWidth = _mapWidth;
	}

	// In the original asm, this writes byte-wise into the variables-array
	tmpPos = mapData.pos();
	mapData.seek(passPos);
	if ((variables != 0) &&
	    (variables != _vm->_inter->_variables->getAddressOff8(0))) {

		_passMap = (int8 *)variables;
		mapHeight = _screenHeight / _tilesHeight;
		mapWidth = _screenWidth / _tilesWidth;

		for (int i = 0; i < mapHeight; i++) {
			for (int j = 0; j < mapWidth; j++)
				setPass(j, i, mapData.readSByte());
			_vm->_inter->_variables->getAddressOff8(var + i * _passWidth);
		}
	}
	mapData.seek(tmpPos);

	tmp = mapData.readSint16LE();
	mapData.skip(tmp * 14);
	tmp = mapData.readSint16LE();
	mapData.skip(tmp * 14 + 28);
	tmp = mapData.readSint16LE();
	mapData.skip(tmp * 14);

	_vm->_goblin->_gobsCount = tmp;
	for (int i = 0; i < _vm->_goblin->_gobsCount; i++)
		loadGoblinStates(mapData, i);

	_vm->_goblin->_soundSlotsCount = _vm->_game->_script->readInt16();
	for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++)
		_vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1);

	delete resource;
}