Subversion Repositories spk

Rev

Rev 273 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
114 cycrow 1
#ifndef CONVERSION_INCLUDED
2
#define CONVERSION_INCLUDED
3
 
273 cycrow 4
#include <cmath>
114 cycrow 5
/*
6
 
7
	conversion from:
8
		int to double 
9
		int (modulo 100000) to int (modulo 0xFFFF)
10
	double to int rounding is done "to nearest" - hence the assembler and not simple static cast
11
 
12
*/
13
 
14
namespace conversion
15
{
273 cycrow 16
#ifdef _WIN64
283 cycrow 17
	// Constants for conversions
18
	constexpr double MULTIPLIER_BOB_TO_BOD = 0.65536; // == 65535 / 100000
19
	constexpr double MULTIPLIER_BOD_TO_BOB = 0.65536; // == 65535 / 100000
20
	constexpr double MULTIPLIER_DOUBLE_TO_INT = 1.52587890625E-05; // == 1 / 65535
114 cycrow 21
 
283 cycrow 22
	// Divide and round a double value
23
	inline double divideAndRound(double value) {
24
		return std::round(value / MULTIPLIER_DOUBLE_TO_INT);
25
	}
26
 
27
	// Convert double to int with rounding
28
	inline int double2int(double d) {
29
		return static_cast<int>(divideAndRound(d));
30
	}
31
 
32
	// Convert vertex from bob to bod
33
	inline int vertex_bob2bod(int i) {
34
		return static_cast<int>(i / MULTIPLIER_BOB_TO_BOD + 0.5);
35
	}
36
 
37
	// Convert vertex from bod to bob
38
	inline int vertex_bod2bob(int i) {
39
		return static_cast<int>(std::round(i * MULTIPLIER_BOD_TO_BOB));
40
	}
41
 
42
	/*
273 cycrow 43
	static inline double __fastcall divideAndRound(double value) {
44
		const double MULTIPLIER = 1.52587890625E-05; // == 1 / 65535
45
 
46
		value /= MULTIPLIER;
47
		return std::round(value);
48
	}
49
 
50
	static inline int __stdcall double2int(double d)
51
	{
52
		return static_cast<int>(divideAndRound(d));
53
	}
54
 
55
	static int __stdcall vertex_bob2bod(int i)
56
	{
57
		// bod = i / 0.65535
58
		static double MULTIPLIER = 0.65536; // == 65535 / 100000
59
		return static_cast<int>(i / MULTIPLIER + 0.5f);
60
	}
61
 
62
	static inline int __stdcall vertex_bod2bob(int i)
63
	{
64
		// bob = i * 0.65535
65
		static double MULTIPLIER = 0.65536; // == 65535 / 100000
66
 
67
		double result = MULTIPLIER * i;
68
		return static_cast<int>(std::round(result));
69
	}
283 cycrow 70
	*/
273 cycrow 71
#else
72
 
114 cycrow 73
__declspec(naked)
74
static 
75
int __stdcall vertex_bob2bod(int i)
76
{
77
	// bod = i / 0.65535
78
	static double MULTIPLIER = 0.65536; // == 65535 / 100000
79
	__asm {
80
		fld MULTIPLIER
81
		fidivr dword ptr [esp + 4]
82
		fistp dword ptr [esp + 4]
83
		mov eax, dword ptr [esp + 4]
84
		ret 4
85
	}
86
}
87
 
88
/*inline 
89
int __stdcall vertex_bob2bod(int i)
90
{
91
	static double MULTIPLIER = 0.65535; // == 65535 / 100000 
92
	return (int)(i / MULTIPLIER);
93
}*/
94
 
95
 
96
__declspec(naked)
97
inline 
98
int __stdcall vertex_bod2bob(int i)
99
{
100
	// bob = i * 0.65535
101
	static double MULTIPLIER = 0.65536; // == 65535 / 100000
102
	__asm {
103
		fld MULTIPLIER
104
		fimul dword ptr [esp + 4]
105
		fistp dword ptr [esp + 4]
106
		mov eax, dword ptr [esp + 4]
107
		ret 4
108
	}
109
}
110
 
111
__declspec(naked)
112
inline 
113
int __stdcall double2int(double d)
114
{
115
	static const double MULTIPLIER=1.52587890625E-05; // == 1 / 65535
116
 
117
	// int = right / multiplier 
118
	__asm{
119
		fld qword ptr [esp + 4]
120
		fdiv MULTIPLIER
121
		fistp dword ptr [esp + 4]
122
		mov eax, dword ptr [esp + 4]
123
		ret 8
124
	}
125
}
126
/*
127
inline 
128
int __stdcall double2int(double d)
129
{
130
	static const double MULTIPLIER=1.52587890625E-05; // == 1 / 65535
131
 
132
	return (int)(d / MULTIPLIER);
133
 
134
}*/
273 cycrow 135
#endif
114 cycrow 136
 
137
} // namespace conversion
138
 
139
#endif // !defined(CONVERSION_INCLUDED)