Exemplo n.º 1
0
reg_t reg_t::operator+(const reg_t right) const {
	if (isPointer() && right.isNumber()) {
		// Pointer arithmetics. Only some pointer types make sense here
		SegmentObj *mobj = g_sci->getEngineState()->_segMan->getSegmentObj(getSegment());

		if (!mobj)
			error("[VM]: Attempt to add %d to invalid pointer %04x:%04x", right.getOffset(), PRINT_REG(*this));

		switch (mobj->getType()) {
		case SEG_TYPE_LOCALS:
		case SEG_TYPE_SCRIPT:
		case SEG_TYPE_STACK:
		case SEG_TYPE_DYNMEM:
			return make_reg(getSegment(), getOffset() + right.toSint16());
		default:
			return lookForWorkaround(right, "addition");
		}
	} else if (isNumber() && right.isPointer()) {
		// Adding a pointer to a number, flip the order
		return right + *this;
	} else if (isNumber() && right.isNumber()) {
		// Normal arithmetics
		return make_reg(0, toSint16() + right.toSint16());
	} else {
		return lookForWorkaround(right, "addition");
	}
}
Exemplo n.º 2
0
reg_t reg_t::operator%(const reg_t right) const {
	if (isNumber() && right.isNumber() && !right.isNull()) {
		// Support for negative numbers was added in Iceman, and perhaps in
		// SCI0 0.000.685 and later. Theoretically, this wasn't really used
		// in SCI0, so the result is probably unpredictable. Such a case
		// would indicate either a script bug, or a modulo on an unsigned
		// integer larger than 32767. In any case, such a case should be
		// investigated, instead of being silently accepted.
		if (getSciVersion() <= SCI_VERSION_0_LATE && (toSint16() < 0 || right.toSint16() < 0))
			warning("Modulo of a negative number has been requested for SCI0. This *could* lead to issues");
		int16 value = toSint16();
		int16 modulo = ABS(right.toSint16());
		int16 result = value % modulo;
		if (result < 0)
			result += modulo;
		return make_reg(0, result);
	} else
		return lookForWorkaround(right, "modulo");
}
Exemplo n.º 3
0
reg_t reg_t::operator/(const reg_t right) const {
	if (isNumber() && right.isNumber() && !right.isNull())
		return make_reg(0, toSint16() / right.toSint16());
	else
		return lookForWorkaround(right, "division");
}
Exemplo n.º 4
0
reg_t reg_t::operator*(const reg_t right) const {
	if (isNumber() && right.isNumber())
		return make_reg(0, toSint16() * right.toSint16());
	else
		return lookForWorkaround(right, "multiplication");
}