Gateware Development


Gateware

Responsibilities

MacOS

When I first joined the Gateware team, I would have to learn more about the existing software, before I could start adding new functionality to the codebase. And what better way to do so than to fix existing bugs? The first bug I started on was that Gateware couldn’t be run on newer versions of MacOS. Because it had been a while since the MacOS implementation of Gateware had been updated, the way we had Vulkan interfacing with Apple’s Metal graphics had become outdated. So, after re-working our implementation of Vulkan, we were able to fully bring the MacOS implementation back up to date and pass all the unit tests.

GInput WinProc Bug

Since Gateware is used in a couple of Full Sail Game Dev courses, it ends up being the main testing ground for Gateware and where many bugs are found. During my time on the Gateware team, one of those courses had its assignments reworked which led to the discovery of a bug that caused the application to crash if more than one instance of the GInput library class was created. After some testing and research, it was found that essentially when multiple GInput instances were created, they would each have their own Windows Procedure (WinProc) and recursively call each other’s WinProc instead of routing back to the original one. So instead, I had to create a static map to hold a reference to the original WinProc for each window and their connections to different GInput libraries.

A more in-depth description of the problem and solution can be found here at this link: https://fsgateware.blogspot.com/2023/05/month-2-week-3-of-gateware-win32.html It also contains blog posts detailing other subjects that I will briefly talk about here as well as the work that other Gateware devs have done both before and after me.

UWP Library Implementations

Most of Gateware’s Libraries had already been ported to support UWP by a previous student named Chase Richards. So, the main goal of my time on the Gateware team during my capstone at Full Sail was to complete the implementation of the required libraries and ensure everything could be successfully compiled into one header file and pass all unit tests.

The two major remaining libraries were GInput and GRasterSurface. When I began working on the GInput library, I expected it to be fairly similar to the Win32 implementation. That assumption ended up being very wrong and cost me a couple of days. Since UWP’s input system is multi-threaded and is largely based on events, I was able to copy and modify a lot of the code written for the GWindow library for the general structure of the GInput library. I was then able to bind the functions to UWP’s input events and connect them to the external interface functions to ensure shared functionality across all platforms.

The GRasterSurface library ended up being a much larger task. The purpose of this library is to draw 2D images directly on the screen and give the user some extra options and configurations on how it will behave. Most other implementations of this library do so by creating an array of pixels from the given image and simply just drawing them directly on the screen using the CPU. UWP, however, does not like to directly draw to the screen as other platforms do for security reasons. So instead, I had to create an instance of our GDirectX library inside of GRasterSurface and have it create a rectangle that fills the entire window. We are then able to treat that rectangle as the screen and draw directly to it using DirectX. Not only were we able to recreate all the necessary functionality to match the other platforms, but this method is also able to use hardware acceleration in drawing to the screen by using the GPU instead of the CPU.

Compilation and Unit Testing

Since the main point of Gateware is to help developers create cross-platform applications, we want to make sure they can also develop cross-platform. Therefore, the Gateware team uses CMake as a way to generate project files and link external libraries (such as Vulkan) to make transferring projects from OS to OS much simpler. A big part of this project is also creating reference points for external files such as images and sound clips that the project can be used to access those files. The problem with UWP is that UWP applications are unable to access files outside of their local folder. Therefore, instead of simply creating reference points, we must have CMake copy all of the external files into a local folder location where the UWP application is able to access them.

A large part of Gateware development is unit testing. So, for the UWP implementation to be officially released and become fully integrated with the main version of Gateware, it needs to pass all the Unit Tests. For the testing, we use YAML to build the different versions of Gateware and run them to check if they pass all the tests. UWP posed two main problems with our existing approach to unit testing.

The first is that UWP applications do not exist as .exe files, instead, they more or less arbitrarily exist on your device with a folder location that is mostly only used for storing various types of save files. This meant that we would have to find a way to not only install the application on the device but also run the application. Eventually, we were able to find a way to deploy the application from the project file (which both builds and installs the project) and also find the application ID which we can use to run the application.

The second problem is that the unit tests write to the console so that we can watch the progress of the unit tests and know which ones have passed and which ones have failed. However, UWP applications are unable to access the console. Therefore, we are unable to use the console to check the status of the tests or even to see if or when the tests finished or not. So instead, I made it so that the YAML looks for a file in a certain location after the application has started. That file will then only be created once the unit tests all pass. If the YAML times out in finding the file, then that means that the unit tests failed. Unfortunately, it is not able to provide much information at the time being, but we hope to be able to add more functionality to this part of the UWP unit testing so that we can have more information on why the unit tests failed.

Conclusion

Overall, I think my time on the Gateware team was extremely beneficial in giving me experience with working with large codebases; creating, updating, and maintaining unit tests; and learning and updating older code. All that I went over here are just the highlights of what I worked on with Gateware and more detailed descriptions of what I talked about and other things that I didn’t cover can be found at the link mentioned earlier. All of the blog posts I made about my work can be found in the months of April to June of 2023. https://fsgateware.blogspot.com/