diff --git a/src/framework/engine.cpp b/src/framework/engine.cpp index 93839b43..b8bab578 100644 --- a/src/framework/engine.cpp +++ b/src/framework/engine.cpp @@ -30,6 +30,8 @@ #include "configs.h" #include "gamestate.h" +#define MINIMUN_UPDATE_DELAY 50 + Engine g_engine; void Engine::init() @@ -54,31 +56,57 @@ void Engine::terminate() void Engine::run() { - ulong ticks; - static ulong lastFrameTicks; - + int ticks = Platform::getTicks(); + int lastUpdateTicks = ticks; + int lastFpsTicks = ticks; + int updateElapsedTicks = ticks; + int frameCount = 0; + int fps = 0; m_running = true; - lastFrameTicks = Platform::getTicks(); + // before redering do the first update + update(ticks, 0); + lastUpdateTicks = ticks; + + Font *font = g_fonts.getDefault(); + Point fpsPos(10,10); + while(!m_stopping) { // fire platform events Platform::poll(); - // update + // update before redering ticks = Platform::getTicks(); - update(ticks, ticks - lastFrameTicks); - lastFrameTicks = ticks; + updateElapsedTicks = ticks - lastUpdateTicks; + if(updateElapsedTicks >= MINIMUN_UPDATE_DELAY) { + update(ticks, updateElapsedTicks); + lastUpdateTicks = ticks; + } // render only when visible - //if(Platform::isWindowVisible()) { + if(Platform::isWindowVisible()) { + // calculate and fps + if(m_calculateFps && font) { + frameCount++; + if(ticks - lastFpsTicks >= 1000) { + lastFpsTicks = ticks; + fps = frameCount; + frameCount = 0; + } + } + render(); + // render fps + if(m_calculateFps && font) { + font->renderText(fpsPos, format("FPS: %d", fps)); + } + // swap buffers Platform::swapBuffers(); - //} + } } - lastFrameTicks = 0; m_stopping = false; m_running = false; } diff --git a/src/framework/engine.h b/src/framework/engine.h index 14a7a90e..99e9b9a1 100644 --- a/src/framework/engine.h +++ b/src/framework/engine.h @@ -36,6 +36,7 @@ class Engine public: Engine() : m_stopping(false), m_running(false), + m_calculateFps(false), m_currentState(NULL) { } void init(); @@ -60,6 +61,9 @@ public: /// Fired by platform on mouse/keyboard input void onInputEvent(InputEvent *event); + /// Enable FPS counter on screen + void enableFpsCounter(bool enable = true) { m_calculateFps = enable; }; + private: /// Called to render every frame void render(); @@ -68,6 +72,7 @@ private: bool m_stopping; bool m_running; + bool m_calculateFps; GameState *m_currentState; }; diff --git a/src/framework/font.cpp b/src/framework/font.cpp index e68fb8c4..a9c746ba 100644 --- a/src/framework/font.cpp +++ b/src/framework/font.cpp @@ -109,25 +109,27 @@ void Font::renderText(const Point& pos, const std::string& text) Point currentPos = pos; const Size& screenSize = g_graphics.getScreenSize(); + const Size& textureSize = m_texture->getSize(); int textLenght = text.length(); for(int i = 0; i < textLenght; ++i) { - int c = (int)text[i]; + int glyph = (int)text[i]; // break rendering if the Y pos is below the screen if(currentPos.y >= screenSize.height()) break; // new line - if(c == '\n') { + if(glyph == (uchar)'\n') { currentPos.y += m_lineHeight; currentPos.x = pos.x; } - // render glyph - else { - // render online if is visible on screen - if(currentPos.x < screenSize.width()) - currentPos.x += renderGlyph(currentPos, c); + // render only if the glyph is valid and visible + else if(glyph >= 32 && currentPos.x < screenSize.width()) { + g_graphics._drawTexturedRect(Rect(currentPos, m_glyphsSize[glyph]), + m_glyphsTextureCoords[glyph], + textureSize); + currentPos.x += m_glyphsSize[glyph].width(); } } @@ -136,15 +138,23 @@ void Font::renderText(const Point& pos, const std::string& text) g_graphics.resetColor(); } -int Font::renderGlyph(const Point& pos, int glyph) +Size Font::calculateTextSize(const std::string& text) { - // don't render invalid glyphs - if(glyph < 32) - return 0; + int textLenght = text.length(); + Size size; + Point currentPos; - // render glyph - Rect screenCoords(pos, m_glyphsSize[glyph]); - g_graphics._drawTexturedRect(screenCoords, m_glyphsTextureCoords[glyph], m_texture->getSize()); + for(int i = 0; i < textLenght; ++i) { + int glyph = (int)text[i]; - return m_glyphsSize[glyph].width(); + if(glyph == (uchar)'\n') { + currentPos.y += m_lineHeight; + size.expandedTo(currentPos.toSize()); + currentPos.x = 0; + } + else if(glyph > 32) { + currentPos.x += m_glyphsSize[glyph].width(); + } + } + return size; } diff --git a/src/framework/font.h b/src/framework/font.h index 29b2aed3..dc50d42c 100644 --- a/src/framework/font.h +++ b/src/framework/font.h @@ -39,9 +39,21 @@ public: /// Load font from file bool load(const std::string &file); - /// Simple text render + /// Simple text render starting at pos void renderText(const Point& pos, const std::string& text); + /// Render text delimited by screenCoords rect + void renderText(const Rect& screenCoords, const std::string& text); + + /** Advanced text render + * screenCoords is the rect that will be filled on the screen + * startRenderPosition is the postion to start rendering relative to the text rect + */ + void renderText(const Rect& screenCoords, const Point& startRenderPosition, const std::string& text); + + /// Simulate render and calculate text size + Size calculateTextSize(const std::string& text); + /* enum EAlign { ALIGN_TOP = 1 << 0, @@ -60,9 +72,6 @@ public: void renderText(const Rect& screenCoords, EAlign align, const std::string& text); */ - /// Render a text - int renderGlyph(const Point& pos, int glyph); - private: int m_lineHeight; int m_cursorSize; diff --git a/src/framework/fonts.cpp b/src/framework/fonts.cpp index 86c5ebb9..fd0d2213 100644 --- a/src/framework/fonts.cpp +++ b/src/framework/fonts.cpp @@ -51,3 +51,13 @@ Font* Fonts::get(const std::string& fontName) error("Font \"%s\" not found", fontName.c_str()); return NULL; } + +Font *Fonts::getDefault() +{ + Font *font = get("tibia-10px-rounded"); + if(font) { + return font; + } + fatal("Default font not found!"); + return NULL; +} diff --git a/src/framework/fonts.h b/src/framework/fonts.h index c233d21f..119a00c6 100644 --- a/src/framework/fonts.h +++ b/src/framework/fonts.h @@ -39,6 +39,9 @@ public: /// Get a font by name Font *get(const std::string& fontName); + /// Get default font + Font *getDefault(); + /// Terminate all fonts void terminate() { } diff --git a/src/main.cpp b/src/main.cpp index 769b77c2..20298e0d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -101,7 +101,7 @@ int main(int argc, const char *argv[]) 640, 480, g_configs.getBoolean("window maximized")); Platform::setWindowTitle("OTClient"); - Platform::setVsync(); + //Platform::setVsync(); // init engine g_engine.init(); @@ -113,6 +113,7 @@ int main(int argc, const char *argv[]) Platform::showWindow(); //Platform::hideMouseCursor(); + g_engine.enableFpsCounter(); // main loop, run everything g_engine.run(); diff --git a/src/menustate.cpp b/src/menustate.cpp index 8c90eb65..63b139e4 100644 --- a/src/menustate.cpp +++ b/src/menustate.cpp @@ -67,14 +67,7 @@ void MenuState::render() Rect texCoords(0, 0, texCoordsSize); texCoords.moveBottomRight(texSize.toPoint()); g_graphics.drawTexturedRect(Rect(0, 0, screenSize), m_background.get(), texCoords); - - Font *font = g_fonts.get("sans-11px-antialised"); - if(font) - font->renderText(Point(10,10), "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac orci id quam condimentum semper."); - - font = g_fonts.get("tibia-10px-rounded"); - if(font) - font->renderText(Point(10,30), "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac orci id quam condimentum semper."); + g_fonts.getDefault()->renderText(Point(10,screenSize.height() - 20), "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac orci id quam condimentum semper."); } void MenuState::update(int ticks, int elapsedTicks)