mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Better implementation of the framerate manager, FPS timer added, minor improvements
This commit is contained in:
parent
0aad12ae67
commit
157002fe68
@ -183,6 +183,14 @@ void CCursorHandler::shiftPos( int &x, int &y )
|
||||
}
|
||||
}
|
||||
|
||||
void CCursorHandler::centerCursor()
|
||||
{
|
||||
SDL_Surface *cursor = this->cursors[mode]->ourImages[number].bitmap;
|
||||
this->xpos = (screen->w / 2.) - (cursor->w / 2.);
|
||||
this->ypos = (screen->h / 2.) - (cursor->h / 2.);
|
||||
SDL_WarpMouse(this->xpos, this->ypos);
|
||||
}
|
||||
|
||||
CCursorHandler::~CCursorHandler()
|
||||
{
|
||||
if(help)
|
||||
|
@ -35,8 +35,9 @@ public:
|
||||
|
||||
void shiftPos( int &x, int &y );
|
||||
void draw2();
|
||||
void hide(){Show=0;};
|
||||
void show(){Show=1;};
|
||||
void hide() { Show=0; };
|
||||
void show() { Show=1; };
|
||||
void centerCursor();
|
||||
~CCursorHandler();
|
||||
};
|
||||
|
||||
|
@ -266,7 +266,7 @@ int main(int argc, char** argv)
|
||||
playIntro();
|
||||
|
||||
SDL_FillRect(screen,NULL,0);
|
||||
SDL_Flip(screen);
|
||||
CSDL_Ext::update(screen);
|
||||
loading.join();
|
||||
tlog0<<"Initialization of VCMI (together): "<<total.getDif()<<std::endl;
|
||||
|
||||
|
@ -105,8 +105,6 @@ CPlayerInterface::CPlayerInterface(int Player)
|
||||
makingTurn = false;
|
||||
showingDialog = new CondSh<bool>(false);
|
||||
sysOpts = GDefaultOptions;
|
||||
//initializing framerate keeper
|
||||
//framerate keeper initialized
|
||||
cingconsole = new CInGameConsole;
|
||||
terminate_cond.set(false);
|
||||
firstCall = 1; //if loading will be overwritten in serialize
|
||||
@ -283,7 +281,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
||||
initMovement(details, ho, hp);
|
||||
|
||||
//first initializing done
|
||||
SDL_framerateDelay(GH.mainFPSmng); // after first move
|
||||
GH.mainFPSmng->framerateDelay(); // after first move
|
||||
|
||||
//main moving
|
||||
for(int i=1; i<32; i+=2*sysOpts.heroMoveSpeed)
|
||||
@ -292,7 +290,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
||||
adventureInt->updateScreen = true;
|
||||
adventureInt->show(screen);
|
||||
CSDL_Ext::update(screen);
|
||||
SDL_framerateDelay(GH.mainFPSmng); //for animation purposes
|
||||
GH.mainFPSmng->framerateDelay(); //for animation purposes
|
||||
} //for(int i=1; i<32; i+=4)
|
||||
//main moving done
|
||||
|
||||
@ -1330,18 +1328,11 @@ void CPlayerInterface::update()
|
||||
if(adventureInt && !adventureInt->selection && GH.topInt() == adventureInt)
|
||||
return;
|
||||
|
||||
GH.updateTime();
|
||||
GH.handleEvents();
|
||||
|
||||
if(adventureInt && !adventureInt->isActive() && adventureInt->scrollingDir) //player forces map scrolling though interface is disabled
|
||||
GH.totalRedraw();
|
||||
else
|
||||
GH.simpleRedraw();
|
||||
|
||||
CCS->curh->draw1();
|
||||
CSDL_Ext::update(screen);
|
||||
CCS->curh->draw2();
|
||||
|
||||
pim->unlock();
|
||||
}
|
||||
|
||||
|
@ -351,12 +351,7 @@ void CGPreGame::update()
|
||||
if(SEL)
|
||||
SEL->update();
|
||||
|
||||
CCS->curh->draw1();
|
||||
SDL_Flip(screen);
|
||||
CCS->curh->draw2();
|
||||
GH.topInt()->show(screen);
|
||||
GH.updateTime();
|
||||
GH.handleEvents();
|
||||
}
|
||||
|
||||
CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMultiMode MultiPlayer /*= CMenuScreen::SINGLE_PLAYER*/, const std::map<ui32, std::string> *Names /*= NULL*/)
|
||||
|
@ -103,6 +103,11 @@ IShowActivable * CGuiHandler::topInt()
|
||||
}
|
||||
|
||||
void CGuiHandler::totalRedraw()
|
||||
{
|
||||
this->invalidateTotalRedraw = true;
|
||||
}
|
||||
|
||||
void CGuiHandler::internalTotalRedraw()
|
||||
{
|
||||
for(int i=0;i<objsToBlit.size();i++)
|
||||
objsToBlit[i]->showAll(screen2);
|
||||
@ -111,6 +116,9 @@ void CGuiHandler::totalRedraw()
|
||||
|
||||
if(objsToBlit.size())
|
||||
objsToBlit.back()->showAll(screen);
|
||||
|
||||
this->invalidateTotalRedraw = false;
|
||||
this->invalidateSimpleRedraw = false;
|
||||
}
|
||||
|
||||
void CGuiHandler::updateTime()
|
||||
@ -303,11 +311,18 @@ void CGuiHandler::handleMouseMotion(SDL_Event *sEvent)
|
||||
}
|
||||
|
||||
void CGuiHandler::simpleRedraw()
|
||||
{
|
||||
this->invalidateSimpleRedraw = true;
|
||||
}
|
||||
|
||||
void CGuiHandler::internalSimpleRedraw()
|
||||
{
|
||||
//update only top interface and draw background
|
||||
if(objsToBlit.size() > 1)
|
||||
blitAt(screen2,0,0,screen); //blit background
|
||||
objsToBlit.back()->show(screen); //blit active interface/window
|
||||
|
||||
this->invalidateSimpleRedraw = false;
|
||||
}
|
||||
|
||||
void CGuiHandler::handleMoveInterested( const SDL_MouseMotionEvent & motion )
|
||||
@ -343,14 +358,33 @@ void CGuiHandler::run()
|
||||
setThreadName(-1, "CGuiHandler::run");
|
||||
try
|
||||
{
|
||||
SDL_initFramerate(mainFPSmng);
|
||||
CCS->curh->centerCursor();
|
||||
mainFPSmng->init(); // resets internal clock, needed for FPS manager
|
||||
while(!terminate)
|
||||
{
|
||||
if(curInt)
|
||||
curInt->update();
|
||||
curInt->update(); // calls a update and drawing process of the loaded game interface object at the moment
|
||||
|
||||
SDL_framerateDelay(mainFPSmng);
|
||||
//SDL_Delay(20); //give time for other apps
|
||||
// Handles mouse and key input
|
||||
GH.updateTime();
|
||||
GH.handleEvents();
|
||||
|
||||
// Redraws the GUI only once during rendering
|
||||
if (this->invalidateTotalRedraw == true)
|
||||
internalTotalRedraw();
|
||||
if (this->invalidateSimpleRedraw == true)
|
||||
internalSimpleRedraw();
|
||||
|
||||
if (SHOW_FPS)
|
||||
drawFPSCounter();
|
||||
|
||||
mainFPSmng->framerateDelay(); // holds a constant FPS
|
||||
|
||||
// draw the mouse cursor and update the screen
|
||||
// todo: bad way of updating the cursor, update screen should be the last statement of the rendering process
|
||||
CCS->curh->draw1();
|
||||
CSDL_Ext::update(screen);
|
||||
CCS->curh->draw2();
|
||||
}
|
||||
} HANDLE_EXCEPTION
|
||||
}
|
||||
@ -363,8 +397,8 @@ CGuiHandler::CGuiHandler()
|
||||
terminate = false;
|
||||
statusbar = NULL;
|
||||
|
||||
mainFPSmng = new FPSmanager;
|
||||
SDL_setFramerate(mainFPSmng, 48);
|
||||
// Creates the FPS manager and sets the framerate to 48 which is doubled the value of the original Heroes 3 FPS rate
|
||||
mainFPSmng = new FPSManager(48);
|
||||
}
|
||||
|
||||
CGuiHandler::~CGuiHandler()
|
||||
@ -377,6 +411,17 @@ void CGuiHandler::breakEventHandling()
|
||||
current = NULL;
|
||||
}
|
||||
|
||||
void CGuiHandler::drawFPSCounter()
|
||||
{
|
||||
const static SDL_Color yellow = {255, 255, 0, 0};
|
||||
static SDL_Rect overlay = { 0, 0, 64, 32};
|
||||
Uint32 black = SDL_MapRGB(screen->format, 10, 10, 10);
|
||||
SDL_FillRect(screen, &overlay, black);
|
||||
std::string fps = toString(mainFPSmng->fps);
|
||||
CSDL_Ext::printAt(fps, 10, 10, FONT_BIG, yellow, screen);
|
||||
}
|
||||
|
||||
|
||||
void CIntObject::activateLClick()
|
||||
{
|
||||
GH.lclickable.push_front(this);
|
||||
|
@ -511,8 +511,16 @@ public:
|
||||
/// Handles GUI logic and drawing
|
||||
class CGuiHandler
|
||||
{
|
||||
private:
|
||||
bool invalidateTotalRedraw;
|
||||
bool invalidateSimpleRedraw;
|
||||
|
||||
void internalTotalRedraw();
|
||||
void internalSimpleRedraw();
|
||||
|
||||
public:
|
||||
FPSmanager * mainFPSmng; //to keep const framerate
|
||||
const static bool SHOW_FPS = false; // shows a fps counter when set to true
|
||||
FPSManager *mainFPSmng; //to keep const framerate
|
||||
timeHandler th;
|
||||
std::list<IShowActivable *> listInt; //list of interfaces - front=foreground; back = background (includes adventure map, window interfaces, all kind of active dialogs, and so on)
|
||||
IStatusBar * statusbar;
|
||||
@ -539,14 +547,17 @@ public:
|
||||
|
||||
CGuiHandler();
|
||||
~CGuiHandler();
|
||||
void run();
|
||||
void totalRedraw(); //forces total redraw (using showAll)
|
||||
void simpleRedraw(); //update only top interface and draw background from buffer
|
||||
void run(); // holds the main loop for the whole program after initialization and manages the update/rendering system
|
||||
|
||||
void totalRedraw(); //forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering
|
||||
void simpleRedraw(); //update only top interface and draw background from buffer, sets a flag, method gets called at the end of the rendering
|
||||
|
||||
void popInt(IShowActivable *top); //removes given interface from the top and activates next
|
||||
void popIntTotally(IShowActivable *top); //deactivates, deletes, removes given interface from the top and activates next
|
||||
void pushInt(IShowActivable *newInt); //deactivate old top interface, activates this one and pushes to the top
|
||||
void popInts(int howMany); //pops one or more interfaces - deactivates top, deletes and removes given number of interfaces, activates new front
|
||||
IShowActivable *topInt(); //returns top interface
|
||||
|
||||
void updateTime(); //handles timeInterested
|
||||
void handleEvents(); //takes events from queue and calls interested objects
|
||||
void handleEvent(SDL_Event *sEvent);
|
||||
@ -554,6 +565,7 @@ public:
|
||||
void handleMoveInterested( const SDL_MouseMotionEvent & motion );
|
||||
void fakeMouseMove();
|
||||
void breakEventHandling(); //current event won't be propagated anymore
|
||||
void CGuiHandler::drawFPSCounter(); // draws the FPS to the upper left corner of the screen
|
||||
ui8 defActionsDef; //default auto actions
|
||||
ui8 captureChildren; //all newly created objects will get their parents from stack and will be added to parents children list
|
||||
std::list<CIntObject *> createdObj; //stack of objs being created
|
||||
|
@ -1,84 +1,41 @@
|
||||
|
||||
/*
|
||||
|
||||
SDL_framerate: framerate manager
|
||||
|
||||
LGPL (c) A. Schiffler
|
||||
|
||||
/*
|
||||
* SDL_framerate.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "SDL_framerate.h"
|
||||
#include <SDL.h>
|
||||
|
||||
/*
|
||||
Initialize the framerate manager
|
||||
*/
|
||||
|
||||
void SDL_initFramerate(FPSmanager * manager)
|
||||
FPSManager::FPSManager(int rate)
|
||||
{
|
||||
/*
|
||||
* Store some sane values
|
||||
*/
|
||||
manager->framecount = 0;
|
||||
manager->rate = FPS_DEFAULT;
|
||||
manager->rateticks = (1000.0 / (float) FPS_DEFAULT);
|
||||
manager->lastticks = SDL_GetTicks();
|
||||
this->rate = rate;
|
||||
this->rateticks = (1000.0 / (double) rate);
|
||||
this->fps = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Set the framerate in Hz
|
||||
*/
|
||||
|
||||
int SDL_setFramerate(FPSmanager * manager, int rate)
|
||||
void FPSManager::init()
|
||||
{
|
||||
if ((rate >= FPS_LOWER_LIMIT) && (rate <= FPS_UPPER_LIMIT)) {
|
||||
manager->framecount = 0;
|
||||
manager->rate = rate;
|
||||
manager->rateticks = (1000.0 / (float) rate);
|
||||
return (0);
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
this->lastticks = SDL_GetTicks();
|
||||
}
|
||||
|
||||
/*
|
||||
Return the current target framerate in Hz
|
||||
*/
|
||||
|
||||
int SDL_getFramerate(FPSmanager * manager)
|
||||
void FPSManager::framerateDelay()
|
||||
{
|
||||
if (manager == NULL) {
|
||||
return (-1);
|
||||
} else {
|
||||
return (manager->rate);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Delay execution to maintain a constant framerate. Calculate fps.
|
||||
*/
|
||||
|
||||
void SDL_framerateDelay(FPSmanager * manager)
|
||||
{
|
||||
Uint32 current_ticks;
|
||||
Uint32 target_ticks;
|
||||
Uint32 the_delay;
|
||||
|
||||
/*
|
||||
* Next frame
|
||||
*/
|
||||
manager->framecount++;
|
||||
|
||||
/*
|
||||
* Get/calc ticks
|
||||
*/
|
||||
current_ticks = SDL_GetTicks();
|
||||
target_ticks = manager->lastticks + (Uint32) ((float) manager->framecount * manager->rateticks);
|
||||
|
||||
if (current_ticks <= target_ticks) {
|
||||
the_delay = target_ticks - current_ticks;
|
||||
SDL_Delay(the_delay);
|
||||
} else {
|
||||
manager->framecount = 0;
|
||||
manager->lastticks = SDL_GetTicks();
|
||||
}
|
||||
Uint32 currentTicks = SDL_GetTicks();
|
||||
double diff = currentTicks - this->lastticks;
|
||||
|
||||
if (diff < this->rateticks) // FPS is higher than it should be, then wait some time
|
||||
{
|
||||
SDL_Delay(ceil(this->rateticks) - diff);
|
||||
}
|
||||
|
||||
this->fps = ceil(1000. / (SDL_GetTicks() - this->lastticks));
|
||||
this->lastticks = SDL_GetTicks();
|
||||
}
|
||||
|
@ -1,65 +1,33 @@
|
||||
|
||||
/*
|
||||
|
||||
SDL_framerate: framerate manager
|
||||
|
||||
LGPL (c) A. Schiffler
|
||||
|
||||
/*
|
||||
* timeHandler.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SDL_framerate_h
|
||||
#define _SDL_framerate_h
|
||||
|
||||
/* Set up for C function definitions, even when using C++ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
/// A fps manager which holds game updates at a constant rate
|
||||
class FPSManager
|
||||
{
|
||||
private:
|
||||
double rateticks;
|
||||
unsigned int lastticks;
|
||||
int rate;
|
||||
|
||||
public:
|
||||
int fps; // the actual fps value
|
||||
|
||||
FPSManager(int rate); // initializes the manager with a given fps rate
|
||||
void FPSManager::init(); // needs to be called directly before the main game loop to reset the internal timer
|
||||
void framerateDelay(); // needs to be called every game update cycle
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* --- */
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
/* --------- Definitions */
|
||||
|
||||
/* Some rates in Hz */
|
||||
|
||||
#define FPS_UPPER_LIMIT 200
|
||||
#define FPS_LOWER_LIMIT 1
|
||||
#define FPS_DEFAULT 30
|
||||
|
||||
/* --------- Structure variables */
|
||||
|
||||
typedef struct {
|
||||
Uint32 framecount;
|
||||
float rateticks;
|
||||
Uint32 lastticks;
|
||||
Uint32 rate;
|
||||
} FPSmanager;
|
||||
|
||||
/* --------- Function prototypes */
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef BUILD_DLL
|
||||
#define DLLINTERFACE __declspec(dllexport)
|
||||
#else
|
||||
#define DLLINTERFACE __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define DLLINTERFACE
|
||||
#endif
|
||||
|
||||
/* Functions return 0 or value for sucess and -1 for error */
|
||||
|
||||
void SDL_initFramerate(FPSmanager * manager);
|
||||
int SDL_setFramerate(FPSmanager * manager, int rate);
|
||||
int SDL_getFramerate(FPSmanager * manager);
|
||||
void SDL_framerateDelay(FPSmanager * manager);
|
||||
|
||||
/* --- */
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SDL_framerate_h */
|
||||
|
12
global.h
12
global.h
@ -135,7 +135,6 @@ const int BFIELD_SIZE = BFIELD_WIDTH * BFIELD_HEIGHT;
|
||||
|
||||
const int SPELLBOOK_GOLD_COST = 500;
|
||||
|
||||
|
||||
//for battle stacks' positions
|
||||
struct THex
|
||||
{
|
||||
@ -348,6 +347,17 @@ enum EAlignment
|
||||
{
|
||||
GOOD, EVIL, NEUTRAL
|
||||
};
|
||||
|
||||
// Converts an int/double or any data type you wish to a string
|
||||
template<typename T>
|
||||
std::string toString(const T& value)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << value;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
//uncomment to make it work
|
||||
//#define MARK_BLOCKED_POSITIONS
|
||||
//#define MARK_VISITABLE_POSITIONS
|
||||
|
Loading…
Reference in New Issue
Block a user