/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * 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. * */ #ifndef STARTREK_FIXEDINT_H #define STARTREK_FIXEDINT_H #include "common/serializer.h" #include "startrek/common.h" namespace StarTrek { /** * Signed fixed-point number. */ template class TFixedInt : Common::Serializable { static const int max = (1 << (totalBits - decimalBits - 1)) - 1; static const int min = -max - 1; T val; public: static TFixedInt fromRaw(T raw) { TFixedInt ret; ret.val = raw; return ret; } TFixedInt() : val(0) {} TFixedInt(double d) { assert(d >= min && d <= max); // FIXME: downgrade this to a warning? val = (T)(d * (1 << decimalBits)); } /** * Constructor from other fixed-point formats. */ template explicit TFixedInt(const TFixedInt &fi) { int diff = otherDB - decimalBits; if (otherDB >= decimalBits) val = fi.raw() >> diff; else val = fi.raw() << (-diff); } T raw() const { return val; } int16 toInt() const { return val >> decimalBits; } double toDouble() const { return ((double)val) / (1 << decimalBits); } TFixedInt operator-() const { return fromRaw(-val); } /** * Multiplication with an int, with the result being an int. Use this if the result * might exceed the capacity of this type. */ int16 multToInt(int32 i) { return ((int32)(val * i)) >> decimalBits; } /** * Multiplication with an int, with the result being the same type. */ TFixedInt operator*(int32 i) const { return fromRaw(val * i); } /** * Multiplication with a FixedInt, with the result being the same type. */ TFixedInt operator*(const TFixedInt &f) const { return fromRaw(((int32)(val * f.val)) >> decimalBits); } /** * Division with an int, with the result being the same type. */ TFixedInt operator/(int32 i) const { return fromRaw(val / i); } TFixedInt operator+(const TFixedInt &f) const { return fromRaw(val + f.val); } TFixedInt operator-(const TFixedInt &f) const { return fromRaw(val - f.val); } void operator+=(const TFixedInt &f) { val += f.val; } void operator-=(const TFixedInt &f) { val -= f.val; } bool operator==(double d) const { return toDouble() == d; } bool operator!=(double d) const { return toDouble() != d; } bool operator<(double d) const { return toDouble() < d; } bool operator<=(double d) const { return toDouble() <= d; } bool operator>(double d) const { return toDouble() > d; } bool operator>=(double d) const { return toDouble() >= d; } bool operator==(const TFixedInt &f) const { return val == f.val; } bool operator!=(const TFixedInt &f) const { return val != f.val; } bool operator<(const TFixedInt &f) const { return val < f.val; } bool operator<=(const TFixedInt &f) const { return val <= f.val; } bool operator>(const TFixedInt &f) const { return val > f.val; } bool operator>=(const TFixedInt &f) const { return val >= f.val; } void saveLoadWithSerializer(Common::Serializer &ser) { if (totalBits == 16) ser.syncAsSint16LE(val); else if (totalBits == 32) ser.syncAsSint32LE(val); else error("Unsupported bit size for TFixedInt"); } }; template int32 operator*(const int16 lhs, const TFixedInt &rhs) { return rhs * lhs; } // Fixed-point (2.14) number (between -1 and 1) typedef TFixedInt Fixed14; // Fixed-point (8.8) number typedef TFixedInt Fixed8; // Fixed-point (16.16) number typedef TFixedInt Fixed16; typedef Fixed8 Angle; } // End of namespace StarTrek #endif