/*************************************************************************** * Copyright (C) 2010 PCSX4ALL Team * * Copyright (C) 2010 Unai * * * * 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 02111-1307 USA. * ***************************************************************************/ #ifndef FIXED_H #define FIXED_H typedef s32 fixed; //senquack - The gpu_drhell poly routines I adapted use 22.10 fixed point, // while original Unai used 16.16: (see README_senquack.txt) //#define FIXED_BITS 16 #define FIXED_BITS 10 #define fixed_ZERO ((fixed)0) #define fixed_ONE ((fixed)1<>1)) #define fixed_LOMASK ((fixed)((1<fixed conversions: #define i2x(x) ((x)<>FIXED_BITS) INLINE fixed FixedCeil(const fixed x) { return (x + (fixed_ONE - 1)) & fixed_HIMASK; } INLINE s32 FixedCeilToInt(const fixed x) { return (x + (fixed_ONE - 1)) >> FIXED_BITS; } //senquack - float<->fixed conversions: #define f2x(x) ((s32)((x) * (float)(1< 0; ++i, x >>= 1); return i - 1; } #endif INLINE void xInv (const fixed _b, s32& iFactor_, s32& iShift_) { u32 uD = (_b<0) ? -_b : _b; if(uD>1) { u32 uLog = Log2(uD); uLog = uLog>(TABLE_BITS-1) ? uLog-(TABLE_BITS-1) : 0; u32 uDen = (uD>>uLog); iFactor_ = s_invTable[uDen]; iFactor_ = (_b<0) ? -iFactor_ :iFactor_; //senquack - Adapted to 22.10 fixed point (originally 16.16): //iShift_ = 15+uLog; iShift_ = 21+uLog; } else { iFactor_=_b; iShift_ = 0; } } INLINE fixed xInvMulx (const fixed _a, const s32 _iFact, const s32 _iShift) { #ifdef __arm__ s64 res; asm ("smull %Q0, %R0, %1, %2" : "=&r" (res) : "r"(_a) , "r"(_iFact)); return fixed(res>>_iShift); #else return fixed( ((s64)(_a)*(s64)(_iFact))>>(_iShift) ); #endif } INLINE fixed xLoDivx (const fixed _a, const fixed _b) { s32 iFact, iShift; xInv(_b, iFact, iShift); return xInvMulx(_a, iFact, iShift); } #endif // GPU_UNAI_USE_INT_DIV_MULTINV /////////////////////////////////////////////////////////////////////////// // --- END INVERSE APPROXIMATION SECTION --- /////////////////////////////////////////////////////////////////////////// #endif //FIXED_H