home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 8.6 KB | 337 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: FWFxMath.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWOS.hpp"
-
- #ifndef FWFXMATH_H
- #include "FWFxMath.h"
- #endif
-
- #ifndef FWSTREAM_H
- #include "FWStream.h"
- #endif
-
- #ifdef FW_DEBUG
- #include <stdio.h>
- #endif
-
- #ifdef FW_BUILD_MAC
- #pragma segment fwodmisc_fixedmath
- #endif
-
- //========================================================================================
- // FW_Fixed
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_Sin
- //----------------------------------------------------------------------------------------
-
- FW_Fixed FW_Sin(FW_Fixed f)
- {
- #ifdef FW_BUILD_MAC68K
- // [BRP] Work around an OpenDoc bug on 68k machines that
- // !!! do not have an FPU installed, at the expense of precision
- FW_Fixed result;
- result.fRep = ::Frac2Fix(::FracSin(f.fRep));
- return result;
- #else
- ODFract fract = ODFractSinCos(f.fRep, NULL);
- return FW_ODFixedToFixed(fract >> 14);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_Cos
- //----------------------------------------------------------------------------------------
-
- FW_Fixed FW_Cos(FW_Fixed f)
- {
- #ifdef FW_BUILD_MAC68K
- // [BRP] Work around an OpenDoc bug on 68k machines that
- // !!! do not have an FPU installed, at the expense of precision
- FW_Fixed result;
- result.fRep = ::Frac2Fix(::FracCos(f.fRep));
- return result;
- #else
- ODFract frac;
- ODFractSinCos(f.fRep, &frac);
- return FW_ODFixedToFixed(frac >> 14);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_Sqrt
- //----------------------------------------------------------------------------------------
-
- FW_Fixed FW_Sqrt(FW_Fixed f)
- {
- ODWide wide;
- wide.hi = 0;
- wide.lo = f.fRep;
- ODWideShift(&wide, -16);
-
- ODFixed fixed = ODWideSquareRoot(&wide);
- return FW_ODFixedToFixed(fixed);
- }
-
- //========================================================================================
- // FW_Wide
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_IntToWide
- //----------------------------------------------------------------------------------------
-
- FW_Wide FW_IntToWide(int i)
- {
- ODWide w = { i, 0 };
- return FW_ODWideToWide(w);
- }
-
- //----------------------------------------------------------------------------------------
- // priv_f2w
- //----------------------------------------------------------------------------------------
-
- static FW_Wide priv_f2w(ODFixed lo)
- {
- long hi = (lo & 0x80000000) ? -1L : 0L;
- ODWide w = { hi, lo };
- ODWideShift(&w, -16);
- return FW_ODWideToWide(w);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_FixedToWide
- //----------------------------------------------------------------------------------------
-
- FW_Wide FW_FixedToWide(FW_Fixed f)
- {
- return priv_f2w(f.fRep);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_ODFixedToWide
- //----------------------------------------------------------------------------------------
-
- FW_Wide FW_ODFixedToWide(ODFixed f)
- {
- return priv_f2w(f);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_WideToInt
- //----------------------------------------------------------------------------------------
-
- int FW_WideToInt(const FW_Wide& w1)
- {
- ODWide w = w1.fRep;
- ODWide h = { 0, 0x80000000l };
- ODWideAdd(&w, &h);
- return w.hi;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_WideToODFixed
- //----------------------------------------------------------------------------------------
-
- ODFixed FW_WideToODFixed(const FW_Wide& w1)
- {
- ODWide w = w1.fRep;
- ODWide h = { 0, 0x00008000l };
- ODWideAdd(&w, &h);
-
- const signed long FW_kPrivMaxSignedWideToFixedInt = 0x00007FFF;
- const signed long FW_kPrivMinSignedWideToFixedInt = 0xFFFF8000;
-
- const ODFixed FW_kPrivMaxFixed = 0x7FFFFFFF;
- const ODFixed FW_kPrivMinFixed = 0x80000000;
-
- if (w.hi > FW_kPrivMaxSignedWideToFixedInt)
- return FW_kPrivMaxFixed;
-
- if (w.hi < FW_kPrivMinSignedWideToFixedInt)
- return FW_kPrivMinFixed;
-
- return (w.hi << 16) | (w.lo >> 16);
- }
-
- //----------------------------------------------------------------------------------------
- // operator +
- //----------------------------------------------------------------------------------------
-
- FW_Wide operator + (const FW_Wide& w1, const FW_Wide& w2)
- {
- ODWide w = w1.fRep;
- ODWideAdd(&w, &w2.fRep);
- return FW_ODWideToWide(w);
- }
-
- //----------------------------------------------------------------------------------------
- // operator -
- //----------------------------------------------------------------------------------------
-
- FW_Wide operator - (const FW_Wide& w1, const FW_Wide& w2)
- {
- ODWide w = w1.fRep;
- ODWideSubtract(&w, &w2.fRep);
- return FW_ODWideToWide(w);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_WideMultiply
- //----------------------------------------------------------------------------------------
-
- FW_Wide FW_WideMultiply (FW_Fixed f1, FW_Fixed f2)
- {
- ODWide w;
- ODWideMultiply(f1.fRep, f2.fRep, &w);
- return FW_ODWideToWide(w);
- }
-
- //----------------------------------------------------------------------------------------
- // operator /
- //----------------------------------------------------------------------------------------
-
- FW_Fixed operator / (const FW_Wide& w1, FW_Fixed f2)
- {
- return FW_ODFixedToFixed(ODWideDivide(&w1.fRep, f2.fRep, NULL));
- }
-
- //========================================================================================
- // Global operators << and >>
- //========================================================================================
-
- FW_CWritableStream& operator<<(FW_CWritableStream& stream, const FW_Fixed& fx)
- {
- stream << fx.fRep;
- return stream;
- }
-
- FW_CReadableStream& operator>>(FW_CReadableStream& stream, FW_Fixed& fx)
- {
- stream >> fx.fRep;
- return stream;
- }
-
- #ifdef FW_DEBUG
-
- //========================================================================================
- // Debug versions of math operators
- //========================================================================================
-
- static void FixedError(FW_Fixed f1, FW_Fixed f2, const char* lpsz)
- {
- char buf[250];
- sprintf(buf, "Fixed error: %s, %.2f, %.2f", lpsz, FW_FixedToDouble(f1), FW_FixedToDouble(f2));
- FW_DEBUG_MESSAGE(buf);
- }
-
- FW_Fixed operator+(FW_Fixed f1, FW_Fixed f2)
- {
- long rep1 = f1.fRep;
- long rep2 = f2.fRep;
-
- long repr = (rep1 >> 16) + (rep2 >> 16);
-
- if (repr < -32768 || repr > 32767)
- FixedError(f1, f2, "Add oflw");
-
- return FW_ODFixedToFixed(f1.fRep + f2.fRep);
- }
-
- FW_Fixed operator-(FW_Fixed f1, FW_Fixed f2)
- {
- long rep1 = f1.fRep;
- long rep2 = f2.fRep;
-
- long repr = (rep1 >> 16) - (rep2 >> 16);
-
- if (repr < -32768 || repr > 32767)
- FixedError(f1, f2, "Sub oflw");
-
- return FW_ODFixedToFixed(f1.fRep - f2.fRep);
- }
-
- FW_Wide& operator += (FW_Wide& w1, const FW_Fixed& f2)
- {
- FW_Wide w2 = FW_FixedToWide(f2);
- return w1 += w2;
- }
-
- FW_Wide& operator -= (FW_Wide& w1, const FW_Fixed& f2)
- {
- FW_Wide w2 = FW_FixedToWide(f2);
- return w1 -= w2;
- }
-
- FW_Fixed operator*(FW_Fixed f1, FW_Fixed f2)
- {
- long rep1 = f1.fRep;
- long rep2 = f2.fRep;
-
- long repr = (rep1 >> 16) * (rep2 >> 16);
-
- if (repr < -32768 || repr > 32767)
- FixedError(f1, f2, "Mul oflw");
-
- return FW_ODFixedToFixed(ODFixedMultiply(f1.fRep, f2.fRep));
- }
-
- FW_Fixed operator/(FW_Fixed f1, FW_Fixed f2)
- {
- if (f2.fRep == 0)
- FixedError(f1, f2, "Div by 0");
-
- return FW_ODFixedToFixed(ODFixedDivide(f1.fRep, f2.fRep));
- }
-
- #endif
-
- #include <math.h>
-
- // #ifdef FW_BUILD_WIN
- // [KVV] OpenDoc DR2 for Windows is missing the following routines
-
- #ifdef FW_BUILD_WIN
- ODFract ODFractSinCos(ODFixed angle, ODFract *cosResult)
- {
- FW_Double flAngle = ODFixedToDouble(angle);
-
- FW_Double flSin = sin(flAngle);
- FW_Double flCos = cos(flAngle);
-
- ODFixed fxSin = ODDoubleToFixed(flSin);
- ODFixed fxCos = ODDoubleToFixed(flCos);
-
- if(cosResult != NULL)
- *cosResult = ODFixedToFract(fxCos);
-
- return ODFixedToFract(fxSin);
- }
- #endif
-
- #ifdef FW_BUILD_WIN
-
- ODULong ODWideSquareRoot(const ODWide *src)
- {
- if(src->hi == 0 && src->lo == 0)
- return 0;
-
- if(src->hi < 0)
- return 0x7FFFFFFFl;
-
- FW_Double d = src->hi + src->lo / 4294967296.0;
- FW_Double s = sqrt(d);
-
- return ODDoubleToFixed(s);
- }
-
- #endif
-