DevBlog 02: Improving on the old framework's GUI

Chod

9650 views

The old version of the framework was first developed in 2016, and at the time seemed like the best project I had written so far in terms of flexibility, reusability and certainly from a design point-of-view. However, over the years it got chopped and changed so much that it became a bombsite of code; it worked, but was not pleasant to work with.

 

One thing in particular that became apparent over time, was that developing cheats with the old framework was quite time consuming. This was because when creating the layout for a menu, all the element creation had to be done manually line-by-line by the cheat developer. In some cases, this could take up hundreds and hundres of lines of code, adding both bloat and creating a messy project. So someting I wanted to address in the new framework (its called V5 btw) is the time it takes to create a GUI...

 

Enter the GUI Studio... This new tool allows a developer to create a menu in real-time using an graphical user interface, save it to a GUI Document, then load it into the program in one line of code. Here's a short video demonstrating the studio: 

 

There are a lot of elements missing currently, but you can see the basic creation of a window, two text boxes and a button. The studio allows for the easy parenting of an element to any other element, and correctly handles relative positions. It also features drag snapping for easily aligning objects along a axis. Once the GUI document is exported, it gets converted into an XML document that looks like this:

 

<?xml version="1.0" encoding="utf-8"?>
<document>
  <meta
    version="100" />
  <element
    name="Window_0">
    <type>V5Interop.Window</type>
    <enabled>true</enabled>
    <hidden>false</hidden>
    <position_x>187</position_x>
    <position_y>158</position_y>
    <size_x>400</size_x>
    <size_y>210</size_y>
    <parent />
    <backgroundcolour>34,35,43,255</backgroundcolour>
    <label>Please Login</label>
  </element>
  <element
    name="tbUsername">
    <type>V5Interop.TextBox</type>
    <enabled>true</enabled>
    <hidden>false</hidden>
    <position_x>46</position_x>
    <position_y>25</position_y>
    <size_x>300</size_x>
    <size_y>20</size_y>
    <parent>Window_0</parent>
    <label>Username</label>
  </element>
  <element
    name="tbPassword">
    <type>V5Interop.TextBox</type>
    <enabled>true</enabled>
    <hidden>false</hidden>
    <position_x>46</position_x>
    <position_y>64</position_y>
    <size_x>300</size_x>
    <size_y>20</size_y>
    <parent>Window_0</parent>
    <label>Password</label>
  </element>
  <element
    name="Button_0">
    <type>V5Interop.Button</type>
    <enabled>true</enabled>
    <hidden>false</hidden>
    <position_x>267</position_x>
    <position_y>144</position_y>
    <size_x>100</size_x>
    <size_y>20</size_y>
    <parent>Window_0</parent>
    <fontsize>12</fontsize>
    <label>Login</label>
  </element>
</document>

The beauty of this system is that if a developer wants to change how the menu system works for their cheat, they can adjust it with the studio, save to XML, then upload to the server. No changes are required to the code for the GUI to be changed.

 

Some of you may be thinking "This looks a lot like OSH GUI". Well, you're not entirely wrong. I was so impressed with the designer from OSH GUI that I wanted to replicate its ease of use and the properties panel. Gladly though, that's the extend of the similarities. While OSH uses a secondary managed renderer for displaying the elements, what we did was to pipe our D3D11 renderer through to the managed canvas, thereby only needing one renderer.

 

One of the hurdles we had to overcome was the pathway of managed -> unmanaged code. One option would be to pInvoke everything we needed, but this would have been a huge task as the V5 Framework is quite extensive. Instead, we created an CLR interop library that acts as a middle man. For example, let's look at the code that creates a text box. Firstly in our managed front end we issue the CreateUITextBox call to the interop library:

 

ManagedCall1.png.7ace8df9b940ec8db5321b905010df63.png

 

And the interop part:

Interop1.png

 

In the interop library, we perform the necessary conversion from the label to wchar_t*, then we issue the CreateElement call to the native back-end. CreateElement returns a pointer to a V5::TextBox, given a parent element, a initial position, and a label. Using this pointer, we create a managed TextBox object, and give it a reference to the native pointer. The managed TextBox simply acts as a wrapper around the native pointer so we can still use OOP on the text box from managed code. After this, we add the managed text box to the _items List and return it. The native back end of course keeps its own list of created elements, but that's not important.

That's pretty much it, all the coder has to do on their end is one line of code:

V5::gGuiManager.LoadDocument(L"Gui\\Login.xml", this);

Where this can either be an existing gui Element to parent all the objects to, or null.

 

I hope you enjoyed this one, next time the wait shouldn't be as long. If there's something in particular you'd like me to cover, please reply and let me know.



14 Comments


Recommended Comments

I’m more experienced with the front end, which is much simpler, but this made me think of how much more efficient it is to load CSS externally to remove it from the content layer to simplify page structure, minimize load times, and make styling updates without modifying the page itself. 


Cool to see a framework like this that will allow for faster updates and enhancements while running leaner 👍

Share this comment


Link to comment

I have been on the sidelines and haven’t said much.. that being said I still have been keeping on the updates and wanted to say thanks for everything you and your guys are doing. Really excited to use the finished product and hope for all the success and business for you guys! Cheers!

Share this comment


Link to comment

Great work as always Chod! The way this is worded in parts almost sounds like you're creating this with a larger goal in mind, not simply reforming the GUI for you tools internally but almost as if you'll be offering this GUI Studio as a service for other developers to use for their cheeses. If this is the case then I'm excited as I've been picking up C++ lately and would definitely love to play with this tool.

Keep up the great work!

  • Like 1

Share this comment


Link to comment

Nice blog for sure. I'm really enjoying reading all this.

I'm not sure that i remember this correctly, but weren't you the main developer for EA back in the days? I would love to hear about how the work was back then, versus now.

Edited by Flzduden

Share this comment


Link to comment
14 hours ago, Flzduden said:

Nice blog for sure. I'm really enjoying reading all this.

I'm not sure that i remember this correctly, but weren't you the main developer for EA back in the days? I would love to hear about how the work was back then, versus now.

Thanks for the comment. I might write a blog about that at some point.

  • Like 2

Share this comment


Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.