ResidualVM: Week 1

Well, I guess the first week is the week that you learn the most.
For the first week, I decided to tackle the main menu of The Longest Journey, for the reason that the main menu can largely improve the experience of playing the game and many components of the main menu can actually be linked to the future diary menu within the game. Due to its complexity, I never intended to implement the whole main menu out within a week. I planned to build a basic structure of it, got something on the screen and then I can move on to other parts based on the built foundation. So far, the outcome is, surprisingly, better than I have expected.
That does not mean I didn’t encounter difficulties. Right at the beginning, I found myself messed up in the different versions of The Longest Journey game data provided on the market. I got my game from Steam, and it turned out that I need to install two extra libraries to let ResidualVM fully support its different sound format. Have to say, using Windows is really not the best choice for installing loads of libraries. I used to have few feelings towards Linux system but now I understand why the opensource community loves it.
So, the game could run on ResidualVM now, and the first step was to get all the resources related to the main menu loaded and rendered on the screen. Thankfully the code base has provided a class called StaticLocationScreen that handles related works. A new class called MainMenuScreen derived from StaticLocationScreen was then created. The next thing I need to get to make the resources, or to be more specific, the widgets of the menu rendered on the screen, is to get their name from the loaded data. By using the debug mode, I was able to dump the list of resources of the location referring to the main menu here, where names of items (widgets here) were shown.

The Debug mode of ResidualVM

Part of the dumped list
Once I got the list of names that I needed, I could load them as widgets accordingly, as what a StaticLocationScreen would have expected. Furthermore, each widget may have two handlers for clicking and mouse moving.

Load the widgets
That is the overall design of a menu, but things not always go easy with you. In the main menu, each button widget is related to a separate text that will show when you put your mouse on it. Well, the problem was that the clicking area of the button is determined by an empty text with an extra large rectangle size. However, ResidualVM would recalculate the size based on the content of the text, causing the clicking area to be extremely small. So the way of calculating the size needs to be changed.

See the help text on the right-hand side?

The special code for the blank text area
After tackling this problem, other things become clear. Just write different handlers for different widgets. The NewGame button needs to open a new game (based on the version, demo or not), and the Credits button will play the credits video. Oh yes, talking about videos, the game also needs to play the video of FunCom game company before the main menu, which was done through cooperating with the class UserInterface.

How things are loaded in the beginning

Up to now, everything seemed to be fine, until something unexpected showed up. In the original game, when the user clicks the button, the clicking sound is ensured to be played completely. The game behaves to be frozen until the sound is finished and carries on doing what it should do. Right now It seemed that changing the screen in UserInterface will cause the playing sound to stop.

I originally tackle this with an empty while loop, busy-waiting for the sound to stop. But obviously, busy-waiting is not a good thing to show up in a game design. Therefore, I started the biggest commit of this week, covering 9 files with more than 100 lines of code modified, to queue the request of changing the screen. As you can imagine that was really a mess, and it just doesn’t feel right to change so many things just for a simple and short clicking sound. In the end, after discussing with the mentor, we decided to just add a delay in the while loop to free the CPU for a while. That seems to be the most appropriate solution for now, apart from the fact that my biggest commit got discarded.

Bothersome clicking sound

Well, that basically covers up the most essential part of this week. Now the main menu has some basic functionalities to support the game. Although there are difficulties encountered, overall speaking, seeing that the main menu is coming to a shape has given me much joy. I’ll keep on working and I am looking forward to next week’s tasks.

For the detailed development of the codes, please refers to the pull request on GitHub.
All code images are generated through Carbon.