mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-26 22:51:01 +00:00
move fixed point number class to separate file
This commit is contained in:
parent
793b94bacc
commit
52b50689d2
@ -9,7 +9,9 @@ add_executable(Raytracer MACOSX_BUNDLE
|
||||
raytracer.cc
|
||||
)
|
||||
add_executable(Raytracer2 MACOSX_BUNDLE
|
||||
raytracer2.cc
|
||||
raytracer2.cc
|
||||
fixed.h
|
||||
fixed.cc
|
||||
)
|
||||
|
||||
|
||||
|
29
Raytracer/fixed.cc
Normal file
29
Raytracer/fixed.cc
Normal file
@ -0,0 +1,29 @@
|
||||
#include "fixed.h"
|
||||
|
||||
long fixed::nMul = 0, fixed::nIMul = 0, fixed::nDiv = 0, fixed::nSqrt = 0;
|
||||
|
||||
fixed sqrt(fixed f)
|
||||
{
|
||||
COUNT_OP(fixed::nSqrt);
|
||||
|
||||
const int FRACBITS = 16; /* Must be even! */
|
||||
const int ITERS = 15 + (FRACBITS >> 1);
|
||||
|
||||
unsigned long root, remHi, remLo, testDiv, count;
|
||||
root = 0; /* Clear root */
|
||||
remHi = 0; /* Clear high part of partial remainder */
|
||||
remLo = f.val; /* Get argument into low part of partial remainder */
|
||||
count = ITERS; /* Load loop counter */
|
||||
|
||||
do {
|
||||
remHi = (remHi << 2) | (remLo >> 30); remLo <<= 2; /* get 2 bits of arg */
|
||||
root <<= 1; /* Get ready for the next bit in the root */
|
||||
testDiv = (root << 1) + 1; /* Test radical */
|
||||
if (remHi >= testDiv) {
|
||||
remHi -= testDiv;
|
||||
root += 1;
|
||||
}
|
||||
} while (count-- != 0);
|
||||
|
||||
return fixed(root, fixed::raw());
|
||||
}
|
119
Raytracer/fixed.h
Normal file
119
Raytracer/fixed.h
Normal file
@ -0,0 +1,119 @@
|
||||
#ifndef FIXED_H
|
||||
#define FIXED_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
inline std::int32_t muls(std::int16_t x, std::int16_t y)
|
||||
{
|
||||
return (std::int32_t)x*y;
|
||||
}
|
||||
|
||||
inline std::uint32_t mulu(std::uint16_t x, std::uint16_t y)
|
||||
{
|
||||
//return (std::uint32_t)x * y;
|
||||
std::uint32_t res;
|
||||
__asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y));
|
||||
return res;
|
||||
}
|
||||
|
||||
inline std::int32_t mulsu(std::int16_t x, std::uint16_t y)
|
||||
{
|
||||
//return (std::int32_t)a * (std::uint32_t)b;
|
||||
std::int32_t res;
|
||||
__asm("mulu %1, %0" : "=d"(res) : "d"(x), "0"(y));
|
||||
if(x < 0)
|
||||
res -= ((std::uint32_t)y) << 16;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define COUNT_OP(var) ++var
|
||||
|
||||
class fixed
|
||||
{
|
||||
std::int32_t val;
|
||||
|
||||
public:
|
||||
class raw {};
|
||||
fixed(std::int32_t val, raw r) : val(val) {}
|
||||
|
||||
fixed() : val(0) {}
|
||||
fixed(int x) : val((long)x << 16) {}
|
||||
fixed(float f) : val(f * 65536) {}
|
||||
|
||||
//operator int() { return val >> 16; }
|
||||
|
||||
fixed operator+(fixed o) const { return fixed(val + o.val, raw()); }
|
||||
fixed operator-(fixed o) const { return fixed(val - o.val, raw()); }
|
||||
fixed operator*(fixed o) const {
|
||||
COUNT_OP(nMul);
|
||||
//return fixed((static_cast<long long>(val) * o.val) >> 16, raw());
|
||||
int16_t a = val >> 16;
|
||||
int16_t c = o.val >> 16;
|
||||
|
||||
uint16_t b = val;
|
||||
uint16_t d = o.val;
|
||||
|
||||
return fixed(((a*c) << 16)
|
||||
+ mulsu(a,d) + mulsu(c,b)
|
||||
+ (mulu(b,d) >> 16),raw());
|
||||
|
||||
}
|
||||
fixed operator/(fixed o) const { COUNT_OP(nDiv); return fixed((static_cast<long long>(val) << 16) / o.val, raw()); }
|
||||
|
||||
fixed operator-() const { return fixed(-val, raw()); }
|
||||
|
||||
fixed& operator+=(fixed o) { val += o.val; return *this; }
|
||||
fixed& operator-=(fixed o) { val -= o.val; return *this; }
|
||||
fixed& operator*=(fixed o) { return (*this = *this * o); }
|
||||
|
||||
bool operator== (fixed o) const { return val == o.val; }
|
||||
bool operator!= (fixed o) const { return val != o.val; }
|
||||
bool operator> (fixed o) const { return val > o.val; }
|
||||
bool operator< (fixed o) const { return val < o.val; }
|
||||
bool operator>= (fixed o) const { return val >= o.val; }
|
||||
bool operator<= (fixed o) const { return val <= o.val; }
|
||||
|
||||
friend fixed sqrt(fixed f);
|
||||
friend fixed floor(fixed f);
|
||||
friend fixed operator*(fixed f, int x);
|
||||
friend fixed operator*(int x, fixed f);
|
||||
friend int floor_to_int(fixed f);
|
||||
|
||||
static long nMul;
|
||||
static long nIMul;
|
||||
static long nDiv;
|
||||
static long nSqrt;
|
||||
};
|
||||
|
||||
/*fixed operator*(fixed f, int x) { return fixed(f.val * x, fixed::raw()); }
|
||||
fixed operator*(int x, fixed f) { return fixed(f.val * x, fixed::raw()); }*/
|
||||
inline fixed operator*(fixed f, int c)
|
||||
{
|
||||
std::int16_t a = f.val >> 16;
|
||||
|
||||
std::uint16_t b = f.val;
|
||||
|
||||
COUNT_OP(fixed::nIMul);
|
||||
return fixed(((a*c) << 16)
|
||||
+ mulsu(c,b),fixed::raw());
|
||||
}
|
||||
inline fixed operator*(int x, fixed f) { return f*x; }
|
||||
|
||||
inline fixed operator*(fixed f, float x) { return f*fixed(x); }
|
||||
inline fixed operator*(float x, fixed f) { return f*fixed(x); }
|
||||
|
||||
|
||||
|
||||
fixed sqrt(fixed f);
|
||||
|
||||
inline fixed floor(fixed f)
|
||||
{
|
||||
return fixed(f.val & 0xFFFF0000L, fixed::raw());
|
||||
}
|
||||
|
||||
inline int floor_to_int(fixed f)
|
||||
{
|
||||
return f.val >> 16;
|
||||
}
|
||||
|
||||
#endif // FIXED_H
|
@ -21,6 +21,7 @@ QDGlobals qd;
|
||||
|
||||
#endif
|
||||
|
||||
#include "fixed.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
@ -31,103 +32,9 @@ QDGlobals qd;
|
||||
using std::sqrt;
|
||||
using std::floor;
|
||||
|
||||
class fixed
|
||||
{
|
||||
long val;
|
||||
|
||||
public:
|
||||
class raw {};
|
||||
fixed(long val, raw r) : val(val) {}
|
||||
|
||||
fixed() : val(0) {}
|
||||
fixed(int x) : val((long)x << 16) {}
|
||||
fixed(float f) : val(f * 65536) {}
|
||||
|
||||
//operator int() { return val >> 16; }
|
||||
|
||||
fixed operator+(fixed o) const { return fixed(val + o.val, raw()); }
|
||||
fixed operator-(fixed o) const { return fixed(val - o.val, raw()); }
|
||||
fixed operator*(fixed o) const { return fixed((static_cast<long long>(val) * o.val) >> 16, raw()); }
|
||||
fixed operator/(fixed o) const { return fixed((static_cast<long long>(val) << 16) / o.val, raw()); }
|
||||
|
||||
fixed operator-() const { return fixed(-val, raw()); }
|
||||
|
||||
fixed& operator+=(fixed o) { val += o.val; return *this; }
|
||||
fixed& operator-=(fixed o) { val -= o.val; return *this; }
|
||||
fixed& operator*=(fixed o) { return (*this = *this * o); }
|
||||
|
||||
bool operator== (fixed o) const { return val == o.val; }
|
||||
bool operator!= (fixed o) const { return val != o.val; }
|
||||
bool operator> (fixed o) const { return val > o.val; }
|
||||
bool operator< (fixed o) const { return val < o.val; }
|
||||
bool operator>= (fixed o) const { return val >= o.val; }
|
||||
bool operator<= (fixed o) const { return val <= o.val; }
|
||||
|
||||
friend fixed sqrt(fixed f);
|
||||
friend fixed floor(fixed f);
|
||||
friend fixed operator*(fixed f, int x);
|
||||
friend fixed operator*(int x, fixed f);
|
||||
friend int floor_to_int(fixed f);
|
||||
};
|
||||
|
||||
fixed operator*(fixed f, int x) { return fixed(f.val * x, fixed::raw()); }
|
||||
fixed operator*(int x, fixed f) { return fixed(f.val * x, fixed::raw()); }
|
||||
|
||||
fixed operator*(fixed f, float x) { return f*fixed(x); }
|
||||
fixed operator*(float x, fixed f) { return f*fixed(x); }
|
||||
|
||||
|
||||
fixed sqrt(fixed f)
|
||||
{
|
||||
#if 1
|
||||
const int FRACBITS = 16; /* Must be even! */
|
||||
const int ITERS = 15 + (FRACBITS >> 1);
|
||||
|
||||
unsigned long root, remHi, remLo, testDiv, count;
|
||||
root = 0; /* Clear root */
|
||||
remHi = 0; /* Clear high part of partial remainder */
|
||||
remLo = f.val; /* Get argument into low part of partial remainder */
|
||||
count = ITERS; /* Load loop counter */
|
||||
|
||||
do {
|
||||
remHi = (remHi << 2) | (remLo >> 30); remLo <<= 2; /* get 2 bits of arg */
|
||||
root <<= 1; /* Get ready for the next bit in the root */
|
||||
testDiv = (root << 1) + 1; /* Test radical */
|
||||
if (remHi >= testDiv) {
|
||||
remHi -= testDiv;
|
||||
root += 1;
|
||||
}
|
||||
} while (count-- != 0);
|
||||
|
||||
return fixed(root, fixed::raw());
|
||||
#else
|
||||
|
||||
fixed lower = 0;
|
||||
fixed upper = 181; // 181.019
|
||||
while(lower != upper)
|
||||
{
|
||||
fixed mid(lower.val/2 + upper.val/2, fixed::raw());
|
||||
fixed s = mid*mid;
|
||||
if(s <= f)
|
||||
lower = mid;
|
||||
if(s >= f)
|
||||
upper = mid;
|
||||
}
|
||||
return lower;
|
||||
#endif
|
||||
}
|
||||
|
||||
fixed floor(fixed f)
|
||||
{
|
||||
return fixed(f.val & 0xFFFF0000L, fixed::raw());
|
||||
}
|
||||
|
||||
int floor_to_int(fixed f)
|
||||
{
|
||||
return f.val >> 16;
|
||||
}
|
||||
|
||||
int floor_to_int(float f)
|
||||
inline int floor_to_int(float f)
|
||||
{
|
||||
return static_cast<int>(std::floor(f));
|
||||
}
|
||||
@ -169,8 +76,8 @@ public:
|
||||
template<class T>
|
||||
bool hitSphere(vec3<T> p0, vec3<T> dir, T& t)
|
||||
{
|
||||
const vec3<T> center(0.0f, 0.0f, -6.0f);
|
||||
const T r = 1.0f;
|
||||
const vec3<T> center(0.0f, 1.0f, -6.0f);
|
||||
const T r = 2.0f;
|
||||
vec3<T> p0c(p0 - center);
|
||||
|
||||
/*
|
||||
@ -202,8 +109,8 @@ T ray(int n, vec3<T> p0, vec3<T> dir)
|
||||
static const vec3<T> light = vec3<T>(-2,4,3).normalize();
|
||||
|
||||
if(1){
|
||||
const vec3<T> center(0.0f, 0.0f, -6.0f);
|
||||
const T r = 1.0f;
|
||||
const vec3<T> center(0.0f, 1.0f, -6.0f);
|
||||
const T r = 2.0f;
|
||||
vec3<T> p0c(p0 - center);
|
||||
|
||||
/*
|
||||
@ -226,7 +133,7 @@ T ray(int n, vec3<T> p0, vec3<T> dir)
|
||||
{
|
||||
vec3<T> p = p0 + dir * t;
|
||||
|
||||
vec3<T> dir2 = p - center;
|
||||
vec3<T> dir2 = (p - center) * (T(1)/r);
|
||||
|
||||
T l = dir2*dir;
|
||||
|
||||
@ -290,7 +197,6 @@ struct rand1<fixed>
|
||||
int main()
|
||||
{
|
||||
WindowPtr win;
|
||||
Debugger();
|
||||
#if !TARGET_API_MAC_CARBON
|
||||
InitGraf(&qd.thePort);
|
||||
InitFonts();
|
||||
@ -366,7 +272,8 @@ int main()
|
||||
|
||||
char buf[256];
|
||||
unsigned char* pstr = (unsigned char*)buf;
|
||||
std::sprintf(buf+1, "pps = %d", (int)( (long)r.right * r.bottom * 60 / (endTime - startTime) ));
|
||||
std::sprintf(buf+1, "pps = %d %ld %ld %ld %ld", (int)( (long)r.right * r.bottom * 60 / (endTime - startTime) ),
|
||||
fixed::nMul, fixed::nIMul, fixed::nDiv, fixed::nSqrt);
|
||||
buf[0] = std::strlen(buf+1);
|
||||
|
||||
SetRect(&r, 10, 10, 10 + StringWidth(pstr) + 10, 30);
|
||||
|
Loading…
Reference in New Issue
Block a user