Mercurial > fife-parpg
changeset 646:07b1cf8e92b5
* Major improvements to fife_math.h and added corresponding Python bindings. Users now have access to FIFE's internal math functions. These functions are recommended to be used by all clients if required. Note: this may cause some problems with certain compilers. I hope this wont have to be reverted. TODO: remove the static constant globals somehow.
* Adopted the new math functions for all subsystems
* Improvements to DeviceCaps. It now detects all possible screen modes.
* User can now select 0 for their bpp and it will attempt to initialize SDL with the current screen bpp.
author | prock@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Wed, 13 Oct 2010 20:24:48 +0000 |
parents | 291ba2946c73 |
children | f2b3512d0e60 |
files | engine/core/controller/engine.cpp engine/core/model/metamodel/grids/hexgrid.cpp engine/core/util/math/angles.h engine/core/util/math/fife_math.h engine/core/util/math/math.i engine/core/util/math/matrix.h engine/core/util/structures/point.h engine/core/video/devicecaps.cpp engine/core/video/devicecaps.h engine/core/view/camera.cpp |
diffstat | 10 files changed, 323 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/engine/core/controller/engine.cpp Tue Oct 12 18:58:47 2010 +0000 +++ b/engine/core/controller/engine.cpp Wed Oct 13 20:24:48 2010 +0000 @@ -210,7 +210,7 @@ m_screenMode = m_devcaps.getNearestScreenMode( m_settings.getScreenWidth(), m_settings.getScreenHeight(), - (bpp ? bpp : 32) , //if it's 0 we use 32 bit as a default + bpp, rbackend, m_settings.isFullScreen()); @@ -309,11 +309,11 @@ TTF_Quit(); SDL_Quit(); - + #ifdef USE_COCOA objc_msgSend(m_autoreleasePool, sel_registerName("release")); #endif - + FL_LOG(_log, "================== Engine destructed =================="); m_destroyed = true; //delete m_logmanager;
--- a/engine/core/model/metamodel/grids/hexgrid.cpp Tue Oct 12 18:58:47 2010 +0000 +++ b/engine/core/model/metamodel/grids/hexgrid.cpp Wed Oct 13 20:24:48 2010 +0000 @@ -38,8 +38,8 @@ static const double HEX_WIDTH = 1; static const double HEX_TO_EDGE = HEX_WIDTH / 2; - static const double HEX_TO_CORNER = 0.5 / cos(DBL_PI / 6); - static const double HEX_EDGE_HALF = HEX_TO_CORNER * sin(DBL_PI / 6); + static const double HEX_TO_CORNER = 0.5 / Mathd::Cos(Mathd::pi() / 6); + static const double HEX_EDGE_HALF = HEX_TO_CORNER * Mathd::Sin(Mathd::pi() / 6); static const double VERTICAL_MULTIP = sqrt(HEX_WIDTH*HEX_WIDTH - HEX_TO_EDGE*HEX_TO_EDGE); static const double VERTICAL_MULTIP_INV = 1 / VERTICAL_MULTIP;
--- a/engine/core/util/math/angles.h Tue Oct 12 18:58:47 2010 +0000 +++ b/engine/core/util/math/angles.h Wed Oct 13 20:24:48 2010 +0000 @@ -52,7 +52,7 @@ double dy = (c2.y - c1.y); double dx = (c2.x - c1.x); - int angle = static_cast<int>(atan2(-dy,dx)*(180.0/DBL_PI)); + int angle = static_cast<int>(Mathd::ATan2(-dy,dx)*(180.0/Mathd::pi())); return angle; }
--- a/engine/core/util/math/fife_math.h Tue Oct 12 18:58:47 2010 +0000 +++ b/engine/core/util/math/fife_math.h Wed Oct 13 20:24:48 2010 +0000 @@ -23,7 +23,9 @@ #define FIFE_UTIL_FIFE_MATH_H // Standard C++ library includes +#include <cassert> #include <cmath> +#include <limits> // Platform specific includes @@ -48,6 +50,8 @@ namespace FIFE { + static const float FLT_STD_EPSILON = std::numeric_limits<float>::epsilon(); + static const float FLT_STD_MAX = std::numeric_limits<float>::max(); static const float FLT_ZERO_TOLERANCE = 1e-06f; static const float FLT_PI = 4.0f*std::atan(1.0f); static const float FLT_TWO_PI = 2.0f*FLT_PI; @@ -61,19 +65,224 @@ static const float FLT_INV_LOG_2 = 1.0f/std::log(2.0f); static const float FLT_INV_LOG_10 = 1.0f/std::log(10.0f); + static const double DBL_STD_EPSILON = std::numeric_limits<double>::epsilon(); + static const double DBL_STD_MAX = std::numeric_limits<double>::max(); static const double DBL_ZERO_TOLERANCE = 1e-08; - static const double DBL_PI = 4.0*std::atan(1.0f); + static const double DBL_PI = 4.0*std::atan(1.0); static const double DBL_TWO_PI = 2.0*DBL_PI; static const double DBL_HALF_PI = 0.5*DBL_PI; static const double DBL_INVERSE_PI = 1.0/DBL_PI; static const double DBL_INVERSE_TWO_PI = 1.0/DBL_TWO_PI; static const double DBL_DEG_TO_RAD = DBL_PI/180.0; - static const double DBL_RAD_TO_DEG = 180.0/DBL_PI; - static const double DBL_LOG_2 = std::log(2.0f); - static const double DBL_LOG_10 = std::log(10.0f); - static const double DBL_INV_LOG_2 = 1.0/std::log(2.0f); - static const double DBL_INV_LOG_10 = 1.0/std::log(10.0f); + static const double DBL_RAD_TO_DEG = 180.0f/DBL_PI; + static const double DBL_LOG_2 = std::log(2.0); + static const double DBL_LOG_10 = std::log(10.0); + static const double DBL_INV_LOG_2 = 1.0/std::log(2.0); + static const double DBL_INV_LOG_10 = 1.0/std::log(10.0); + + template <class numT> + struct float_traits { }; + + template <> + struct float_traits<float> { + typedef float float_type; + static inline float_type epsilon() { return FLT_STD_EPSILON; } + static inline float_type zeroTolerance() { return FLT_ZERO_TOLERANCE; } + static inline float_type max() { return FLT_STD_MAX; } + static inline float_type pi() { return FLT_PI; } + static inline float_type twoPi() { return FLT_TWO_PI; } + static inline float_type halfPi() { return FLT_HALF_PI; } + static inline float_type inversePi() { return FLT_INVERSE_PI; } + static inline float_type inverseTwoPi() { return FLT_INVERSE_TWO_PI; } + static inline float_type degToRad() { return FLT_DEG_TO_RAD; } + static inline float_type radToDeg() { return FLT_RAD_TO_DEG; } + static inline float_type log2() { return FLT_LOG_2; } + static inline float_type log10() { return FLT_LOG_10; } + static inline float_type invLog2() { return FLT_INV_LOG_2; } + static inline float_type invLog10() { return FLT_INV_LOG_10; } + }; + + template <> + struct float_traits<double> { + typedef double float_type; + static inline float_type epsilon() { return DBL_STD_EPSILON; } + static inline float_type zeroTolerance() { return DBL_ZERO_TOLERANCE; } + static inline float_type max() { return DBL_STD_MAX; } + static inline float_type pi() { return DBL_PI; } + static inline float_type twoPi() { return DBL_TWO_PI; } + static inline float_type halfPi() { return DBL_HALF_PI; } + static inline float_type inversePi() { return DBL_INVERSE_PI; } + static inline float_type inverseTwoPi() { return DBL_INVERSE_TWO_PI; } + static inline float_type degToRad() { return DBL_DEG_TO_RAD; } + static inline float_type radToDeg() { return DBL_RAD_TO_DEG; } + static inline float_type log2() { return DBL_LOG_2; } + static inline float_type log10() { return DBL_LOG_10; } + static inline float_type invLog2() { return DBL_INV_LOG_2; } + static inline float_type invLog10() { return DBL_INV_LOG_10; } + }; + + template <typename T> + class Math { + public: + typedef T num_type; + typedef float_traits<num_type> traits_type; + + static inline num_type epsilon() { return traits_type::epsilon(); } + static inline num_type zeroTolerance() { return traits_type::zeroTolerance(); } + static inline num_type max() { return traits_type::max(); } + static inline num_type pi() { return traits_type::pi(); } + static inline num_type twoPi() { return traits_type::twoPi(); } + static inline num_type halfPi() { return traits_type::halfPi(); } + static inline num_type inversePi() { return traits_type::inversePi(); } + static inline num_type inverseTwoPi() { return traits_type::inverseTwoPi(); } + static inline num_type degToRad() { return traits_type::degToRad(); } + static inline num_type radToDeg() { return traits_type::radToDeg(); } + static inline num_type log2() { return traits_type::log2(); } + static inline num_type log10() { return traits_type::log10(); } + static inline num_type invLog2() { return traits_type::invLog2(); } + static inline num_type invLog10() { return traits_type::invLog10(); } + + static T ACos(T _val); + static T ASin(T _val); + static T ATan(T _val); + static T ATan2(T _x, T _y); + static T Ceil(T _val); + static T Cos(T _val); + static T Exp(T _val); + static T FAbs(T _val); + static T Floor(T _val); + static T FMod (T _x, T _y); + static T InvSqrt(T _val); + static T Log(T _val); + static T Log2(T _val); + static T Log10(T _val); + static T Pow(T _base, T _exponent); + static T Sin(T _val); + static T Sqr(T _val); + static T Sqrt(T _val); + static T Tan(T _val); + }; + + typedef Math<float> Mathf; + typedef Math<double> Mathd; + template<typename T> + inline T Math<T>::ACos(T _val) { + if (-static_cast<T>(1) < _val) { + if (_val < static_cast<T>(1)) { + return static_cast<T>(std::acos(_val)); + } + else { + return static_cast<T>(0); + } + } + else { + return pi(); + } + } + + template <class T> + inline T Math<T>::ASin(T _val) { + if (-static_cast<T>(1) < _val) { + if (_val < static_cast<T>(1)) { + return static_cast<T>(std::asin(_val)); + } + else { + return halfPi(); + } + } + else { + return -halfPi(); + } + } + + template <class T> + inline T Math<T>::ATan(T _val) { + return static_cast<T>(std::atan(_val)); + } + + template <class T> + inline T Math<T>::ATan2(T _x, T _y) { + return static_cast<T>(std::atan2(_x, _y)); + } + + template <class T> + inline T Math<T>::Ceil(T _val) { + return static_cast<T>(std::ceil(_val)); + } + + template <class T> + inline T Math<T>::Cos(T _val) { + return static_cast<T>(std::cos(_val)); + } + + template <class T> + inline T Math<T>::Exp(T _val){ + return static_cast<T>(std::exp(_val)); + } + + template <class T> + inline T Math<T>::FAbs(T _val) { + return static_cast<T>(std::fabs(_val)); + } + + template <class T> + inline T Math<T>::Floor(T _val) { + return static_cast<T>(std::floor(_val)); + } + + template <class T> + inline T Math<T>::FMod(T _x, T _y) { + return static_cast<T>(std::fmod(_x, _y)); + } + + template <class T> + inline T Math<T>::InvSqrt(T _val) { + return static_cast<T>(1/std::sqrt(_val)); + } + + template <class T> + inline T Math<T>::Log(T _val) { + return static_cast<T>(std::log(_val)); + } + + template <class T> + inline T Math<T>::Log2(T _val) { + return invLog2() * static_cast<T>(std::log(_val)); + } + template <class T> + inline T Math<T>::Log10(T _val) { + + return invLog10() * static_cast<T>(std::log(_val)); + } + + template <class T> + inline T Math<T>::Pow(T _base, T _exponent) { + return static_cast<T>(std::pow(_base, _exponent)); + } + + template <class T> + inline T Math<T>::Sin(T _val) { + return static_cast<T>(std::sin(_val)); + } + + template <class T> + inline T Math<T>::Sqr(T _val) { + return _val*_val; + } + + template <class T> + inline T Math<T>::Sqrt(T _val) { + return static_cast<T>(std::sqrt(_val)); + } + + template <class T> + inline T Math<T>::Tan(T _val) { + return static_cast<T>(std::tan(_val)); + } + + /** Returns the next higher power of 2 based on the passed argument + */ inline unsigned nextPow2(unsigned x) { --x;
--- a/engine/core/util/math/math.i Tue Oct 12 18:58:47 2010 +0000 +++ b/engine/core/util/math/math.i Wed Oct 13 20:24:48 2010 +0000 @@ -26,30 +26,55 @@ namespace FIFE { - static const float FLT_ZERO_TOLERANCE; - static const float FLT_PI; - static const float FLT_TWO_PI; - static const float FLT_HALF_PI; - static const float FLT_INVERSE_PI; - static const float FLT_INVERSE_TWO_PI; - static const float FLT_DEG_TO_RAD; - static const float FLT_RAD_TO_DEG; - static const float FLT_LOG_2; - static const float FLT_LOG_10; - static const float FLT_INV_LOG_2; - static const float FLT_INV_LOG_10; + template <class numT> + struct float_traits { }; + + template <typename T> + class Math { + public: + typedef T num_type; + typedef float_traits<num_type> traits_type; + + static inline num_type epsilon(); + static inline num_type zeroTolerance(); + static inline num_type max(); + static inline num_type pi(); + static inline num_type twoPi(); + static inline num_type halfPi(); + static inline num_type inversePi(); + static inline num_type inverseTwoPi(); + static inline num_type degToRad(); + static inline num_type radToDeg(); + static inline num_type log2(); + static inline num_type log10(); + static inline num_type invLog2(); + static inline num_type invLog10(); - static const double DBL_ZERO_TOLERANCE; - static const double DBL_PI; - static const double DBL_TWO_PI; - static const double DBL_HALF_PI; - static const double DBL_INVERSE_PI; - static const double DBL_INVERSE_TWO_PI; - static const double DBL_DEG_TO_RAD; - static const double DBL_RAD_TO_DEG; - static const double DBL_LOG_2; - static const double DBL_LOG_10; - static const double DBL_INV_LOG_2; - static const double DBL_INV_LOG_10; + static T ACos(T _val); + static T ASin(T _val); + static T ATan(T _val); + static T ATan2(T _x, T _y); + static T Ceil(T _val); + static T Cos(T _val); + static T Exp(T _val); + static T FAbs(T _val); + static T Floor(T _val); + static T FMod (T _x, T _y); + static T InvSqrt(T _val); + static T Log(T _val); + static T Log2(T _val); + static T Log10(T _val); + static T Pow(T _base, T _exponent); + static T Sin(T _val); + static T Sqr(T _val); + static T Sqrt(T _val); + static T Tan(T _val); + }; + + typedef Math<float> Mathf; + typedef Math<double> Mathd; + + %template(Mathf) Math<float>; + %template(Mathd) Math<double>; }
--- a/engine/core/util/math/matrix.h Tue Oct 12 18:58:47 2010 +0000 +++ b/engine/core/util/math/matrix.h Wed Oct 13 20:24:48 2010 +0000 @@ -118,8 +118,8 @@ y/=mag; z/=mag; } - T c = cos(angle*DBL_PI/180); - T s = sin(angle*DBL_PI/180); + T c = Math<T>::Cos(angle*Math<T>::pi()/180); + T s = Math<T>::Sin(angle*Math<T>::pi()/180); m0 = x*x*(1-c)+c; m1 = y*x*(1-c)+z*s; m2 = z*x*(1-c)-y*s;
--- a/engine/core/util/structures/point.h Tue Oct 12 18:58:47 2010 +0000 +++ b/engine/core/util/structures/point.h Wed Oct 13 20:24:48 2010 +0000 @@ -131,7 +131,7 @@ T invLength = 1.0/length(); //TODO: get rid of this static cast - if (invLength > static_cast<T>(DBL_ZERO_TOLERANCE)) { + if (invLength > static_cast<T>(Mathd::zeroTolerance())) { x = x * invLength; y = y * invLength; } @@ -145,9 +145,9 @@ */ void rotate(T angle){ //TODO: get rid of this static cast - T theta = (angle * static_cast<T>(DBL_PI))/180; - T costheta = cos(theta); - T sintheta = sin(theta); + T theta = (angle * static_cast<T>(Mathd::pi()))/180; + T costheta = static_cast<T>(Mathd::Cos(theta)); + T sintheta = static_cast<T>(Mathd::Sin(theta)); T nx = x; T ny = y; @@ -160,9 +160,9 @@ */ void rotate(const PointType2D<T>& origin, T angle){ //TODO: get rid of this static cast - T theta = (angle * static_cast<T>(DBL_PI))/180; - T costheta = cos(theta); - T sintheta = sin(theta); + T theta = (angle * static_cast<T>(Mathd::pi()))/180; + T costheta = static_cast<T>(Mathd::Cos(theta)); + T sintheta = static_cast<T>(Mathd::Sin(theta)); T nx = x - origin.x; T ny = y - origin.y; @@ -281,7 +281,7 @@ T invLength = 1.0/length(); //TODO: get rid of this static cast - if (invLength > static_cast<T>(DBL_ZERO_TOLERANCE)) { + if (invLength > static_cast<T>(Mathd::zeroTolerance())) { x = x * invLength; y = y * invLength; z = z * invLength;
--- a/engine/core/video/devicecaps.cpp Tue Oct 12 18:58:47 2010 +0000 +++ b/engine/core/video/devicecaps.cpp Wed Oct 13 20:24:48 2010 +0000 @@ -21,6 +21,7 @@ // Standard C++ library includes #include <iostream> +#include <algorithm> // 3rd party library includes #include <SDL.h> @@ -51,6 +52,18 @@ m_SDLFlags = rhs.getSDLFlags(); } + bool ScreenMode::operator <(const ScreenMode& rhs) const { + if (m_bpp < rhs.getBPP() ) { + return true; + } + else if (m_bpp == rhs.getBPP()) { + if (m_width < rhs.getWidth() || m_height < rhs.getHeight()) { + return true; + } + } + return false; + } + DeviceCaps::DeviceCaps() : m_driverName("Invalid"), m_hwAvailable(false), @@ -115,7 +128,7 @@ int bufferSize = 256; char buffer[bufferSize]; - int numBPP = 1; + int numBPP = 3; int bpps[numBPP]; //clear in case this is called twice @@ -145,8 +158,10 @@ #endif //BITS PER PIXEL - bpps[0] = 32; - + bpps[0] = 16; + bpps[1] = 24; + bpps[2] = 32; + //COMMON FS RESOLUTIONS int resolutions[15][2] = { {640, 480}, @@ -174,10 +189,9 @@ int bpp; if (flags[j] & SDL_FULLSCREEN) { bpp = SDL_VideoModeOK(resolutions[k][0],resolutions[k][1], bpps[i], flags[j]); - + if (bpp > 0) { - ScreenMode mode = ScreenMode(resolutions[k][0],resolutions[k][1], bpps[i], flags[j]); - m_screenModes.push_back(mode); + m_screenModes.push_back(ScreenMode(resolutions[k][0],resolutions[k][1], bpps[i], flags[j])); } } else { //windowed mode @@ -185,8 +199,7 @@ //we are checking to make sure the bpp is supported here. bpp = SDL_VideoModeOK(resolutions[k][0],resolutions[k][1], bpps[i], flags[j]); if (bpp > 0) { - ScreenMode mode = ScreenMode(0,0, bpps[i], flags[j]); - m_screenModes.push_back(mode); + m_screenModes.push_back(ScreenMode(0,0, bpps[i], flags[j])); break; //insert windowed mode once as all resolutions are supported. } } @@ -195,6 +208,11 @@ } } + //sort the list to keep the most preferred modes at the top of the selection process + //in getNearestScreenMode() + std::sort(m_screenModes.begin(), m_screenModes.end()); + std::reverse(m_screenModes.begin(), m_screenModes.end()); + if(SDL_VideoDriverName(buffer, bufferSize) != NULL) { m_driverName = std::string(buffer); } @@ -260,6 +278,20 @@ break; } + //current screen bpp selected + if (widthCheck && heightCheck && bpp == 0 && fsCheck && rendCheck) { + mode = ScreenMode(width, height, bpp, m_screenModes[i].getSDLFlags()); + foundMode = true; + break; + } + + if (m_screenModes[i].getWidth() == 0 && m_screenModes[i].getHeight() == 0 && bpp == 0 && fsCheck && rendCheck) { + mode = ScreenMode(width, height, bpp, m_screenModes[i].getSDLFlags()); + foundMode = true; + break; + } + + widthCheck = false; heightCheck = false; bppCheck = false;
--- a/engine/core/video/devicecaps.h Tue Oct 12 18:58:47 2010 +0000 +++ b/engine/core/video/devicecaps.h Wed Oct 13 20:24:48 2010 +0000 @@ -51,6 +51,8 @@ */ ~ScreenMode() {}; + bool operator <(const ScreenMode& rhs) const; + /** Returns the width of the screen mode. * @note If both width and height are 0 it means that ALL modes are available * for use with the specified flags. Most likely this is a windowed mode.
--- a/engine/core/view/camera.cpp Tue Oct 12 18:58:47 2010 +0000 +++ b/engine/core/view/camera.cpp Wed Oct 13 20:24:48 2010 +0000 @@ -327,7 +327,7 @@ void Camera::calculateZValue(ScreenPoint& screen_coords) { int dy = -(screen_coords.y - toScreenCoordinates(m_location.getMapCoordinates()).y); - screen_coords.z = static_cast<int>(tan(m_tilt * (DBL_PI / 180.0)) * static_cast<double>(dy)); + screen_coords.z = static_cast<int>(Mathd::Tan(m_tilt * (Mathd::pi() / 180.0)) * static_cast<double>(dy)); } ExactModelCoordinate Camera::toMapCoordinates(ScreenPoint screen_coords, bool z_calculated) {