Implement FPS display (F2 to toggle ON/OFF)
This commit is contained in:
		
							parent
							
								
									41675859dd
								
							
						
					
					
						commit
						26843f2e51
					
				
					 3 changed files with 127 additions and 2 deletions
				
			
		| 
						 | 
					@ -54,7 +54,9 @@ enum
 | 
				
			||||||
	REQUEST_SETFULLSCREEN,
 | 
						REQUEST_SETFULLSCREEN,
 | 
				
			||||||
	REQUEST_WINRESIZE,
 | 
						REQUEST_WINRESIZE,
 | 
				
			||||||
	REQUEST_MESSAGEBOX,
 | 
						REQUEST_MESSAGEBOX,
 | 
				
			||||||
	REQUEST_SETCURSORVISIBLE
 | 
						REQUEST_SETCURSORVISIBLE,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						UPDATE_FPS
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EventThread::EventThread()
 | 
					EventThread::EventThread()
 | 
				
			||||||
| 
						 | 
					@ -70,6 +72,13 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fullscreen = rtData.config.fullscreen;
 | 
						fullscreen = rtData.config.fullscreen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fps.lastFrame = SDL_GetPerformanceCounter();
 | 
				
			||||||
 | 
						fps.displaying = false;
 | 
				
			||||||
 | 
						fps.immInitFlag = false;
 | 
				
			||||||
 | 
						fps.immFiniFlag = false;
 | 
				
			||||||
 | 
						fps.acc = 0;
 | 
				
			||||||
 | 
						fps.accDiv = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool cursorInWindow = false;
 | 
						bool cursorInWindow = false;
 | 
				
			||||||
	bool windowFocused = false;
 | 
						bool windowFocused = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,6 +88,11 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
	if (SDL_NumJoysticks() > 0)
 | 
						if (SDL_NumJoysticks() > 0)
 | 
				
			||||||
		js = SDL_JoystickOpen(0);
 | 
							js = SDL_JoystickOpen(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char buffer[128];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char pendingTitle[128];
 | 
				
			||||||
 | 
						bool havePendingTitle = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (true)
 | 
						while (true)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (!SDL_WaitEvent(&event))
 | 
							if (!SDL_WaitEvent(&event))
 | 
				
			||||||
| 
						 | 
					@ -135,6 +149,39 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
			    (event.key.keysym.mod & KMOD_LALT))
 | 
								    (event.key.keysym.mod & KMOD_LALT))
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				setFullscreen(win, !fullscreen);
 | 
									setFullscreen(win, !fullscreen);
 | 
				
			||||||
 | 
									if (!fullscreen && havePendingTitle)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										SDL_SetWindowTitle(win, pendingTitle);
 | 
				
			||||||
 | 
										pendingTitle[0] = '\0';
 | 
				
			||||||
 | 
										havePendingTitle = false;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (event.key.keysym.scancode == SDL_SCANCODE_F2)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (!fps.displaying)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										fps.immInitFlag = true;
 | 
				
			||||||
 | 
										fps.displaying = true;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										fps.displaying = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if (fullscreen)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											/* Prevent fullscreen flicker */
 | 
				
			||||||
 | 
											strncpy(pendingTitle, rtData.config.game.title.constData(),
 | 
				
			||||||
 | 
											        sizeof(pendingTitle));
 | 
				
			||||||
 | 
											havePendingTitle = true;
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										SDL_SetWindowTitle(win, rtData.config.game.title.constData());
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,6 +209,25 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
			updateCursorState(cursorInWindow);
 | 
								updateCursorState(cursorInWindow);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case UPDATE_FPS :
 | 
				
			||||||
 | 
								if (!fps.displaying)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								snprintf(buffer, sizeof(buffer), "%s - %d FPS",
 | 
				
			||||||
 | 
								         rtData.config.game.title.constData(), event.user.code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Updating the window title in fullscreen
 | 
				
			||||||
 | 
								 * mode seems to cause flickering */
 | 
				
			||||||
 | 
								if (fullscreen)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									strncpy(pendingTitle, buffer, sizeof(pendingTitle));
 | 
				
			||||||
 | 
									havePendingTitle = true;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								SDL_SetWindowTitle(win, buffer);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case SDL_KEYUP :
 | 
							case SDL_KEYUP :
 | 
				
			||||||
			keyStates[event.key.keysym.scancode] = false;
 | 
								keyStates[event.key.keysym.scancode] = false;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -309,3 +375,41 @@ bool EventThread::getShowCursor() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return showCursor;
 | 
						return showCursor;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EventThread::notifyFrame()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!fps.displaying)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t current = SDL_GetPerformanceCounter();
 | 
				
			||||||
 | 
						uint64_t diff = current - fps.lastFrame;
 | 
				
			||||||
 | 
						fps.lastFrame = current;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fps.immInitFlag)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fps.immInitFlag = false;
 | 
				
			||||||
 | 
							fps.immFiniFlag = true;
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static uint64_t freq = SDL_GetPerformanceFrequency();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int32_t currFPS = freq / diff;
 | 
				
			||||||
 | 
						fps.acc += currFPS;
 | 
				
			||||||
 | 
						++fps.accDiv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fps.displayCounter += diff;
 | 
				
			||||||
 | 
						if (fps.displayCounter < freq && !fps.immFiniFlag)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fps.displayCounter = 0;
 | 
				
			||||||
 | 
						fps.immFiniFlag = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int32_t avgFPS = fps.acc / fps.accDiv;
 | 
				
			||||||
 | 
						fps.acc = fps.accDiv = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SDL_Event event;
 | 
				
			||||||
 | 
						event.user.code = avgFPS;
 | 
				
			||||||
 | 
						event.user.type = UPDATE_FPS;
 | 
				
			||||||
 | 
						SDL_PushEvent(&event);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,8 @@
 | 
				
			||||||
#include <QByteArray>
 | 
					#include <QByteArray>
 | 
				
			||||||
#include <QVector>
 | 
					#include <QVector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct RGSSThreadData;
 | 
					struct RGSSThreadData;
 | 
				
			||||||
struct SDL_Thread;
 | 
					struct SDL_Thread;
 | 
				
			||||||
struct SDL_Window;
 | 
					struct SDL_Window;
 | 
				
			||||||
| 
						 | 
					@ -66,7 +68,7 @@ public:
 | 
				
			||||||
	void process(RGSSThreadData &rtData);
 | 
						void process(RGSSThreadData &rtData);
 | 
				
			||||||
	void cleanup();
 | 
						void cleanup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Called from rgss thread */
 | 
						/* Called from RGSS thread */
 | 
				
			||||||
	void requestFullscreenMode(bool mode);
 | 
						void requestFullscreenMode(bool mode);
 | 
				
			||||||
	void requestWindowResize(int width, int height);
 | 
						void requestWindowResize(int width, int height);
 | 
				
			||||||
	void requestShowCursor(bool mode);
 | 
						void requestShowCursor(bool mode);
 | 
				
			||||||
| 
						 | 
					@ -78,13 +80,28 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void showMessageBox(const char *body, int flags = 0);
 | 
						void showMessageBox(const char *body, int flags = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* RGSS thread calls this once per frame */
 | 
				
			||||||
 | 
						void notifyFrame();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void resetInputStates();
 | 
						void resetInputStates();
 | 
				
			||||||
	void setFullscreen(SDL_Window *, bool mode);
 | 
						void setFullscreen(SDL_Window *, bool mode);
 | 
				
			||||||
	void updateCursorState(bool inWindow);
 | 
						void updateCursorState(bool inWindow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool fullscreen;
 | 
						bool fullscreen;
 | 
				
			||||||
	bool showCursor;
 | 
						bool showCursor;
 | 
				
			||||||
	volatile bool msgBoxDone;
 | 
						volatile bool msgBoxDone;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							uint64_t lastFrame;
 | 
				
			||||||
 | 
							uint64_t displayCounter;
 | 
				
			||||||
 | 
							bool displaying;
 | 
				
			||||||
 | 
							bool immInitFlag;
 | 
				
			||||||
 | 
							bool immFiniFlag;
 | 
				
			||||||
 | 
							uint64_t acc;
 | 
				
			||||||
 | 
							uint32_t accDiv;
 | 
				
			||||||
 | 
						} fps;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Used to asynchronously inform the rgss thread
 | 
					/* Used to asynchronously inform the rgss thread
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -394,6 +394,8 @@ struct GraphicsPrivate
 | 
				
			||||||
		fpsLimiter.delay();
 | 
							fpsLimiter.delay();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		++frameCount;
 | 
							++frameCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							threadData->ethread->notifyFrame();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void compositeToBuffer(FBO::ID fbo)
 | 
						void compositeToBuffer(FBO::ID fbo)
 | 
				
			||||||
| 
						 | 
					@ -716,5 +718,7 @@ void Graphics::repaintWait(volatile bool *exitCond)
 | 
				
			||||||
		p->blitBufferFlippedScaled();
 | 
							p->blitBufferFlippedScaled();
 | 
				
			||||||
		SDL_GL_SwapWindow(p->threadData->window);
 | 
							SDL_GL_SwapWindow(p->threadData->window);
 | 
				
			||||||
		p->fpsLimiter.delay();
 | 
							p->fpsLimiter.delay();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							p->threadData->ethread->notifyFrame();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue