1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef STARTREK_FIXEDINT_H 24 #define STARTREK_FIXEDINT_H 25 26 #include "common/serializer.h" 27 28 #include "startrek/common.h" 29 30 namespace StarTrek { 31 32 /** 33 * Signed fixed-point number. 34 */ 35 template<typename T, uint totalBits, uint decimalBits> 36 class TFixedInt : Common::Serializable { 37 static const int max = (1 << (totalBits - decimalBits - 1)) - 1; 38 static const int min = -max - 1; 39 40 T val; 41 42 public: fromRaw(T raw)43 static TFixedInt fromRaw(T raw) { 44 TFixedInt ret; 45 ret.val = raw; 46 return ret; 47 } 48 TFixedInt()49 TFixedInt() : val(0) {} TFixedInt(double d)50 TFixedInt(double d) { 51 assert(d >= min && d <= max); // FIXME: downgrade this to a warning? 52 val = (T)(d * (1 << decimalBits)); 53 } 54 55 /** 56 * Constructor from other fixed-point formats. 57 */ 58 template<typename T2, uint otherTB, uint otherDB> 59 explicit TFixedInt<T, totalBits, decimalBits>(const TFixedInt<T2, otherTB, otherDB> &fi) { 60 int diff = otherDB - decimalBits; 61 if (otherDB >= decimalBits) 62 val = fi.raw() >> diff; 63 else 64 val = fi.raw() << (-diff); 65 } 66 raw()67 T raw() const { 68 return val; 69 } 70 toInt()71 int16 toInt() const { 72 return val >> decimalBits; 73 } 74 toDouble()75 double toDouble() const { 76 return ((double)val) / (1 << decimalBits); 77 } 78 79 TFixedInt operator-() const { 80 return fromRaw(-val); 81 } 82 83 /** 84 * Multiplication with an int, with the result being an int. Use this if the result 85 * might exceed the capacity of this type. 86 */ multToInt(int32 i)87 int16 multToInt(int32 i) { 88 return ((int32)(val * i)) >> decimalBits; 89 } 90 91 /** 92 * Multiplication with an int, with the result being the same type. 93 */ 94 TFixedInt operator*(int32 i) const { 95 return fromRaw(val * i); 96 } 97 /** 98 * Multiplication with a FixedInt, with the result being the same type. 99 */ 100 TFixedInt operator*(const TFixedInt &f) const { 101 return fromRaw(((int32)(val * f.val)) >> decimalBits); 102 } 103 /** 104 * Division with an int, with the result being the same type. 105 */ 106 TFixedInt operator/(int32 i) const { 107 return fromRaw(val / i); 108 } 109 TFixedInt operator+(const TFixedInt &f) const { 110 return fromRaw(val + f.val); 111 } 112 TFixedInt operator-(const TFixedInt &f) const { 113 return fromRaw(val - f.val); 114 } 115 116 void operator+=(const TFixedInt &f) { 117 val += f.val; 118 } 119 void operator-=(const TFixedInt &f) { 120 val -= f.val; 121 } 122 123 bool operator==(double d) const { 124 return toDouble() == d; 125 } 126 bool operator!=(double d) const { 127 return toDouble() != d; 128 } 129 bool operator<(double d) const { 130 return toDouble() < d; 131 } 132 bool operator<=(double d) const { 133 return toDouble() <= d; 134 } 135 bool operator>(double d) const { 136 return toDouble() > d; 137 } 138 bool operator>=(double d) const { 139 return toDouble() >= d; 140 } 141 142 bool operator==(const TFixedInt &f) const { 143 return val == f.val; 144 } 145 bool operator!=(const TFixedInt &f) const { 146 return val != f.val; 147 } 148 bool operator<(const TFixedInt &f) const { 149 return val < f.val; 150 } 151 bool operator<=(const TFixedInt &f) const { 152 return val <= f.val; 153 } 154 bool operator>(const TFixedInt &f) const { 155 return val > f.val; 156 } 157 bool operator>=(const TFixedInt &f) const { 158 return val >= f.val; 159 } 160 saveLoadWithSerializer(Common::Serializer & ser)161 void saveLoadWithSerializer(Common::Serializer &ser) { 162 if (totalBits == 16) 163 ser.syncAsSint16LE(val); 164 else if (totalBits == 32) 165 ser.syncAsSint32LE(val); 166 else 167 error("Unsupported bit size for TFixedInt"); 168 } 169 }; 170 171 template<typename T, uint totalBits, uint decimalBits> 172 int32 operator*(const int16 lhs, const TFixedInt<T, totalBits, decimalBits> &rhs) { 173 return rhs * lhs; 174 } 175 176 177 // Fixed-point (2.14) number (between -1 and 1) 178 typedef TFixedInt<int16, 16, 14> Fixed14; 179 180 // Fixed-point (8.8) number 181 typedef TFixedInt<int16, 16, 8> Fixed8; 182 183 // Fixed-point (16.16) number 184 typedef TFixedInt<int32, 32, 16> Fixed16; 185 186 typedef Fixed8 Angle; 187 188 } // End of namespace StarTrek 189 190 #endif 191