diff --git a/src/modules/font/freetype/Font.cpp b/src/modules/font/freetype/Font.cpp index 6aa3b243d..0379a847f 100644 --- a/src/modules/font/freetype/Font.cpp +++ b/src/modules/font/freetype/Font.cpp @@ -52,7 +52,7 @@ Rasterizer *Font::newRasterizer(love::image::ImageData *data, const std::string { size_t strlen = text.size(); size_t numglyphs = 0; - + unsigned int *glyphs = new unsigned int[strlen]; try diff --git a/src/modules/timer/Timer.h b/src/modules/timer/Timer.h index 79421729a..40e394bbc 100644 --- a/src/modules/timer/Timer.h +++ b/src/modules/timer/Timer.h @@ -63,21 +63,19 @@ public: * @return The "current" FPS. **/ virtual int getFPS() const = 0; + + /** + * Gets the average delta time (seconds per frame) over the last second. + **/ virtual double getAverageDelta() const = 0; /** - * Gets the amount of time since the program started. Only useful for timing - * code or measuring intervals. - * @return The time (in seconds) since the program started. - **/ - virtual double getTime() const = 0; - - /** - * Gets the amount of time passed since an unspecified time. The time is accurate - * to the microsecond, and is limited to 24 hours. + * Gets the amount of time passed since an unspecified time. Useful for + * profiling code or measuring intervals. The time is microsecond-precise, + * and increases monotonically. * @return The time (in seconds) **/ - virtual double getMicroTime() const = 0; + virtual double getTime() const = 0; }; // Timer diff --git a/src/modules/timer/sdl/Timer.cpp b/src/modules/timer/sdl/Timer.cpp index d308c87af..23c797076 100644 --- a/src/modules/timer/sdl/Timer.cpp +++ b/src/modules/timer/sdl/Timer.cpp @@ -18,17 +18,38 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "common/config.h" -#include "common/delay.h" +#include "Timer.h" -#ifdef LOVE_WINDOWS -# include -# include -#else -# include +#include "common/delay.h" +#include "common/int.h" + +// SDL +#include + +#if defined(LOVE_WINDOWS) +#include +#elif defined(LOVE_MACOSX) +#include +#include +#elif defined(LOVE_LINUX) +#include +#include +#include #endif -#include "Timer.h" +namespace +{ +#if defined(LOVE_LINUX) +inline double getTimeOfDay() +{ + timeval t; + gettimeofday(&t, NULL); + return (double) t.tv_sec + (double) t.tv_usec / 1000000.0; +} +#endif +} namespace love { @@ -45,12 +66,13 @@ Timer::Timer() , fpsUpdateFrequency(1) , frames(0) , dt(0) + , timerFrequency(getTimerFrequency()) { - // Init the SDL timer system. + // Init the SDL timer system (needed for SDL_Delay.) if (SDL_InitSubSystem(SDL_INIT_TIMER) < 0) - throw Exception(SDL_GetError()); + throw love::Exception("%s", SDL_GetError()); - prevFpsUpdate = currTime = getMicroTime(); + prevFpsUpdate = currTime = getTime(); } Timer::~Timer() @@ -72,10 +94,10 @@ void Timer::step() // "Current" time is previous time by now. prevTime = currTime; - // Get ticks from SDL - currTime = getMicroTime(); + // Get ticks from system. + currTime = getTime(); - // Convert to number of seconds + // Convert to number of seconds. dt = currTime - prevTime; double timeSinceLast = currTime - prevFpsUpdate; @@ -110,35 +132,45 @@ double Timer::getAverageDelta() const return averageDelta; } -double Timer::getTime() const +double Timer::getTimerFrequency() { - return SDL_GetTicks()/1000.0; +#if defined(LOVE_MACOSX) + mach_timebase_info_data_t info; + mach_timebase_info(&info); + return (double) info.numer / (double) info.denom / 1000000000.0; +#elif defined(LOVE_WINDOWS) + LARGE_INTEGER temp; + if (QueryPerformanceFrequency(&temp) != 0 && temp.QuadPart != 0) + return 1.0 / (double) temp.QuadPart; +#endif + return 0; } -double Timer::getMicroTime() const +double Timer::getTime() const { -#ifdef LOVE_WINDOWS - static __int64 freq = 0; - - if (!freq) - { - LARGE_INTEGER temp; - QueryPerformanceFrequency(&temp); - - freq = (__int64) temp.QuadPart; - } - +#if defined(LOVE_LINUX) + double mt; + // Check for POSIX timers and monotonic clocks. If not supported, use the gettimeofday fallback. +#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) \ +&& (defined(CLOCK_MONOTONIC_RAW) || defined(CLOCK_MONOTONIC)) + timespec t; +#ifdef CLOCK_MONOTONIC_RAW + clockid_t clk_id = CLOCK_MONOTONIC_RAW; +#else + clockid_t clk_id = CLOCK_MONOTONIC; +#endif + if (clock_gettime(clk_id, &t) == 0) + mt = (double) t.tv_sec + (double) t.tv_nsec / 1000000000.0; + else +#endif + mt = getTimeOfDay(); + return mt; +#elif defined(LOVE_MACOSX) + return (double) mach_absolute_time() * timerFrequency; +#elif defined(LOVE_WINDOWS) LARGE_INTEGER microTime; QueryPerformanceCounter(µTime); - - // The 64 to 32 bit integer conversion, assuming the fraction part down - // to microseconds takes 20 bits, should not be a problem unless the - // system has an uptime of a few decades. - return (double) microTime.QuadPart / (double) freq; -#else - timeval t; - gettimeofday(&t, NULL); - return t.tv_sec + t.tv_usec/1000000.0; + return (double) microTime.QuadPart * timerFrequency; #endif } diff --git a/src/modules/timer/sdl/Timer.h b/src/modules/timer/sdl/Timer.h index ea6cf6156..5d8e160bb 100644 --- a/src/modules/timer/sdl/Timer.h +++ b/src/modules/timer/sdl/Timer.h @@ -21,11 +21,8 @@ #ifndef LOVE_TIMER_SDL_TIMER_H #define LOVE_TIMER_SDL_TIMER_H -// SDL -#include - // LOVE -#include +#include "timer/Timer.h" namespace love { @@ -59,7 +56,6 @@ public: int getFPS() const; double getAverageDelta() const; double getTime() const; - double getMicroTime() const; private: @@ -81,6 +77,12 @@ private: // The current timestep. double dt; + // The reciprocal of the timer frequency. + const double timerFrequency; + + // Returns the timer frequency on some platforms. + static double getTimerFrequency(); + }; // Timer } // sdl diff --git a/src/modules/timer/wrap_Timer.cpp b/src/modules/timer/wrap_Timer.cpp index 6379d5bb2..fad032340 100644 --- a/src/modules/timer/wrap_Timer.cpp +++ b/src/modules/timer/wrap_Timer.cpp @@ -68,12 +68,6 @@ int w_getTime(lua_State *L) return 1; } -int w_getMicroTime(lua_State *L) -{ - lua_pushnumber(L, instance->getMicroTime()); - return 1; -} - // List of functions to wrap. static const luaL_Reg functions[] = { @@ -83,7 +77,6 @@ static const luaL_Reg functions[] = { "getAverageDelta", w_getAverageDelta }, { "sleep", w_sleep }, { "getTime", w_getTime }, - { "getMicroTime", w_getMicroTime }, { 0, 0 } }; diff --git a/src/modules/timer/wrap_Timer.h b/src/modules/timer/wrap_Timer.h index 10646cb70..fd29481dc 100644 --- a/src/modules/timer/wrap_Timer.h +++ b/src/modules/timer/wrap_Timer.h @@ -35,7 +35,6 @@ int w_getFPS(lua_State *L); int w_getAverageDelta(lua_State *L); int w_sleep(lua_State *L); int w_getTime(lua_State *L); -int w_getMicroTime(lua_State *L); extern "C" LOVE_EXPORT int luaopen_love_timer(lua_State *L); } // timer diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 4910e88b1..be367d2a2 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -18,15 +18,15 @@ * 3. This notice may not be removed or altered from any source distribution. **/ -// STL -#include +// LOVE +#include "common/config.h" +#include "Window.h" // SDL #include -// LOVE -#include "common/config.h" -#include "Window.h" +// STL +#include namespace love { @@ -49,7 +49,9 @@ Window::~Window() } Window::_currentMode::_currentMode() - : width(800), height(600), fullscreen(false), vsync(true), fsaa(0) + : width(800) + , height(600) + , flags() { } @@ -177,12 +179,12 @@ bool Window::setWindow(int width, int height, WindowFlags *flags) // Set the new display mode as the current display mode. currentMode.width = width; currentMode.height = height; - currentMode.fsaa = fsaa; - currentMode.fullscreen = fullscreen; - currentMode.vsync = (real_vsync != 0); - currentMode.resizable = ((surface->flags & SDL_RESIZABLE) != 0); - currentMode.borderless = ((surface->flags & SDL_NOFRAME) != 0); - currentMode.centered = centered; + currentMode.flags.fsaa = fsaa; + currentMode.flags.fullscreen = fullscreen; + currentMode.flags.vsync = (real_vsync != 0); + currentMode.flags.resizable = ((surface->flags & SDL_RESIZABLE) != 0); + currentMode.flags.borderless = ((surface->flags & SDL_NOFRAME) != 0); + currentMode.flags.centered = centered; return true; } @@ -191,12 +193,7 @@ void Window::getWindow(int &width, int &height, WindowFlags &flags) const { width = currentMode.width; height = currentMode.height; - flags.fullscreen = currentMode.fullscreen; - flags.vsync = currentMode.vsync; - flags.fsaa = currentMode.fsaa; - flags.resizable = currentMode.resizable; - flags.borderless = currentMode.borderless; - flags.centered = currentMode.centered; + flags = currentMode.flags; } bool Window::checkWindowSize(int width, int height, bool fullscreen) const @@ -232,6 +229,7 @@ WindowSize *Window::getFullscreenSizes(int &n) const WindowSize w = {modes[i]->w, modes[i]->h}; sizes[i] = w; } + return sizes; } @@ -286,6 +284,7 @@ bool Window::setIcon(love::image::ImageData *imgd) SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(imgd->getData(), w, h, 32, pitch, rmask, gmask, bmask, amask); SDL_WM_SetIcon(icon, NULL); SDL_FreeSurface(icon); + return true; } diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index 6269db2ac..adcea8ac7 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -22,7 +22,7 @@ #define LOVE_WINDOW_SDL_WINDOW_H // LOVE -#include +#include "window/Window.h" namespace love { @@ -34,6 +34,7 @@ namespace sdl class Window : public love::window::Window { public: + Window(); ~Window(); @@ -62,21 +63,23 @@ public: static love::window::Window *getSingleton(); const char *getName() const; + private: + std::string windowTitle; + struct _currentMode { _currentMode(); + int width; int height; - bool fullscreen; - bool vsync; - int fsaa; - bool resizable; - bool borderless; - bool centered; + WindowFlags flags; + } currentMode; + bool created; + }; // Window } // sdl