Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3584 sourcerer 1
/*
2
 * This file is part of LibCSS.
3
 * Licensed under the MIT License,
4
 *                http://www.opensource.org/licenses/mit-license.php
5
 * Copyright 2008 John-Mark Bell 
6
 */
7
 
8
#ifndef libcss_fpmath_h_
9
#define libcss_fpmath_h_
10
 
11
#ifdef __cplusplus
12
extern "C"
13
{
14
#endif
15
 
16
#include 
17
#include 
18
 
19
/* 22:10 fixed point math */
20
#define CSS_RADIX_POINT 10
21
 
22
/* type for fixed point numbers */
23
typedef int32_t css_fixed;
24
 
25
static inline css_fixed
26
css_add_fixed(const css_fixed x, const css_fixed y) {
27
	int32_t ux = x;
28
	int32_t uy = y;
29
	int32_t res = ux + uy;
30
 
31
	/* Calculate overflowed result. (Don't change the sign bit of ux) */
32
	ux = (ux >> 31) + INT_MAX;
33
 
34
	/* Force compiler to use cmovns instruction */
35
	if ((int32_t) ((ux ^ uy) | ~(uy ^ res)) >= 0) {
36
		res = ux;
37
	}
38
 
39
	return res;
40
}
41
 
42
static inline css_fixed
43
css_subtract_fixed(const css_fixed x, const css_fixed y) {
44
	int32_t ux = x;
45
	int32_t uy = y;
46
	int32_t res = ux - uy;
47
 
48
	ux = (ux >> 31) + INT_MAX;
49
 
50
	/* Force compiler to use cmovns instruction */
51
	if ((int32_t)((ux ^ uy) & (ux ^ res)) < 0) {
52
		res = ux;
53
	}
54
 
55
	return res;
56
}
57
 
58
static inline css_fixed
59
css_divide_fixed(const css_fixed x, const css_fixed y) {
60
	int64_t xx = ((int64_t)x << CSS_RADIX_POINT) / y;
61
 
62
	if (xx < INT_MIN)
63
		xx = INT_MIN;
64
 
65
	if (xx > INT_MAX)
66
		xx = INT_MAX;
67
 
68
	return xx;
69
}
70
 
71
static inline css_fixed
72
css_multiply_fixed(const css_fixed x, const css_fixed y) {
73
	int64_t xx = ((int64_t)x * (int64_t)y) >> CSS_RADIX_POINT;
74
 
75
	if (xx < INT_MIN)
76
		xx = INT_MIN;
77
 
78
	if (xx > INT_MAX)
79
		xx = INT_MAX;
80
 
81
	return xx;
82
}
83
 
84
static inline css_fixed
85
css_int_to_fixed(const int a) {
86
	int64_t xx = ((int64_t) a) << CSS_RADIX_POINT;
87
 
88
	if (xx < INT_MIN)
89
		xx = INT_MIN;
90
 
91
	if (xx > INT_MAX)
92
		xx = INT_MAX;
93
 
94
	return xx;
95
}
96
 
97
static inline css_fixed
98
css_float_to_fixed(const float a) {
99
	float xx = a * (float) (1 << CSS_RADIX_POINT);
100
 
101
	if (xx < INT_MIN)
102
		xx = INT_MIN;
103
 
104
	if (xx > INT_MAX)
105
		xx = INT_MAX;
106
 
107
	return (css_fixed) xx;
108
}
109
 
110
/* Add two fixed point values */
111
#define FADD(a, b) (css_add_fixed((a), (b)))
112
/* Subtract two fixed point values */
113
#define FSUB(a, b) (css_subtract_fixed((a), (b)))
114
/* Multiply two fixed point values */
115
#define FMUL(a, b) (css_multiply_fixed((a), (b)))
116
/* Divide two fixed point values */
117
#define FDIV(a, b) (css_divide_fixed((a), (b)))
118
 
119
/* Convert a floating point value to fixed point */
120
#define FLTTOFIX(a) ((css_fixed) ((a) * (float) (1 << CSS_RADIX_POINT)))
121
/* Convert a fixed point value to floating point */
122
#define FIXTOFLT(a) ((float) (a) / (float) (1 << CSS_RADIX_POINT))
123
 
124
/* Convert an integer to a fixed point value */
125
#define INTTOFIX(a) (css_int_to_fixed(a))
126
/* Convert a fixed point value to an integer */
127
#define FIXTOINT(a) ((a) >> CSS_RADIX_POINT)
128
 
129
/* truncate a fixed point value */
130
#define TRUNCATEFIX(a) (a & ~((1 << CSS_RADIX_POINT)- 1 ))
131
 
132
/* Useful values */
133
#define F_PI_2	0x00000648	/* 1.5708 (PI/2) */
134
#define F_PI	0x00000c91	/* 3.1415 (PI) */
135
#define F_3PI_2	0x000012d9	/* 4.7124 (3PI/2) */
136
#define F_2PI	0x00001922	/* 6.2831 (2 PI) */
137
 
138
#define F_90	0x00016800	/*  90 */
139
#define F_180	0x0002d000	/* 180 */
140
#define F_270	0x00043800	/* 270 */
141
#define F_360	0x0005a000	/* 360 */
142
 
143
#define F_0_5	0x00000200	/* 0.5 */
144
#define F_1	0x00000400	/*   1 */
145
#define F_10	0x00002800	/*  10 */
146
#define F_72	0x00012000	/*  72 */
147
#define F_100	0x00019000	/* 100 */
148
#define F_200	0x00032000	/* 200 */
149
#define F_255	0x0003FC00	/* 255 */
150
#define F_300	0x0004b000	/* 300 */
151
#define F_400	0x00064000	/* 400 */
152
 
153
#ifdef __cplusplus
154
}
155
#endif
156
 
157
#endif
158