Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Real-time FPS Counter Overlay

Newbie Spellweaver
Joined
Apr 22, 2009
Messages
62
Reaction score
54
This simple addon will display a real time FPS counter in the top right corner of the screen during gameplay

This is just a quick draft. I'll make it togglable from the options or with a chat command in the near future. Feel free to modify this as you like and maybe give me some credits if you learn anything from it.

Note: my fps are locked to 60 in this screenshot probabilly because I'm in window mode
CcFR4cS - Real-time FPS Counter Overlay - RaGEZONE Forums


Installing (detailed version for newbyes):
  1. Open your Gunz.sln in visual studio
  2. If you don't have a folder named Addons, Right click Gunz -> Add -> New filter and name it Addons
  3. Right click the Addons folder -> Add -> New filter and name it FPS Overlay
  4. Right click the FPS Overlay folder -> Add -> New item... -> Header File and name it FPSOverlay.h
  5. Paste this code in the file you just created and save it:
  6. Right click the FPS Overlay folder -> Add -> New item... -> C++ File and name it FPSOverlay.cpp
  7. Paste this code in the file you just created and save it:
  8. Open Game -> ZGame.cpp
  9. Find
    Code:
    #ifdef LOCALE_NHNUSA
    #include "ZNHN_USA_Report.h"
    #endif

    And add this below it:
    Code:
    #include "FPSOverlay.h" // [addon] real-time fps counter overlay
  10. Find
    Code:
    void ZGame::Draw()
    {

    and scroll down to the bottom of the function, which should look something like this
    Code:
    	__BP(505, "ZGame::Draw::RenderStencilLight");
    	if(Z_VIDEO_DYNAMICLIGHT)
    		ZGetStencilLight()->Render();
    	__EP(505);
    
    	__EP(37);
    
    	__BP(38,"ZGame::Draw::DrawGameMessage");
    
    	m_Match.OnDrawGameMessage();
    
    //	m_HelpScreen.DrawHelpScreen();
    
    	__EP(38);
    
    	__EP(20);
    
    	*more commented out code*
    
    }
  11. Add the following code before that final closed curly bracket
    Code:
    // [addon] real-time fps counter overlay
    ZAddons::Francesco::FPSOverlay::Get()->Draw();
  12. Right click Gunz -> Project only -> Rebuild Only Gunz and you're ready to go! Just copy Gunz.exe from your Gunz/Runtime folder to your client

Installing (short version):
  1. Add an "Addons" folder/filter to your Gunz solution (if you don't have one already)
  2. Add an "FPS Overlay" folder/filter inside the Addons folder/filter
  3. Add these two files under FPS Overlay:
    FPSOverlay.h:
    FPSOverlay.cpp:
  4. Include FPSOverlay.h in ZGame.cpp
  5. Add
    Code:
    ZAddons::Francesco::FPSOverlay::Get()->Draw();
    at the bottom of ZGame::Draw()
  6. Rebuild Gunz (or rebuild all if you want)

EDIT: fixed a mistake in the code (copypaste messed up LOL) recopypaste the .cpp file

EDIT2: Fixed a weird-butt bug that caused the counter to randomly not display. Please re-copypaste the .cpp file
 

Attachments

You must be registered for see attachments list
Praise the Sun!
Loyal Member
Joined
Dec 4, 2007
Messages
2,502
Reaction score
986
All you need is one simple function call, no point in creating a huge overhead.

PHP:
char szBuffer[64];
sprintf_s(szBuffer, sizeof(szBuffer), "FPS: %i", g_fFPS);
g_pDC->Text((g_pDC->GetClipRect().w - g_pDC->GetFont()->GetWidth(szBuffer) - 10), 15, szBuffer);
 
Newbie Spellweaver
Joined
Apr 22, 2009
Messages
62
Reaction score
54
All you need is one simple function call, no point in creating a huge overhead.

PHP:
char szBuffer[64];
sprintf_s(szBuffer, sizeof(szBuffer), "FPS: %i", g_fFPS);
g_pDC->Text((g_pDC->GetClipRect().w - g_pDC->GetFont()->GetWidth(szBuffer) - 10), 15, szBuffer);

That's ovbious, but this design has much less messy code.
Imagine adding hundreds of these modifications to your source and then forgetting all the changes in the various files and not being able to manage them later on or taking them out.
This way, modifications are easily pluggable into the GunZ source and manageable, and all of the code is in one file.
It's just good coding practice :p. You will see it will group all of the code once I also add the interface options.
And I can keep adding modifications related to this FPS counter to other files and still have all or most of the code in FPSOverlay.cpp.
 
Praise the Sun!
Loyal Member
Joined
Dec 4, 2007
Messages
2,502
Reaction score
986
That's ovbious, but this design has much less messy code.
Imagine adding hundreds of these modifications to your source and then forgetting all the changes in the various files and not being able to manage them later on or taking them out.
This way, modifications are easily pluggable into the GunZ source and manageable, and all of the code is in one file.
It's just good coding practice :p. You will see it will group all of the code once I also add the interface options.
And I can keep adding modifications related to this FPS counter to other files and still have all or most of the code in FPSOverlay.cpp.

I'm sorry, but how is that design worse than nesting 3 classes? I'm not saying you should just paste that code in an existing class, though there's nothing wrong with pasting it in ZGame.cpp. My point is that you're doing a lot of unnecessary string modifications as well as use an auto_ptr that is of no use.
 
Newbie Spellweaver
Joined
Apr 22, 2009
Messages
62
Reaction score
54
I'm sorry, but how is that design worse than nesting 3 classes? I'm not saying you should just paste that code in an existing class, though there's nothing wrong with pasting it in ZGame.cpp. My point is that you're doing a lot of unnecessary string modifications as well as use an auto_ptr that is of no use.

string modifications are simply the same, just done the c++ way.
that's not nesting 3 classes, it's just a singleton class inside namespaces.
It's a design meant to make extending that code easier later on.
It's not necessary, I just find it easier to manage the code this way.
The auto_ptr is the singleton of the class, it saves a delete of the class instance.

I know it might look overkill but I'm working with a big project and it saves a lot of time when I have to edit my code or add stuff to it.

I also use similar design when developing game engines from scratch (obviously not in the form of addons as seen here, but in the form of wrapping stuff in classes in a modular fashion) and it works great for me. It's just my taste I guess.

Coding is like art, and this is simply a different style.
 
Last edited:
Praise the Sun!
Loyal Member
Joined
Dec 4, 2007
Messages
2,502
Reaction score
986
string modifications are simply the same, just done the c++ way.

Yes, but they're unnecessary. All you need is a sprintf.

that's not nesting 3 classes, it's just a singleton class inside namespaces.

Which is overkill.

The auto_ptr is the singleton of the class, it saves a delete of the class instance.

auto_ptr automatically destroys a pointer when control leaves the scope. Dependant on the compiler, that's either never or every-time the ZGame object is destroyed.

I know it might look overkill but I'm working with a big project and it saves a lot of time when I have to edit my code or add stuff to it.

I also use similar design when developing game engines from scratch and it works great for me. It's just my taste I guess.

Coding is like art, and this is simply a different style.

Your style is different, but that's not really an issue, it's understandable when you're doing a lot of addons. What I don't get is why you use

PHP:
static const char *szText;
                static int x;
                static std::stringstream ss;
 
                ss.clear();
                ss.str(std::string());
                ss.precision(3);
                // not sure why, but the string seems to need to be longer than a certain amount to be drawn
                ss << std::fixed << "            FPS: " << g_fFPS;
                szText = ss.str().c_str();
 
                x = g_pDC->GetClipRect().w - g_pDC->GetFont()->GetWidth(szText) - 10;
                g_pDC->Text(x, 10, szText); // [todo] draw this the same way as the game draws its widgets

rather than

PHP:
char szBuffer[64];
sprintf_s(szBuffer, sizeof(szBuffer), "FPS: %i", g_fFPS);
g_pDC->Text((g_pDC->GetClipRect().w - g_pDC->GetFont()->GetWidth(szBuffer) - 10), 15, szBuffer);

The latter is way more optimized and much cleaner.
 
Newbie Spellweaver
Joined
Apr 22, 2009
Messages
62
Reaction score
54
Yes, but they're unnecessary. All you need is a sprintf.



Which is overkill.



auto_ptr automatically destroys a pointer when control leaves the scope. Dependant on the compiler, that's either never or every-time the ZGame object is destroyed.



Your style is different, but that's not really an issue, it's understandable when you're doing a lot of addons. What I don't get is why you use

PHP:
static const char *szText;
                static int x;
                static std::stringstream ss;
 
                ss.clear();
                ss.str(std::string());
                ss.precision(3);
                // not sure why, but the string seems to need to be longer than a certain amount to be drawn
                ss << std::fixed << "            FPS: " << g_fFPS;
                szText = ss.str().c_str();
 
                x = g_pDC->GetClipRect().w - g_pDC->GetFont()->GetWidth(szText) - 10;
                g_pDC->Text(x, 10, szText); // [todo] draw this the same way as the game draws its widgets

rather than

PHP:
char szBuffer[64];
sprintf_s(szBuffer, sizeof(szBuffer), "FPS: %i", g_fFPS);
g_pDC->Text((g_pDC->GetClipRect().w - g_pDC->GetFont()->GetWidth(szBuffer) - 10), 15, szBuffer);

The latter is way more optimized and much cleaner.

auto_ptr does exactly what I need. I want a singleton instance of the FPSOverlay class that is automatically allocated when I first access it and deleted when the game is closed without me deleting it manually or allocating it manually.


its not "more optimized", it's the c way of formatting strings. c++ is supposed to use stringstreams to format strings which are safer from buffer overflow. the performance is the same. I use stringstreams just because I fond the code more readable. It doesn't affect performance and it's safer.

oh, and the namespaces are there for future code order, for example if I have multiple people creating addons with that pattern I'll have of the addons authors under the ZAddons namespace and all of their addons under their name's namespace.

It's just coding style, it's not like it's less efficient.

My priorities when coding are:
1. pretty readable code that I'll be able to maintain easily
1.1 performance
2 following some of the language standards and best practices that I like
 
Last edited:
Praise the Sun!
Loyal Member
Joined
Dec 4, 2007
Messages
2,502
Reaction score
986
auto_ptr does exactly what I need. I want a singleton instance of the FPSOverlay class that is automatically allocated when I first access it and deleted when the game is closed without me deleting it manually or allocating it manually.

No it does not.



that ensures that the object to which it points gets destroyed automatically when control leaves a scope.

its not "more optimized", it's the c way of formatting strings. c++ is supposed to use stringstreams to format strings which are safer from buffer overflow. the performance is the same. I use stringstreams just because I fond the code more readable. It doesn't affect performance and it's safer.

The performance isn't close to being the same, you should run a benchmark. The C++ way of formatting strings is at least 10 times as slow as the C way. And my code is more optimized due to the limited amount of function calls.

Also, sprintf_s is secured from buffer overflows just as much as your C++ function calls.
 
Newbie Spellweaver
Joined
Apr 22, 2009
Messages
62
Reaction score
54
No it does not.





The performance isn't close to being the same, you should run a benchmark. The C++ way of formatting strings is at least 10 times as slow as the C way. And my code is more optimized due to the limited amount of function calls.

Also, sprintf_s is secured from buffer overflows just as much as your C++ function calls.

I'm aware of sprintf_s, I just don't like how the code looks :p

about auto_ptr
"the object to which it points gets destroyed automatically when control leaves a scope."

the scope of the static auto_ptr to instance is the class itself, and it will go out of scope only when GunZ closes, just like a global variable or any static member of a class. Which is the behaviour I'm looking for.

Never had any major performance issue with my designs, prettying up code reduces performance by 2-3% at most OVERALL (not talking about specific snippets) if done well. I just like coding this way. I care about performance, it's just not my main priority. In fact the 2D game engine I'm developing runs at thousands of frames per second.

Come on, why are you gonna argue about someone's coding style? :p It works and it doesn't kill performance.

TL;DR these are snippets from my GunZ ProMode that I'm developing and they're all going to follow this format because I cbb to strip them down, as they're still very simple to install if not simpler for big mods.
 
Praise the Sun!
Loyal Member
Joined
Dec 4, 2007
Messages
2,502
Reaction score
986
I'm aware of sprintf_s, I just don't like how the code looks :p

about auto_ptr
"the object to which it points gets destroyed automatically when control leaves a scope."

the scope of the static auto_ptr to instance is the class itself, and it will go out of scope only when GunZ closes, just like a global variable or any static member of a class. Which is the behaviour I'm looking for.

Never had any major performance issue with my designs, prettying up code reduces performance by 2-3% at most OVERALL (not talking about specific snippets) if done well. I just like coding this way. I care about performance, it's just not my main priority. In fact the 2D game engine I'm developing runs at thousands of frames per second.

Come on, why are you gonna argue about someone's coding style? :p It works and it doesn't kill performance.

TL;DR these are snippets from my GunZ ProMode that I'm developing and they're all going to follow this format because I cbb to strip them down, as they're still very simple to install if not simpler for big mods.

I'm not arguing about your code style, I'm pointing out that the string overhead is unnecessary and can block your thread up to 200 ms last time I benchmarked.

As for going out of scope, it's compiler dependant as I stated before. The scope might also refer to the caller function.
 
Newbie Spellweaver
Joined
Apr 22, 2009
Messages
62
Reaction score
54
I'm not arguing about your code style, I'm pointing out that the string overhead is unnecessary and can block your thread up to 200 ms last time I benchmarked.

As for going out of scope, it's compiler dependant as I stated before. The scope might also refer to the caller function.

Oh I see.
I've been using auto_ptr that way for a long time on multiple versions of gcc and visual studio and it was always doing what I expected - if anything changes in the future, I'll just switch to other singleton methods.

Same goes for performance, if I encountered such performance issues I would obviously switch back to sprintf_s, but so far it has not affected the game's performance.

Its fun to compare coding habits with other people though :D

ps: afaik all auto_ptr does is deallocate the pointer on its destructor, which makes it trigger when the instance of auto_ptr goes out of scope, so as long as gcc and MSVC don't decide to change this, it will keep working.
 
Junior Spellweaver
Joined
Sep 27, 2016
Messages
151
Reaction score
10
My ZGame.cpp has problem. Please help me !!! :(
Franc[e]sco

Franc[e]sco - Real-time FPS Counter Overlay - RaGEZONE Forums
 
Back
Top