mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-25 19:25:20 +00:00
191 lines
4.5 KiB
C++
191 lines
4.5 KiB
C++
/* 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<typename T, uint totalBits, uint decimalBits>
|
|
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<typename T2, uint otherTB, uint otherDB>
|
|
explicit TFixedInt<T, totalBits, decimalBits>(const TFixedInt<T2, otherTB, otherDB> &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) override {
|
|
if (totalBits == 16)
|
|
ser.syncAsSint16LE(val);
|
|
else if (totalBits == 32)
|
|
ser.syncAsSint32LE(val);
|
|
else
|
|
error("Unsupported bit size for TFixedInt");
|
|
}
|
|
};
|
|
|
|
template<typename T, uint totalBits, uint decimalBits>
|
|
int32 operator*(const int16 lhs, const TFixedInt<T, totalBits, decimalBits> &rhs) {
|
|
return rhs * lhs;
|
|
}
|
|
|
|
|
|
// Fixed-point (2.14) number (between -1 and 1)
|
|
typedef TFixedInt<int16, 16, 14> Fixed14;
|
|
|
|
// Fixed-point (8.8) number
|
|
typedef TFixedInt<int16, 16, 8> Fixed8;
|
|
|
|
// Fixed-point (16.16) number
|
|
typedef TFixedInt<int32, 32, 16> Fixed16;
|
|
|
|
typedef Fixed8 Angle;
|
|
|
|
} // End of namespace StarTrek
|
|
|
|
#endif
|