Rev 273 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#ifndef CONVERSION_INCLUDED
#define CONVERSION_INCLUDED
#include <cmath>
/*
conversion from:
int to double
int (modulo 100000) to int (modulo 0xFFFF)
double to int rounding is done "to nearest" - hence the assembler and not simple static cast
*/
namespace conversion
{
#ifdef _WIN64
// Constants for conversions
constexpr double MULTIPLIER_BOB_TO_BOD = 0.65536; // == 65535 / 100000
constexpr double MULTIPLIER_BOD_TO_BOB = 0.65536; // == 65535 / 100000
constexpr double MULTIPLIER_DOUBLE_TO_INT = 1.52587890625E-05; // == 1 / 65535
// Divide and round a double value
inline double divideAndRound(double value) {
return std::round(value / MULTIPLIER_DOUBLE_TO_INT);
}
// Convert double to int with rounding
inline int double2int(double d) {
return static_cast<int>(divideAndRound(d));
}
// Convert vertex from bob to bod
inline int vertex_bob2bod(int i) {
return static_cast<int>(i / MULTIPLIER_BOB_TO_BOD + 0.5);
}
// Convert vertex from bod to bob
inline int vertex_bod2bob(int i) {
return static_cast<int>(std::round(i * MULTIPLIER_BOD_TO_BOB));
}
/*
static inline double __fastcall divideAndRound(double value) {
const double MULTIPLIER = 1.52587890625E-05; // == 1 / 65535
value /= MULTIPLIER;
return std::round(value);
}
static inline int __stdcall double2int(double d)
{
return static_cast<int>(divideAndRound(d));
}
static int __stdcall vertex_bob2bod(int i)
{
// bod = i / 0.65535
static double MULTIPLIER = 0.65536; // == 65535 / 100000
return static_cast<int>(i / MULTIPLIER + 0.5f);
}
static inline int __stdcall vertex_bod2bob(int i)
{
// bob = i * 0.65535
static double MULTIPLIER = 0.65536; // == 65535 / 100000
double result = MULTIPLIER * i;
return static_cast<int>(std::round(result));
}
*/
#else
__declspec(naked)
static
int __stdcall vertex_bob2bod(int i)
{
// bod = i / 0.65535
static double MULTIPLIER = 0.65536; // == 65535 / 100000
__asm {
fld MULTIPLIER
fidivr dword ptr [esp + 4]
fistp dword ptr [esp + 4]
mov eax, dword ptr [esp + 4]
ret 4
}
}
/*inline
int __stdcall vertex_bob2bod(int i)
{
static double MULTIPLIER = 0.65535; // == 65535 / 100000
return (int)(i / MULTIPLIER);
}*/
__declspec(naked)
inline
int __stdcall vertex_bod2bob(int i)
{
// bob = i * 0.65535
static double MULTIPLIER = 0.65536; // == 65535 / 100000
__asm {
fld MULTIPLIER
fimul dword ptr [esp + 4]
fistp dword ptr [esp + 4]
mov eax, dword ptr [esp + 4]
ret 4
}
}
__declspec(naked)
inline
int __stdcall double2int(double d)
{
static const double MULTIPLIER=1.52587890625E-05; // == 1 / 65535
// int = right / multiplier
__asm{
fld qword ptr [esp + 4]
fdiv MULTIPLIER
fistp dword ptr [esp + 4]
mov eax, dword ptr [esp + 4]
ret 8
}
}
/*
inline
int __stdcall double2int(double d)
{
static const double MULTIPLIER=1.52587890625E-05; // == 1 / 65535
return (int)(d / MULTIPLIER);
}*/
#endif
} // namespace conversion
#endif // !defined(CONVERSION_INCLUDED)