GSoC 2022 Summary

Hi! I am Avijeet Maurya, one of the GSoC 2022 contributors working on ScummVM. The main focus of my GSoC project was on improving the condition of several existing game engines through bug fixes and implementing some other improvements.

What was done

GLK Scott

Implemented support for C64 and TI99/4A games by porting the GLK Scott interpreter from spatterlight.

Blog Posts:

Week 1 – Getting started.

Week 2 – Some progress and cleanup

Week 3 – Community Bonding period ends

Week 4 – Start of the coding period

Week 5 – Finishing up Scott

Pull requests: #1, #2, #3, #4

PINK

Various bug fixes related to the in-game PDA and updating the code to work with the newer MacGUI implementation. Also fixed bugs related to Hebrew support.

Blog Posts:

Week 6 – Working on PINK

Week 7 – Finishing up PINK

Week 11 – Finishing WAGE and PINK

Pull requests: #1, #2, #3, #4, #5, #6, #7, #8

WAGE

Various bug fixes and MacGUI related improvements.

Blog Posts:

Week 8 – Working on WAGE

Week 9 – Working on WAGE II

Week 10 – Working on WAGE III

Week 11 – Finishing WAGE and PINK

Pull Requests: #1

MacVenture

Various bug fixes related to GUI.

Blog Posts:

Week 12 – Working on MacVenture

Week 13 – Working on MacVenture II

Week 14 – Working on MacVenture III

Week 15 – Wrapping up

Pull requests: #1

Avalanche

Fixed two gameplay bugs.

Blog Posts:

Week 15 Part II – Working on Avalanche

Pull requests: #1

What is Left

The leftover work is distributed between MacVenture and Avalanche. For MacVenture I still need to:

  • Implement lasso selection
  • Add IIGS support

For Avalanche I need to work on the TODOs listed on the wiki page.

Closing Thoughts

GSoC wasn’t something I could have completed on my own so I would like to start by thanking the ScummVM team for being so helpful at all stages of the program. Special thanks to sev, eientei, Jaderlund and Voltya for helping out with different parts of the project.

Getting started with contributing to other open source projects was always a daunting prospect because of how difficult it was to actually understand the huge codebase of various projects but this time I managed to overcome that through a combination of just going at the problem at hand and also asking for help when needed.

A really important thing I discovered through GSoC was to have a positive mindset while coding. I never really felt nervous, even when I was stuck on something because I knew I had people to rely on and ask questions to. This helped me progress through in a much more relaxed manner which is something I don’t think I could have done before.

And speaking of asking questions, it was something I always hesitated to do because I felt like it was a stupid thing to do but now I know that it’s better to admit that you don’t understand something rather than pretend that you do and cause problems later.

Another thing I have learned through GSoC is getting into the habit of working daily. I used to be very irregular in when I work and I am happy to have changed that.

I also liked writing the weekly blogs and from now on I’ll try to write about what I work on, even if it’s just some personal notes. You need to really understand what you are working on to write about it and I often had some new insights about the problems I was facing when I tried to describe them in my blog.

And in the end I want to thank all the people who followed me through this journey and read the blog posts. I really enjoyed writing them and it’s great knowing that there were people who interested in reading what I had to say!

Thanks for reading!

Week 15 Part II – Working on Avalanche

A small addition to Week 15’s entry is some work I did on Avalanche. There’s wasn’t much time left when I got to Avalanche so after looking at the pending issues, I decided to tackle some gameplay bugs as those are generally simpler than implementing entirely new features.

The first one was about the in-game movement direction indicator.

Direction indicator in bottom left.

The game has two different movement methods, arrow keys and clicking. The bugged behavior would update the direction indicator only when arrow keys were used. To fix this was quite simple, I just found the function used to handle keyboard input and checked how the direction indicator was being updated for the corresponding arrow key input. I then went to the part of the code which handles mouse input and used those same function and now it works perfectly.

The second bug was something I found while playing through the game. Spoilers for the game upcoming incase that’s something you are worried about.

There’s a segment where you have to climb up a dais but it’s rigged to shoot a arrow as soon as you do that. The solution to progress is to quickly climb down to avoid the arrow. However, the bugged behavior would insta-kill you as soon as you entered the command to climb up.

We are killed before the arrow reaches us.

To fix this I looked for the code which handles the arrow firing event. Luckily the error in that code was quite obvious.

The same sprite data is used for both the character and the arrow

The sprite data is what holds the coordinates of the sprite. Since the same sprite data was being used, they would immediately pass the collision check. I replaced this to use the correct sprite data for the main character.

We now die when the arrow reaches us

This was the last fix I could make for Avalanche in the time I had and also the last of my contribution for this GSoC. This was a great journey and working on ScummVM was a good experience for me. I’ll be posting a GSoC summary post after this (and you might have already seen a password protected version thanks to a mess up) so look forward to that. Thanks for sticking to the end with me!

Week 15 – Wrapping up

The final week of GSoC and it ended up being rougher than I hoped for last week.

I started working on implementing lasso selection and in theory it was really simple. All I had to do was:

  • Detect if a click inside the inventory window is on a object or not.
  • If it’s not on an object then we can start the lasso and start polling for mouse move events.
  • On a mouseup event, we select all the objects inside the current lasso area.
  • Then we should be able to click and drag any of those objects to move all of them

I managed to get the item selection working and it should have been enough to get the lasso working but unfortunately it wasn’t that simple. During the process of porting the WebVenture code, the behavior of many functions was changed and the overall flow and structure of the engine has been altered significantly. The changes were small enough that you could technically still clear the games but they add together to make it harder to finish adding all the functionality from WebVenture.

An example of such change is the ability to move objects when they are selected. Here’s two GIFs showing the behavior on a Mac and WebVenture:

WebVenture
Mac

And here’s what happens with ScummVM:

By itself, it’s just a minor annoyance while playing and can be worked around. However, it’s a required functionality for lasso selection to work. Here’s how lasso selection looks on the Mac:

I couldn’t really figure out how to make lasso work without some major rewrites to parts of the code so I decided to leave this for later. The current TODO list for MacVenture looks like:

  • Fix some minor behavior discrepancies
  • Add IIGS support
  • Add Lasso selection
  • Implement some stubbed functions

There’s not much time left in the final coding period so I have opened a PR with my currently finished work on MacVenture. I’ll also try to finish some of the TODO tasks for Avalanche which were listed on it’s wiki entry here.

The coding period might be coming to a close but I am planning on continuing my work after GSoC during the coming weekends. I’d also like to write a blog post looking back at all the work done during these 15 weeks so look forward to that. Thanks for reading and see you next week!

Week 14 – Working on MacVenture III

Continuing from last week, I worked a bit more on IIGS support but I eventually realized that it might be too much work to take on in this GSoC period. I was initially planning on just writing the code for loading all the game data into the existing data structures and hoped that it would be enough to get things working but it wasn’t that simple. So I decided to leave it for the time being and work on it on my own pace after GSoC is over.

So after this I decided to just take care of all the pending tasks and issues from the original 2016 GSoC work and work has been going smoothly.

This is a small blog post but the first week of college was pretty hectic and I tried to do my best in the time I had. Hoping to do to better this week as GSoC comes to an end.

That’s it for this week. Thanks for reading and see you again next time!

Week 13 – Working on MacVenture II

Another week spent on MacVenture though this one was a bit uneventful. I learned a bit more about the .2mg format and saw what WebVenture was doing with it and it didn’t seem too complicated so that’s what I am adding to ScummVM right now.

About WebVenture, I actually managed to get it working. What worked was to place the game in it’s root directory and to run the website on a http-server. This should give me another frame of reference when comparing game behavior.

WebVenture Working in WebBrowser

I am not too well versed with node/javascript development but it’s good enough for me to go through and understand what’s happening. And speaking of understand, let’s have a look at the javascript file which is being executed as the game runs.

?

It wasn’t exactly what you can describe as understandable with all the obfuscation and lack of formatting. Luckily this wasn’t really that big of a problem and all I had to do was to run the Closure Compiler on the repo with all optimizations disabled and generate a file with everything intact except for the formatting (which got fixed with an online beautifier).

Anyways, having a working WebVenture made it easier to step through the game as it runs and see which piece of code is called when. Visual Studio Code wasn’t doing to well with JS code and things like Jump to Definition were often going to the wrong function so this was a really useful thing.

After that I worked for a bit on implementing the required functions to get the data from the .2mg files but that had to be put on hold for a while. Colleges were finally open and I had to leave the city to get to the hostel. I had to make some preparations both before leaving and after arriving and that made it hard to get the time to work so I took the weekend off.

The blog post got delayed by a day too but I have adjusted my hostel and will be working regularly from here ?I hope to work a bit harder this week to make up for the lost time.

That’s it for this blog post. Thanks for reading you next week!

Week 12 – Working on MacVenture

3 months have passed since GSoC started! This week I started working on MacVenture which was also worked on by another GSoC student blorente in 2016. You can see his blog here. My work continues were he left off, fixing the engine to work with the newer MacGui while also implementing some new things.

The first thing I worked on was the borders.

The borders had a bunch of problems. The title wasn’t aligned properly in either direction and it was just broken when you had a window active. If you read my past blogs then you might remember how nine-patch gave me some troubles when I was working with WAGE. This time wasn’t any different either.

It took me a decent amount of time to wrap my head around how they work but eventually I figured things out and realized that the problem is in the division of the border into different areas.

The images below aren’t accurate as far as the scale of the area is concerned but it’s good enough to show the problem and how to solve it.

 

This was the older way the border was divided into 3 areas. The 2nd rect is stretched to fill the required width while the others are fixed in length. Also the title can only be printed at the start of an rect. This is why the title wouldn’t get centered.

To fix this we can instead divide the border into 5 rects. This time the 2nd and 4th rect are stretched to fill the remaining area while the 3rd one is of the size of the title. This way we can center the 3rd rect and the title with it.

The other problem was that active windows also shared the same set of offsets as the inactive ones. This wasn’t a problem when we were just printing the title in the beginning but with it being centered, I now had to make sure that the same offsets also worked with the active window borders. This required some tedious redrawing and testing but eventually I got it to work too.

After this I starting working on the leftover tasks from the previous work. There’s also the task of adding support for the Apple IIgs version of the games and that’s what I am working on right now.

That’s it for this week. Thanks for reading and see you next week.

Week 11 – Finishing WAGE and PINK

After last week’s blog post I opened the PR for both WAGE and PINK to get them reviewed. Let’s start with PINK:

For PINK there was a regression caused by a later commit which broke some things. The problem was that the window mode wasn’t being set and the fix was really easy. A bigger problem was the Hebrew text wasn’t being rendered properly. It has been there from the start but I never noticed it because I can’t read it.

The text is reversed and the borders are broken

Thanks to discord user rzil for the help with the hebrew text. It was kinda hard dealing with text you can’t read and it being an RTL language just made things more annoying. What I ended up having to do was to render the text in reverse order and that was enough to fix it.

Fixed!

With this PINK was done and it got merged.

WAGE spent quite some time in review. The first major issue was Engine code being called from inside Graphics. Another issue was with how I had solved some game specific issues. I had implemented some game specific hacks but a general solution was desirable.

Most of the issues were caused because of how object click detection was implemented. In the current system, each object had it’s own screen to draw on. To detect clicks, ScummVM would just see if something was drawn at that pixel. This was however too precise because the original game seemed to count any click inside the bounding box of the object. I rewrote the object detection code to work like that and it fixed all issues.

There was also a problem with how the bounds of the objects were calculated. Fixing that fixed the issues with cropped bitmaps.

Some formatting issues needed to be fixed too but after that WAGE finally got merged. However there are still some things which need to be addressed. Some functions were stubbed (not implemented) so I worked on those. There’s are some some TODOs from the original JAVA implementation which need to be looked at.

And that’s where I am right now.

Thanks for reading and see you next week!

Week 10 – Working on WAGE III

Work on WAGE continues this week too. I started by writing some test games which rendered multiple different shapes in different styles so I could get ScummVM to match the original as close as possible.

A common problem with all shapes was how thick borders were handled. The border was supposed to to increase in width equally on both sides of the shape’s edge but it didn’t which made the shapes larger than they should have been. This was easy to fix and I did it for all the shapes.

Now to discuss the individual shapes. Rects had the same problem as before with being a pixel longer on the right and bottom so that had to fixed.

For Polygons the way the line was being drawn didn’t match the original perfectly. ScummVM uses the Bresenham’s line drawing algorithm for drawing lines but mini vMac either uses something else or is changing the end points of the line… There’s a difference of a pixel here and there in the lines which is minor but visible, specially at certain slopes.

For ovals there was another problem with the borders. The thickness had to be uniform throughout the perimeter so I had to change that. And again a similar problem as with the polygons where some lines didn’t quite match.

Now to deal with the individual game bugs. Most of the are resolved and right now I only have 2 more left to deal with. I hope those don’t take much time as I have already spent quite a bit of time on WAGE and would like to move to the next engine.

That’s it for this week and thanks for reading!

Week 9 – Working on WAGE II

Another week spent on working on WAGE and I am getting closer to finishing up.

Continuing the issue with the font from last week, we decided to just hardcode the correct font as the game might have been using a different version of the engine with different behavior.

After that I worked on implementing the about screen. Different games do different font types, sizes, alignment, etc. so I just went with a general center aligned screen. It took some time to get the alignment working properly but I managed to do that.

There were a bunch of game specific bugs left to deal with, 24 to be exact so I started working on them one by one. There wasn’t much in terms of how I solved them and the process was to just set some breakpoints in places related to the bug and see what’s going wrong.

To fix them I had to implement some game specific fixes but I think it’s the only way as they all might have used a slightly different version of the engine.

The only notable task from these fixes was to add more resolution options to WAGE. Originally it was hardcoded to run at 512×342 but now it also supports 800×600 and 1024×768. This was necessary to support some games which needed larger windows.

Currently there are 13 tasks left and most of them fall under the category of “Ignored bytes while rendering” and “Unhandled comparisons while executing the script”. I don’t have a good idea of why these are caused but so far I haven’t found any difference in the behavior in the Original vs ScummVM so they might be harmless after all. I’ll look more into them and that should be the last I have to do.

Thanks for reading and see you next week!

Week 8 – Working on WAGE

I started working on WAGE this week and it has been the most challenging engine so far. Some tasks took a long time to finish but I am happy to say that I managed to fix them 🙂 There’s still some work to do but I am expecting to finish that this week.

In this blog post I’ll just talk about a really long chain of issues. So one of the game wasn’t looking like it was supposed to.

Spot the differences!

The immediately obvious problem is that things are moving, more specifically the windows and the right side corners. Looking at just the bottom right corner would make you think that it’s also moving diagonally with the windows but that’s not the case actually! It just appears to be moving diagonally because of the pattern it has. The top right corner makes it more clear that they are actually moving sideways.

So the first thing to fix was the corners and after going through the code responsible for it I realized that it’s a problem with the code drawing the corners. The rounded corners are drawn by drawing horizontal lines of varying widths and the problem was that the right side was being drawn a pixel longer. This was because the code didn’t consider that we don’t use the right and bottom edges of a Rect.

However I couldn’t just change this code to fix things because other engines were already using it and had accounted for it’s weird behavior in their own code. After confirming that they were indeed working fine with the broken version of the code (which took a long time), sev came with the idea to create alternate versions of the functions with the correct behavior and use them where needed.

After that I just hardcoded coordinates for the window to see if that’s the only thing wrong with it’s position and that’s when I found another small issue.

There’s one pixel of empty space around the image

It’s a bit hard to see but the image inside the window is surrounded by some empty space. This one wasn’t that hard to fix and was caused because the dimensions were being calculated before the title for the window was set.

Next was actually fixing the window coordinates. This took some time going through all the relevant code but eventually I did found out the problem. If you look at the window border you can see the squares at the corner which extend past the window edge by 2 pixels. The coordinates in the game data didn’t consider them but ScummVM would position the window from their vertex. To fix this the code just added 4 pixels to both dimensions. However it just added them to the bottom and right edge. To correctly fix it I had to subtract 2 pixels from the top and left edge and add 2 on the other ones.

However this brought another problem to light.

ScummVM vs Original Diff

Even with the window at the correct position, the title itself wasn’t at the correct position. This one took a lot of time to fix. The biggest problem was in actually understanding how the borders were drawn. I could see that it in a file called nine_patch.cpp but I neither knew what the name meant or what the code was doing. The text was rendered after the border so I decided to see if I could fix it’s alignment first.

The problem with this was simple, there’s supposed to be 5 pixels of padding between the rect and the left and right sides on the text. However the font itself had a pixel of whitespace around the individual characters. The padding only had to be 4 pixels on each side to look correct. I changed it and that made the text aligned.

However the Rect itself was in the wrong position and that meant going back to nine_patch.cpp to fix it.

Initially I was just thinking that it(nine patch) was just weird name choice and not a specific thing which exists. But after a long time of just looking at the code and understanding nothing, I decided to just google it because nothing else was coming to my mind. And it turns out that it is a way of storing borders to draw them at any resolution. All the resources online seemed to Android specific but the basic concept was still the same and with that knowledge and some stepping through I managed to get a good idea of how it was working.

I won’t explain how nine patch works here because there are already some online resources which will do a better job so let’s just focus on the problem. The Rect is supposed to be centered on the border but because of the Rect had an odd length (67 pixels wide) and the border even (306 pixels wide), one side would have one more pixel than the other, 119 and 120 to be specific.

Which side gets which length would depend on the implementation of the nine patch but for ScummVM it was the exact opposite of the Original behavior. To fix it I just had to change how it was rounding the length after dividing it into two. Rounding to the nearest integer makes it match the Original.

With that fixed I can get to the last issue and that is the font in the second window being different. I haven’t made a lot of progress with this but based on what I have seen so far, the font type is correct but the size is wrong. There are also two more other issues pending for now.

With only one week left in the coding period, I’ll be trying to finish everything in time so look forward to the next blog to see if I could do it ?.

Thanks for reading and see you next week!