Odamex
Setting the Standard in Multiplayer Doom
common/m_fixed.h
Go to the documentation of this file.
00001 // Emacs style mode select   -*- C++ -*- 
00002 //-----------------------------------------------------------------------------
00003 //
00004 // $Id: m_fixed.h 1788 2010-08-24 04:42:57Z russellrice $
00005 //
00006 // Copyright (C) 1993-1996 by id Software, Inc.
00007 // Copyright (C) 2006-2010 by The Odamex Team.
00008 //
00009 // This program is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU General Public License
00011 // as published by the Free Software Foundation; either version 2
00012 // of the License, or (at your option) any later version.
00013 //
00014 // This program is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // DESCRIPTION:
00020 //      Fixed point arithemtics, implementation.
00021 //
00022 //-----------------------------------------------------------------------------
00023 
00024 
00025 #ifndef __M_FIXED__
00026 #define __M_FIXED__
00027 
00028 #include <stdlib.h>
00029 #include "doomtype.h"
00030 
00031 //
00032 // Fixed point, 32bit as 16.16.
00033 //
00034 #define FRACBITS                                16
00035 #define FRACUNIT                                (1<<FRACBITS)
00036 
00037 typedef int fixed_t;            // fixed 16.16
00038 typedef unsigned int dsfixed_t; // fixedpt used by span drawer
00039 
00040 extern "C" fixed_t FixedMul_ASM                         (fixed_t a, fixed_t b);
00041 extern "C" fixed_t STACK_ARGS FixedDiv_ASM      (fixed_t a, fixed_t b);
00042 fixed_t FixedMul_C                              (fixed_t a, fixed_t b);
00043 fixed_t FixedDiv_C                              (fixed_t a, fixed_t b);
00044 
00045 #ifdef ALPHA
00046 inline fixed_t FixedMul (fixed_t a, fixed_t b)
00047 {
00048     return (fixed_t)(((long)a * (long)b) >> 16);
00049 }
00050 
00051 inline fixed_t FixedDiv (fixed_t a, fixed_t b)
00052 {
00053     if (abs(a) >> 14 >= abs(b))
00054             return (a^b)<0 ? MININT : MAXINT;
00055         return (fixed_t)((((long)a) << 16) / b);
00056 }
00057 
00058 #else
00059 
00060 #ifdef USEASM
00061 
00062 #if defined(_MSC_VER)
00063 
00064 __inline fixed_t FixedMul (fixed_t a, fixed_t b)
00065 {
00066         fixed_t result;
00067         __asm {
00068                 mov             eax,[a]
00069                 imul    [b]
00070                 shrd    eax,edx,16
00071                 mov             [result],eax
00072         }
00073         return result;
00074 }
00075 
00076 #if 1
00077 // Inlining FixedDiv with VC++ generates too many bad optimizations.
00078 #define FixedDiv(a,b)                   FixedDiv_ASM(a,b)
00079 #else
00080 __inline fixed_t FixedDiv (fixed_t a, fixed_t b)
00081 {
00082         if (abs(a) >> 14 >= abs(b))
00083                 return (a^b)<0 ? MININT : MAXINT;
00084         else
00085         {
00086                 fixed_t result;
00087 
00088                 __asm {
00089                         mov             eax,[a]
00090                         mov             edx,[a]
00091                         sar             edx,16
00092                         shl             eax,16
00093                         idiv    [b]
00094                         mov             [result],eax
00095                 }
00096                 return result;
00097         }
00098 }
00099 #endif
00100 
00101 #else
00102 
00103 #define FixedMul(a,b)                   FixedMul_ASM(a,b)
00104 #define FixedDiv(a,b)                   FixedDiv_ASM(a,b)
00105 
00106 #endif
00107 
00108 #else // !USEASM
00109 #define FixedMul(a,b)                   FixedMul_C(a,b)
00110 #define FixedDiv(a,b)                   FixedDiv_C(a,b)
00111 #endif
00112 
00113 #endif // !ALPHA
00114 
00115 #endif
00116 
00117 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends