Operators vs Macros

New to FreeBASIC? Post your questions here.
AWPStar
Posts: 42
Joined: May 03, 2009 21:47

Operators vs Macros

Postby AWPStar » Mar 22, 2021 22:26

I want make fixed-point udt and work with it like with any other types.
It not very convenient to use something like that "fpAdd(1, 2)"
But for operators fbc generates functions and it slows the speed of code.
Is there any solution for this?
D.J.Peters
Posts: 8297
Joined: May 28, 2005 3:28
Contact:

Re: Operators vs Macros

Postby D.J.Peters » Mar 22, 2021 23:26

BASIC macros are the fastest solution instead of overwrite math operators.
Inline assembler for fixed point math are a massive speed boost for fixed point math.

Joshy
D.J.Peters
Posts: 8297
Joined: May 28, 2005 3:28
Contact:

Re: Operators vs Macros

Postby D.J.Peters » Mar 22, 2021 23:30

Mix of macros and high level operators.

Joshy

Code: Select all

'#define _DEBUG

#ifdef _DEBUG
  #define dprint(msg) : scope : dim as integer h=FreeFile() : open err for output as #h:print #h,msg:close #h : end scope
#else
  #define dprint(msg) :
#endif

'        32 bit 16,16 fixed point math

' 0111111111111111,000000000000000 = 32767
'                ...
'  100000000000000,000000000000000 = 8192
'   10000000000000,000000000000000 = 4096
'    1000000000000,000000000000000 = 2048
'     100000000000,000000000000000 = 1024
'      10000000000,000000000000000 = 512
'        100000000,000000000000000 = 256
'         10000000,000000000000000 = 128
'          1000000,000000000000000 = 64
'           100000,000000000000000 = 32
'            10000,000000000000000 = 16
'             1000,000000000000000 = 8
'              100,000000000000000 = 4
'               10,000000000000000 = 2
'                1,000000000000000 = 1
'                0,111111111111111 = 0.9999847
'                0,100000000000000 = 0.5
'                0,010000000000000 = 0.25
'                0,001000000000000 = 0.125
'                0,000100000000000 = 0.0625
'                0,000010000000000 = 0.03125
'                0,000001000000000 = 0.015625
'                0,000000100000000 = 0.0078125
'                0,000000010000000 = 0.00390625
'                0,000000001000000 = 0.001953125
'                0,000000000100000 = 0.0009765625
'                0,000000000010000 = 0.00048828125
'                0,000000000001000 = 0.000244140625
'                0,000000000000100 = 0.0001220703125
'                0,000000000000010 = 0.00006103515625
'                0,000000000000001 = 0.000030517578125


' 0111111111111111,000000000000000 = 32767.0
'                ...
' 0000000000000100,000000000000000 = 4.0
' 0000000000000010,000000000000000 = 2.0
' 0000000000000001,000000000000000 = 1.0
' 0000000000000000,000000000000000 = 0.0
' 1111111111111111,000000000000000 =-1.0
' 1111111111111110,000000000000000 =-2.0
' 1111111111111100,000000000000000 =-4.0
'                ...
' 1000000000000000,0               =-32768.0

type FP32 as long

#define TAB_MAX (1024) ' !!! must be power of two !!!
#define TAB_MASK (TAB_MAX-1)

dim shared as FP32 FP32SINTAB(TAB_MASK)
dim shared as FP32 FP32COSTAB(TAB_MASK)

#define FONE 65536   ' 1.0    in fixed point
#define FPI  205887  ' PI     in fixed point
#define FPI2 411775  ' PI*2.0 in fixed point


' r=S2F(x) single to fixed
#define S2F(x_) ((x_)*(1 shl 16))

' r=f/(1 shl 16) fixed to single
#define F2S(x_) ((x_)/65536.0f)

' r=integer to fixed
#define I2F(x_) ((x_) shl 16)

' r=fixed to integer
#define F2I(x_) ((x_) shr 16)

' r=rounded(fixed) to integer
#define RF2I(x_)(((x_)+&H8000) shr 16)

' r=x+y
#define FAdd(x_,y_) ((x_)+(y_))

' r=x-y
#define FSub(x_,y_) ((x_)-(y_))

' r=x*y
#define FMul(x_, y_) ( (clngint(x_)*(y_)) shr 16)

' r=x/y
#define FDiv(x_, y_) ( ((clngint(x_) shl 16)) / (y_))

' r=1.0/x
#define FInv(x_) (1 shl 16)/(x_)

' r=x^x
#define FSqrd(x_) FMul(x_,x_)

' create sin cos fixed point array
sub _module_init_ constructor
  dim as single w,s=atn(4)/TAB_MAX
  for i as integer =0 to TAB_MASK
    dim as single si=sin(w),co=cos(w)
    FP32SINTAB(i)=S2F(si)
    FP32COSTAB(i)=S2F(co)
    w+=s
  next
end sub
' fixed point squarroot
function FSqr(x as FP32) as FP32
  dim as FP32 t=any, q=0, b=&H40000000, r=x
  while( b > &H40 )
    t = q + b
    if ( r >= t ) then r-=t : q=t+b
    r shl= 1
    b shr= 1
  wend
  q shr= 8
  return q
end function

' fixed point sin
function FSin(ang as integer) as FP32
  ang and=TAB_MASK
  return FP32SINTAB(ang)
end function
' fixed point cos
function FCos(ang as integer) as FP32
  ang and=TAB_MASK
  return FP32SINTAB(ang)
end function
' fixed point tan
function FTan(ang as integer) as FP32
  ang and=TAB_MASK
  return (FDiv(FP32SINTAB(ang) shl 16, FP32COSTAB(ang)) shr 16)
end function
' fixed point cos and sin
sub FCosSin(ang as integer,pCos as FP32 ptr,pSin as FP32 ptr)
  ang and=TAB_MASK
  *pCos=FP32COSTAB(ang)
  *pSin=FP32SINTAB(ang)
end sub

' fixed point 3D vector
type VECTOR
  declare constructor
  ' pixel to VECTOR
  declare constructor(byval ui as ulong)
  declare constructor(byval sx as single,_
                      byval sy as single,_
                      byval sz as single)

  declare constructor(byref fx as FP32,_
                      byref fy as FP32,_
                      byref fz as FP32)

  declare constructor(byref v as VECTOR)

  declare operator cast as string
  ' VECTOR to pixel color pset(x,y),vector
  declare operator cast as ulong

  declare operator +=(byref v as VECTOR)

  declare operator -=(byref v as VECTOR)

  declare operator *=(byref s as FP32)

  declare operator /=(byref s as FP32)

  declare function LengthSqrd as FP32

  declare function Length as FP32

  declare function Distance(byref v as VECTOR) as FP32

  declare function Normalized as VECTOR

  declare sub      Normalize
  as FP32 x=any,y=any,z=any
end type
dim shared as VECTOR _v

constructor VECTOR (byval ui as ulong)
  dprint("VECTOR(pixel)")
  dim as long r = ui and 255 : ui shr= 8
  dim as long g = ui and 255 : ui shr= 8
  dim as long b = ui and 255
  x=I2F(r) : y=I2F(g) : z=I2F(b)
end constructor

constructor VECTOR
  dprint("VECTOR()")
  x=0:y=0:z=0
end constructor

constructor VECTOR(sx as single,_
                   sy as single,_
                   sz as single)
  dprint("VECTOR(s,s,s)")
  x=S2F(sx) : y=S2F(sy) : z=S2F(sz)
end constructor

constructor VECTOR(byref fx as FP32,_
                   byref fy as FP32,_
                   byref fz as FP32)
  dprint("VECTOR(fp,fp,fp)")
  x=fx : y=fy : z=fz
end constructor

constructor VECTOR(byref v as VECTOR)
  dprint("VECTOR(VECTOR)")
  x=v.x : y=v.y : z=v.z
end constructor

operator VECTOR.cast as ulong
  dprint("pixel=VECTOR")
  dim as ulong ur=any,ug=any,ub=any
  dim as single s = F2S(x)
  if s<0 then s = -s
  if s=0 then
    ur=0
  elseif s>1 then
    ur=255
  else
    ur=s*255
  end if
  s = F2S(y)
  if s<0 then s = -s
  if s=0 then
    ug=0
  elseif s>1 then
    ug=255
  else
    ug=s*255
  end if
  s = F2S(z)
  if s<0 then s = -s
  if s=0 then
    ub=0
  elseif s>1 then
    ub=255
  else
    ub=s*255
  end if
  operator = RGB(ur,ug,ub)
end operator

operator VECTOR.cast as string
  return "V(" & F2S(x) & "," & F2S(y) & "," & F2S(z) & ")"
end operator

operator VECTOR.+=(byref v as VECTOR)
  dprint("+=v")
  x+=v.x : y+=v.x : z+=v.x
end operator

operator VECTOR.-=(byref v as VECTOR)
  x-=v.x : y-=v.x : z-=v.x
end operator

operator VECTOR.*=(byref s as FP32)
  dprint("*=s")
  x=fmul(x,s)
  y=fmul(y,s)
  z=fmul(z,s)
end operator

operator VECTOR./=(byref s as FP32)
  dprint("/=s")
  if s=0 then
    x=0:y=0:z=0
  else
    dim as FP32 inv=FInv(s)
    x=fmul(x,inv)
    y=fmul(y,inv)
    z=fmul(z,inv)
  end if
end operator

operator +(byref l as VECTOR,byref r as VECTOR) as VECTOR
  dprint("v+v")
  return type<VECTOR>(l.x+r.x, l.y+r.y, l.z+r.z)
end operator

operator -(byref l as VECTOR,byref r as VECTOR) as VECTOR
  dprint("v-v")
  return type<VECTOR>(l.x-r.x, l.y-r.y, l.z-r.z)
end operator

operator *(byref l as VECTOR,byref r as FP32) as VECTOR
  dprint("v*s")
  return type<VECTOR>(fmul(l.x,r),fmul(l.y,r),fmul(l.z,r))
end operator

operator *(byref l as FP32, byref r as VECTOR) as VECTOR
  dprint("s*v")
  return type<VECTOR>(fmul(l,r.x),fmul(l,r.y),fmul(l,r.z))
end operator

' dot product
operator *(byref l as VECTOR,byref r as VECTOR) as FP32
  dprint("v*v")
  return fmul(l.x,r.x)+fmul(l.y,r.y)+fmul(l.z,r.z)
end operator

' cross product
operator \(byref l as VECTOR,byref r as VECTOR) as VECTOR
  dprint("v\v")
  return type<VECTOR>(fmul(l.y,r.z)-fmul(l.z,r.y), _
                      fmul(l.z,r.x)-fmul(l.x,r.z), _
                      fmul(l.x,r.y)-fmul(l.y,r.x))
end operator

function VECTOR.LengthSqrd as FP32
  dprint("VECTOR.LengthSqrd()")
  return fsqrd(x)+fsqrd(y)+fsqrd(z)
end function

function VECTOR.Length as FP32
  dprint("VECTOR.Length()")
  return fsqr(fsqrd(x)+fsqrd(y)+fsqrd(z))
end function

function VECTOR.Distance(byref other as VECTOR) as FP32
  dprint("VECTOR.Distance(VECTOR)")
  _v = this-other
  var _l = fsqrd(_v.x) + fsqrd(_v.y) + fsqrd(_v.z)
  if _l<>0 then  _l = fsqr(_l)
  return _l
end function

function VECTOR.Normalized as VECTOR
  dprint("VECTOR.Normalized()")
  var _l = fsqrd(x)+fsqrd(y)+fsqrd(z)
  if _l=0 then
    _v.x=0:_v.y=0:_v.z=0
  else
    _l=finv(fsqr(_l))
    _v.x=fmul(x,_l)
    _v.y=fmul(y,_l)
    _v.z=fmul(z,_l)
  end if
  return _v
end function

sub VECTOR.Normalize
  dprint("VECTOR.Normalize")
  var _l = fsqrd(x)+fsqrd(y)+fsqrd(z)
  if _l=0 then
    x=0 : y=0 : z=0
  else
    _l=FInv(fsqr(_l))
    x=fmul(x,_l)
    y=fmul(y,_l)
    z=fmul(z,_l)
  end if
end sub

' a 4x3 fixed point matrix
' last row asumed 0,0,0,1
type MATRIX
  declare constructor

  declare constructor(byref m as MATRIX)

  declare constructor(byref r00 as FP32,byref r01 as FP32,byref r02 as FP32, _
                      byref r10 as FP32,byref r11 as FP32,byref r12 as FP32, _
                      byref r20 as FP32,byref r21 as FP32,byref r22 as FP32)

  declare constructor(byref r00 as FP32,byref r01 as FP32,byref r02 as FP32,byref r03 as FP32, _
                      byref r10 as FP32,byref r11 as FP32,byref r12 as FP32,byref r13 as FP32, _
                      byref r20 as FP32,byref r21 as FP32,byref r22 as FP32,byref r23 as FP32)

  declare constructor(byref a as VECTOR, _
                      byref b as VECTOR, _
                      byref c as VECTOR)

  declare constructor(byref a as VECTOR, _
                      byref b as VECTOR, _
                      byref c as VECTOR, _
                      byref t as VECTOR)

  declare sub Identity

  declare sub Scale    (byref s as FP32)

  declare sub Scale    (byref v as VECTOR)

  declare sub Translate(byref v as VECTOR)

  declare sub Pitch    (byval ang as integer)

  declare sub Yaw      (byval ang as integer)

  declare sub Roll     (byval ang as integer)

  declare sub PYR      (byval p as integer, _
                        byval y as integer, _
                        byval r as integer)

  declare function Rotate   (byref v as VECTOR) as VECTOR

  declare function Transform(byref v as VECTOR) as VECTOR
 
  as FP32 m00=any,m01=any,m02=any,m03=any
  as FP32 m10=any,m11=any,m12=any,m13=any
  as FP32 m20=any,m21=any,m22=any,m23=any
end type
dim shared as MATRIX _p,_y,_r
constructor MATRIX
end constructor

constructor MATRIX(byref m as MATRIX)
  dprint("MATRIX(MATRIX)")
  m00=m.m00:m01=m.m01:m02=m.m02:m03=m.m03
  m10=m.m10:m11=m.m11:m12=m.m12:m13=m.m13
  m20=m.m20:m21=m.m21:m22=m.m22:m23=m.m23
end constructor

constructor MATRIX(byref r00 as FP32,byref r01 as FP32,byref r02 as FP32, _
                   byref r10 as FP32,byref r11 as FP32,byref r12 as FP32, _
                   byref r20 as FP32,byref r21 as FP32,byref r22 as FP32)
  dprint("MATRIX(FP,...)")
  m00=r00:m01=r01:m02=r02:m03=0
  m10=r10:m11=r11:m12=r12:m13=0
  m20=r20:m21=r21:m22=r22:m23=0
end constructor


constructor MATRIX(byref r00 as FP32,byref r01 as FP32,byref r02 as FP32,byref r03 as FP32, _
                   byref r10 as FP32,byref r11 as FP32,byref r12 as FP32,byref r13 as FP32, _
                   byref r20 as FP32,byref r21 as FP32,byref r22 as FP32,byref r23 as FP32)
  dprint("MATRIX(FP,...)")
  m00=r00:m01=r01:m02=r02:m03=r03
  m10=r10:m11=r11:m12=r12:m13=r13
  m20=r20:m21=r21:m22=r22:m23=r23
end constructor

constructor MATRIX(byref a as VECTOR, _
                   byref b as VECTOR, _
                   byref c as VECTOR)
  dprint("MATRIX(VECTOR,...)")
  m00=a.x : m01=a.y : m02=a.z : m03=0
  m10=b.x : m11=b.y : m12=b.z : m13=0
  m20=c.x : m21=c.y : m22=c.z : m23=0
end constructor

constructor MATRIX(byref a as VECTOR, _
                   byref b as VECTOR, _
                   byref c as VECTOR, _
                   byref t as VECTOR)
  dprint("MATRIX(VECTOR,...)")
  m00=a.x : m01=a.y : m02=a.z : m03=t.x
  m10=b.x : m11=b.y : m12=b.z : m13=t.y
  m20=c.x : m21=c.y : m22=c.z : m23=t.z
end constructor

sub MATRIX.Identity
  dprint("MATRIX.Identity")
  m00=FONE: m01=0   : m02=0   : m03=0
  m10=0   : m11=FONE: m12=0   : m13=0
  m20=0   : m21=0   : m22=FONE: m23=0
end sub

sub MATRIX.Scale(byref s as FP32)
  dprint("MATRIX.Scale(s)")
  m00=s: m01=0: m02=0: m03=0
  m10=0: m11=s: m12=0: m13=0
  m20=0: m21=0: m22=s: m23=0
end sub

sub MATRIX.Scale(byref v as VECTOR)
  dprint("MATRIX.Scale(VECTOR)")
  m00=v.x: m01=0  : m02=0  : m03=0
  m10=0  : m11=v.y: m12=0  : m13=0
  m20=0  : m21=0  : m22=v.z: m23=0
end sub

sub MATRIX.Translate(byref v as VECTOR)
  dprint("MATRIX.Translate(VECTOR)")
  m00=FONE: m01=0   : m02=0   : m03=v.x
  m10=0   : m11=FONE: m12=0   : m13=v.y
  m20=0   : m21=0   : m22=FONE: m23=v.z
end sub

sub MATRIX.Pitch(byval ang as integer)
  dprint("MATRIX.Pitch(ang)")
  ang and=TAB_MASK
  var s=FP32SINTAB(ang)
  var c=FP32COSTAB(ang)
  m00=FONE: m01= 0 : m02= 0: m03=0
  m10=0   : m11= c : m12= s: m13=0
  m20=0   : m21=-s : m22=-c: m23=0
end sub

sub MATRIX.Yaw(byval ang as integer)
  dprint("MATRIX.Yaw(ang)")
  ang and=TAB_MASK
  var s=FP32SINTAB(ang)
  var c=FP32COSTAB(ang)
  m00= c: m01= 0   : m02=-s: m03=0
  m10= 0: m11= FONE: m12= 0: m13=0
  m20=-s: m21= 0   : m22= c: m23=0
end sub

sub MATRIX.Roll(byval ang as integer)
  dprint("MATRIX.Roll(ang)")
  ang and=TAB_MASK
  var s=FP32SINTAB(ang)
  var c=FP32COSTAB(ang)
  m00= c: m01= s: m02= 0  : m03=0
  m10=-s: m11= c: m12= 0  : m13=0
  m20= 0: m21= 0: m22=FONE: m23=0
end sub

operator *(byref l as MATRIX,byref r as MATRIX) as MATRIX
  dprint("MATRIX*MATRIX")
  _p.m00 = fmul(l.m00,r.m00) + fmul(l.m01,r.m10) + fmul(l.m02,r.m20)
  _p.m01 = fmul(l.m00,r.m01) + fmul(l.m01,r.m11) + fmul(l.m02,r.m21)
  _p.m02 = fmul(l.m00,r.m02) + fmul(l.m01,r.m12) + fmul(l.m02,r.m22)
  _p.m03 = fmul(l.m00,r.m03) + fmul(l.m01,r.m13) + fmul(l.m02,r.m23) + l.m03

  _p.m10 = fmul(l.m10,r.m00) + fmul(l.m11,r.m10) + fmul(l.m12,r.m20)
  _p.m11 = fmul(l.m10,r.m01) + fmul(l.m11,r.m11) + fmul(l.m12,r.m21)
  _p.m12 = fmul(l.m10,r.m02) + fmul(l.m11,r.m12) + fmul(l.m12,r.m22)
  _p.m13 = fmul(l.m10,r.m03) + fmul(l.m11,r.m13) + fmul(l.m12,r.m23) + l.m13

  _p.m20 = fmul(l.m20,r.m00) + fmul(l.m21,r.m10) + fmul(l.m22,r.m20)
  _p.m21 = fmul(l.m20,r.m01) + fmul(l.m21,r.m11) + fmul(l.m22,r.m21)
  _p.m22 = fmul(l.m20,r.m02) + fmul(l.m21,r.m12) + fmul(l.m22,r.m22)
  _p.m23 = fmul(l.m20,r.m03) + fmul(l.m21,r.m13) + fmul(l.m22,r.m23) + l.m23
  operator = _p
end operator

sub MATRIX.PYR(byval p as integer, _
               byval y as integer, _
               byval r as integer)
  dprint("MATRIX.PYR(p,y,r)")
  _p.Pitch(p)
  _y.Yaw  (y)
  _r.Roll (r)
  this=_p*_y*_r
end sub

function MATRIX.Rotate(byref v as VECTOR) as VECTOR
  dprint("MATRIX.Rotate")
  return type<VECTOR>(fmul(m00,v.x) + fmul(m01,v.y) + fmul(m02,v.z), _
                      fmul(m10,v.x) + fmul(m11,v.y) + fmul(m12,v.z), _
                      fmul(m20,v.x) + fmul(m21,v.y) + fmul(m22,v.z))
end function

function MATRIX.Transform(byref v as VECTOR) as VECTOR
  dprint("MATRIX.Transform")
  return type<VECTOR>(fmul(m00,v.x) + fmul(m01,v.y) + fmul(m02,v.z) + m03, _
                      fmul(m10,v.x) + fmul(m11,v.y) + fmul(m12,v.z) + m13, _
                      fmul(m20,v.x) + fmul(m21,v.y) + fmul(m22,v.z) + m23)
end function



type RAY
  declare constructor
  declare constructor(byref o as VECTOR,byref d as VECTOR)
  as VECTOR Origin
  as VECTOR Direction
  as FP32   ODot
  as FP32   DDot
  as FP32   t
end type

constructor RAY
  dprint("RAY()")
  Direction.z=FONE
  DDot=fsqrd(Direction.z)
end constructor

constructor RAY(byref o as VECTOR, _
                byref d as VECTOR)
  dprint("RAY(VECTOR,VECTOR)")
  Origin   =o
  Direction=d
  ODot=fsqrd(Origin.x)+fsqrd(Origin.y)+fsqrd(Origin.z)
  DDot=fsqrd(Direction.x)+fsqrd(Direction.y)+fsqrd(Direction.z)
end constructor

type SPHERE
  declare constructor
  declare constructor(byref c as VECTOR, _
                      byval r as FP32)
  declare constructor(byval cx as single, _
                      byval cy as single, _
                      byval cz as single, _
                      byval r  as single)
  declare function Intersection(byref r as RAY) as boolean
  as VECTOR Center
  as FP32   Radius,R2,CDot
end type

constructor SPHERE
  dprint("SPHERE()")
  Radius=S2F(0.5)
  R2=fsqrd(Radius)
end constructor

constructor SPHERE(byref c as VECTOR, _
                   byval r as FP32)
  dprint("SPHERE(VECTOR,FP32)")
  Center=c
  Radius=r
  R2=fsqrd(Radius)
  CDot=fsqrd(Center.x)+fsqrd(Center.y)+fsqrd(Center.z)
end constructor

constructor SPHERE(byval cx as single, _
                   byval cy as single, _
                   byval cz as single, _
                   byval r  as single)
  dprint("SPHERE(sX,sY,sZ,sRadius)")
  Center.x=S2F(cx)
  Center.y=S2F(cy)
  Center.z=S2F(cz)
  Radius=S2F(r)
  R2=fsqrd(Radius)
  CDot=fsqrd(Center.x)+fsqrd(Center.y)+fsqrd(Center.z)
end constructor

function SPHERE.Intersection(byref r as RAY) as boolean
  dim as FP32 L=r.DDot
  If L=0 Then beep:return false
  dim as FP32 M=fmul(fmul(&H20000,r.Direction.x),r.Origin.X-Center.X) _
               +fmul(fmul(&H20000,r.Direction.y),r.Origin.Y-Center.Y) _
               +fmul(fmul(&H20000,r.Direction.z),r.Origin.Z-Center.Z)
  dim as FP32 N = CDot+r.ODot - fmul(&H20000,Center*r.Origin) - R2
  dim as FP32 T = fsqrd(M) - fmul(&H40000 ,fmul(L,N))
  if (T<0) then return false
  L=fmul(&H20000,L)
  if (T=0) then
    T = fdiv(-M,L)
    if (T<=0) then return false
    r.t=T
    return true
  else ' two hit points
    T=fsqr(T)
    dim as FP32 T1 = fdiv(-M - T,L)
    dim as FP32 T2 = fdiv(-M + T,L)
    If (T1 < &B100000) Then T1 = 0
    If (T2 < &B100000) Then T2 = 0
    ' no hits
    If (t1=0 andalso t2=0) Then return false
    ' both are ok
    If T1 > 0 andalso T2 > 0 Then
      If T1 < T2 Then
        r.t=T1
      else
        r.t=T2
      end if
    Else ' one are ok
      If T1 > 0 Then
        r.t=T1
      Else
        r.t=T2
      end if
    End If
    return true
  End If
end function

dim as SPHERE Sph = SPHERE(VECTOR(S2F(0),S2F(0),S2F(2)),S2F(.5))
dim as VECTOR Origin
dim as VECTOR Direction


dim as integer scr_w,scr_h,scr_p
screeninfo scr_w,scr_h
scr_w*=0.5
scr_h*=0.5
screenres scr_w,scr_h,32,2
screenset 1,0

screeninfo scr_w,scr_h,,,scr_p

dim as single xr,yr

scr_p shr=2

if scr_w>scr_h then
  xr=scr_w/scr_h
  yr=1.0
else
  yr=scr_w/scr_h
  xr=1.0
end if
dim as single xs=xr/scr_w
dim as single ys=yr/scr_h
xr*=0.5
yr*=0.5

Origin.x = S2F(0.0)
Origin.y = S2F(0.0)
Origin.z = S2F(-.5)

Direction.z=S2F(2.4)

dim as ulong ptr row


  cls
  row=screenptr()
  for y as single=0 to scr_h-1
    Direction.y=S2F(-yr+y*ys)
    dim as ulong ptr pixel = row
    for x as single=0 to scr_w-1
      Direction.x=S2F(-xr+x*xs)
      dim as RAY r=Ray(Origin,Direction)
      if Sph.Intersection(r) then
        dim as VECTOR h=Origin+Direction*r.t
        dim as VECTOR N=h-sph.center
        pixel[x]=N ' cast vector to RGB (ulong)
      end if
    next
    row+=scr_p ' row += pitch in pixels
  next
  flip
 sleep
AWPStar
Posts: 42
Joined: May 03, 2009 21:47

Re: Operators vs Macros

Postby AWPStar » Apr 11, 2021 21:48

D.J.Peters

Code: Select all

dim shared as long sqrlu(1024)

function fpSqr(_x as ulong) as long
   ' 1.4142135
   if _x<=1024 then
      return sqrlu(_x shr 0) \ 1448 '(1482910/1024) 'shr 11
   elseif _x<=2048 then
      return sqrlu(_x shr 1) \ 1024 '(1482910/1024)
   elseif _x<=4096 then
      return sqrlu(_x shr 2) \ 724
   elseif _x<=8192 then
      return sqrlu(_x shr 3) \ 512
   elseif _x<=16384 then
      return sqrlu(_x shr 4) \ 362
   elseif _x<=32768 then
      return sqrlu(_x shr 5) \ 256
   elseif _x<=65536 then
      return sqrlu(_x shr 6) \ 181
   elseif _x<=131072 then
      return sqrlu(_x shr 7) \ 128 ' 128.0
   elseif _x<=262144 then
      return sqrlu(_x shr 8) \ 90 ' 90.5
   elseif _x<=524288 then
      return sqrlu(_x shr 9) \ 64 ' 64.0
   elseif _x<=1048576 then
      return sqrlu(_x shr 10) \ 45 ' 45.25
   elseif _x<=2097152 then
      return sqrlu(_x shr 11) \ 32 ' 32.0
   elseif _x<=4194304 then
      return sqrlu(_x shr 12) * 5 \ 113 '/ 23 ' 22.62
   elseif _x<=8388608 then
      return sqrlu(_x shr 13) \ 16 '16.0
   elseif _x<=16777216 then
      return sqrlu(_x shr 14) \ 11 '11.3
   elseif _x<=33554432 then
      return sqrlu(_x shr 15) \ 8 ' 8.0
   elseif _x<=67108864 then
      return sqrlu(_x shr 16) *10 \ 56 ' 5.65
   elseif _x<=134217728 then
      return sqrlu(_x shr 17) \ 4 ' 4.0
   elseif _x<=268435456 then
      return sqrlu(_x shr 18) *10 \ 28  ' 2.82
   elseif _x<=536870912 then
      return sqrlu(_x shr 19) \ 2 ' 2.0
   elseif _x<=1073741824 then
      return sqrlu(_x shr 20) * 10 \ 14 ' 1.41421
   elseif _x<=2147483648 then
      return sqrlu(_x shr 21) \ 1
   end if
end function

' 2097152   = 2^21
for n as long = 0 to 1024
   sqrlu(n) =    sqr(n*2048) *1024 ' 2097152
next

screenres 1024,768,32

dim as single ov,v
for n as long = 0 to 1023
   ov = n * 2050.001
   v = fpSqr(ov*1024)/ 1024
   'pset(n, sqr(ov)*0.5), &H8800
   pset(n, v*0.5)
next

sleep


Not really sure how to optimize this.
I have 5 bits after point and int range (0-2097151). But it should be much faster for your version.(0-32767)
AWPStar
Posts: 42
Joined: May 03, 2009 21:47

Re: Operators vs Macros

Postby AWPStar » May 16, 2021 12:11

Is there something like c++ inline function ?
Last edited by AWPStar on May 16, 2021 12:15, edited 1 time in total.
marcov
Posts: 3143
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Operators vs Macros

Postby marcov » May 16, 2021 12:14

AWPStar wrote:I want make fixed-point udt and work with it like with any other types.
It not very convenient to use something like that "fpAdd(1, 2)"
But for operators fbc generates functions and it slows the speed of code.
Is there any solution for this?


Implement decent function inlining ?

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 3 guests