Concluding Post

This blog post is the culmination of my GSoC 2022 journey.
This summer, I worked on the ScummVM Director engine, where I completed the STUB code in the engine and worked on fixing various issues in it and bringing it more in line with the original working, thus improving the compatibility of games (D4 and older).

This is a list of the Pull Requests I created during the summer in ScummVM. They completely describe each issue they are supposed to fix/implement. My initial work was with the STUBs. Here is a list of STUBs that were resolved.

Next, I worked on the various issues encountered in certain targets of Director Engine which get updated on this Trello board. This board also contains the open issues of the Director engine.

I also created a couple of test movies to gain a better understanding of the internals of the original Macromedia Director. They can be found here.

It was a great experience working with the ScummVM Director devteam (sev, djsrv, rvanlaar, mstea, moralrecordings and all the other devs). I consider myself privileged to have contributed to such a popular and well-maintained open source project. I learnt a lot of things this summer from this awesome experience.

Since director is an ongoing project and the plan is to support games till D7, I will be sticking around and contributing to the Director engine (and ScummVM) after GSoC. I would love to continue being a part of the community and volunteer in the project.

A huge thanks to my mentors sev and djsrv (and the devteam) to help me out throughout the duration of this programme and answering even my dumbest queries with patience πŸ˜€

This is the concluding post of my GSoC journey. I loved the project and the people and would continue to be a part of it. Thank you everyone πŸ˜€

WEEK 12: PopUpMenus can be drawn!

This week, I mostly worked on the PopUpMenuXObj. sev had outlined to me the steps that would be needed to get it working.

The first step was to make the MacPopUp menu constructor. Now MacPopUp is very similar to MacMenu (essentially, it is a menu with a single submenu. It can have BITD images as menuItems, and can be drawn anywhere on the screen instead of just the top)

So MacPopUp is derived from MacMenu. We have MacWindowManager::addMenu(), which removes the current menu if one exists. creates a new one, sets it as the menu of the movie and adds that to the _windows array. To change this for MacPopUp, we need to remove the part where it is set as the menu of the movie, and we assign the index of the menu in the _windows array ourselves. (This is something done in the original director engine too to prevent collision of popupmenu IDs with the IDs of other windows). So the MacWindowManager::addPopUpMenu() has been made to do this (creates a MacPopUp instead of a MacMenu in our case)

Then a null item is added to the menu, and the submenu is created by the provided string. These functions take care of creation of MacPopUp, and the menu object is created using this.

Now, for drawing, I had to change some functions of MacMenu. Most of the changes were in MacMenu::mouseClick(), MacMenu::draw() and MacMenu::calcDimensions.

The changes were mainly the passing of drawing coordinates as a parameter in calcDimensions, adding a forceDraw flag in mouseClick to allow drawing anywhere on the screen, and removal of drawing of top bar in draw().

The end result is this:
Now, the changes to these functions were done directly in MacMenu. Adding a macpopupmenu.cpp to the project is resulting in LNK2019 error. I had tried resolving it before writing the constructor, but then went ahead with just the header. I will try to fix it again now and override them in the MacPopUp class.

I will finish this and then pick up the issue I have not touched since long – the window options. Some of the work on that is already done. I will have to finish up the remaining.

This is the 12th weekly update of my GSoC program. I will be submitting my work before 12 September. My experience with ScummVM has been amazing this summer and I would be sticking around on the discord and continue contributing to the project (to the Director engine and other stuff – like there was a content verification project proposed in the GSoC ideas list which I would definitely like to work on, not as GSoC project, but voluntary contribution). The experience with my mentors has been great, both sev and djsrv were quite helpful and understanding throughout the time, and were more than happy to help me anytime (This is the same for the rest of the director engine team – rvanlaar, mstea and moralrecordings). I am happy to have contributed to the director engine and would continue doing that.

See you! πŸ˜€

WEEK 11: Fixed 32bpp text in buttons

This week, I finally got to the bottom of this issue. I will describe the cause and the fix.
Now we have the MacButton widget, which inherits from MacText. Basically, we have MacText, which has a shape drawn around it, and that is MacButton for you (a cursory description). I spent time trying to find something around.
The color we use for rendering text is not the one provided to the widget but the ones stored in _textLines chunks of MacText.
This then led me to drawString() of Font namespace, then to drawChar(), and then to MacFONTFont::drawChar(), where the surface is filled with pixel data at relevant places.

Now, this flow did not have the issue. It worked as expected. I checked this for anything wrong but everything till the surface population seemed correct.
In the end, It turned out to be this. As you can see, values below 255 were inherently supposed to be 8bpp, and that is where the issue lied. I caught this by passing 100 and 150 as the bgcolor for the MacButton widget. When we might expect a gray color in case of 32bpp, I got green and blue. This clearly meant that it was 8bpp behaviour.

I got around this by templating this function for 8bpp and 32bpp surfaces, as the function which calls it is also templated according to surface. The changes are here.

Apart from this, I got an outline of how to implement the PopUpMenuXObj from sev, where I had some doubts regarding when to render the expanded menu list. That is something I would be completing now, along with the window optiones issue I had paused for some time earlier.

Looking for a great week ahead πŸ˜€

WEEK 10: popUpMenuXObj and diving deeper into 32bpp button text bug

This week, I was mainly working on 2 things: popUpMenuXObj and the 32bpp button text bug I mentioned in the last post.

Clearly, the hack I mentioned in the last post shouldn’t be on the master upstream. Substituting 0x000000FF with 0x010101FF is a bad idea. I and sev delved deeper into the issue tonight, and this would be resolved as a lot of details were gathered from our investigations. A lot of functions related to drawing stuff on the screen don’t use uint32 for their colors, and this is one of the things to fix.

This week, I have also started work on the popUpMenuXObj, which is a Mac XObject used in Meet Mediaband and the Apartment movies. The popUp menu is similar to the existing MacMenu in looks (just constrained to 1 submenu and can be drawn anywhere on the screen instead of just at the top)

Currently the MacPopUp is resolving the menuLists and saves it in the relevant object, making an entry in the _windows hashmap. The next step is to actually draw the menu on screen whenever it is called.

Next week, I would be focussing on completing these tasks at the earliest and then resolving the palette issues of The Seven Colours and Windows movies.

Goodnight πŸ˜€

WEEK 9: Fixing BITD decoding, text in 32 bpp

There were 3 issues I fixed this week. The rest of this blog will explain them.

The first one was the extra corner pixels being drawn in some rectangles.

While the first thing you will notice in this image is the distorted big black rectangle with colored streaks, that is not the issue I am talking about (Though that is the next one).

This was a simple fix of not overlapping the sides of rectangles at the corners in Graphics::drawRect()

The next issue was the faulty decoding of BITD resources, which gies us that garbled rectangle. This is in fact a regression, it worked well before BITD decoding of 32bpp was changed to support D4 movies.

I created a couple of test movies to check how BITD works. After checking the bytes of the movies I made, I realized that before D4, pixel data in BITD for 32bpp was saved in the ARGB format. But from D4, Director started saving the alpha of all pixels in a row, then the red value, then green and then blue. I was looking for some similarity in both the decodings, not wanting to branch it on the basis of Director version (I was thinking that Director might not have done such a change and there might be some uniformity I am missing), but I ended up writing decoding by a version check.

The end result:

I made sure this does not introduce a regression in D4 movies, and it works fine.

The next issue I picked up was no text in buttons in 32bpp mode. Now this one had more than one thing wrong with it. Buttons in ScummVM Director engine have a MacButton widget, which inherits from the MacText widget. While TextCastMember did work fine in 32bpp (Which uses the MacText widget), buttons had no text in them.

The first issue I found was that the foreground color and the background color being passed to the widget was same. I did change it, but there was this werid bit. The colors being passed to the widget were both black instead ofΒ white. Still, the buttons were all white (empty). When I switched the background color to any other 32bpp color, it did fill the button with that color, showing the text in white.

Also, MacText is not using the foreground color we pass for the font in the button, but uses the color specified in the _textLines chunk (A Graphics::MacFontRun struct)

The next problem I observed was that ScummVM was, for some reason, turning 32bpp black (255) into white. This was happening only for MacButton but not for MacText. This was the reason why buttons were white even when the background color we passed was black. When I passed 0x010101FF (nearly black) instead of 0x000000FF (black), the text rendering works. The solution I cam up with is quite hacky (replacing 0X000000FF with 0x010101FF for 32bpp button text), but I must find the root of why 255 is being converted to white and fix it.

This was all for this week. Looking forward to the next one πŸ˜€ !

WEEK 8: Finalising KEY* and update

This week, I tested and finalized the KEY* Pull Request. It is good to be merged now, and shouldn’t be adding any regressions.

moralrecordings streamed a playthrough ofΒ  Eastern Mind: The Lost Souls of Tong NouΒ on this twitch link. It seems that this game now runs much better than it did 7 months ago, that means that support for D4 games is getting better.

My first task for this week is to look in the BITD rendering regression for 8bpp. sev pointed me towards this commit, this did enable the BITD rendering for 32bpp mode. I have been advised to retain the 8bpp rendering which worked before this change along with the 32bpp which works after this, while introducing no new regressions.

This week, there wasnt much progress, as I had some interviews which ate up a lot of my hours. But that is over now, and I will resume work full time now on the tasks. The next issue in line would be fixing text in buttons in 32bpp, and I would move onto other issues then.

Looking for a great week ahead!

WEEK 7: Resource loading from KEY*, looking at text rendering in 32bpp

This week, I completed the resource loading from KEY* chunks. This change implements the correct loading of the following chunks:

  • CAS*
  • VWCF
  • VWFM
  • FXmp
  • Fmap
  • VWTL
  • STR
  • Lctx
  • Sord
  • VWLB
  • VWFI
  • VWSC
  • VWAC

Earlier, we were just looking for the first resource of these resource types and load them. But these resources are owned by the movie, and the right way is to load them from the KEY* resource.

Now, I am looking at these issues:

I am taking a look at the widget of Button castmember to check the text in the widget in 32bpp mode and other modes.

I had a crazy week full of tests, so I didn’t have a lot of progress this week. But I am happy to have passed the Mid evals, a huge thanks to sev and djsrv for that. It was made possible with their help.

Looking forward to a great week ahead!!

Week 6: Working on stuff related to resource loading

This week, I mostly worked on the 2 issues that I mentioned in my last week’s blog post.

I started off with the resource checksum implementation in ScummVM. VWCF Resources in D4 and later have a checksum and use an algorithm to check that. The algorithm was reverse engineered by djsrv and sev. These changes have been merged to master.

This functionality is important for implementing saving and loading of movies in D4 and later movies. There was a prior discussion with sev and djsrv (though it was very brief), but we would be implementing movie save and load in the engine too. sev said that he will see whether it will fit into my GSoC time line or not. Given that there are a lot of weeks left, this might happen.

The next issue I picked up (and am working on currently) is loading the resources based on the parent-child mapping given in the KEY* resource instead of just loading the first resource in the map.

Have a look at here. In one of my previous posts, I had mentioned about the multiple casts in D5 and later movies, where the concept of shared casts is obsolete. Currently, we are assigning Chunk 1D 1024 to the current movie. So children of 1024 are actually children of the current movie. Taking the case of castmembers, castmembers owned by parent ID 1024 are actually castmembers in the _loadedCast.

I plan to remove the usage of getFirstResource and change them all to the indices read by the KEY* parent-child mappings. This would be an improvement to the resource loading of the engine.

I have some tests going on at my uni, so I might have erratic work hours on some days. But I would continuously work the issues and push my work.

Looking for a great week ahead of me!

WEEK 5: Working on window properties

This week started with me finishing the Windows fonts changes. It required some changes in a lot of assorted places. In the process, I broke the desktop mode of director engine (It gives a black screen with a warning now), I am taking a look at that.

My older PRs also got merged this week, with the offset rect one still being open (I didn’t do the changes. I am also having a look at that now)

After this, I had informed sev that I won’t be able to do a lot for a couple of days, as I was travelling back to my university. I am here again.

After this, I picked up working on the window properties: https://trello.com/c/g1BaUzXz/292-missing-window-properties
I had wrestled with this in the past for a brief period of time, but I didn’t have any success. Thankfully, sev had directed me towards the code that made the first property I worked on, the titleVisible, fairly straightforward. Then I followed suit for modal, fileName and windowType (the last two still need some work)

I am not able to test my changes with the window properties as I have run into some issues with BasiliskII, where it is not opening other dictionary movies. But I can get this fixed, or maybe make my own movies for testing, while having the changes as draft PRs πŸ™‚

I plan to pick up Calculate Movie Checksum (https://trello.com/c/BpdScbbQ/501-calculate-movie-checksum) and Use KEY* More (https://trello.com/c/sHMquaRS/500-use-key-more) next. According to sev, Movie Checksum calculation would be fairly easy to implement. And using KEY* chunk mappings would solve a lot of missing resource issues we currently encounter in ScummVM.

This week’s progress was mediocre at best. I had to travel and was not in the best of health, but I hope to (I must) have better progress in the coming weeks.

Looking ahead to another exciting week!!!

WEEK 4: Fixing things

The title might seem a bit vague. Don’t worry, I am listing what I did and what the week was like.
First thing I did this week – Remove all instances of _loadedCast outside of the Cast namespace. I had been indiscriminately using it, and there were some places where it was already there (although fewer instances than what I had introduced). sev told me that this is something wrong. Till D4, we have a single cast for each movie, and a shared cast for all the movies in the project. But starting from D5, the concept of shared cast became obsolete, and a movie can have more than 1 cast. I did the required refactoring for this. Now we have barebones support for multiple casts (barebones = just an array a hashmap of casts with the first one being the loadedCast).

Next, we had The Apartment movies. sev asked me to look into this, as this would give me a better idea of how to tackle issues for other targets (like Meet Mediaband).
The issue was unintended navigation. while D2 movies worked fine, D3 and D4 apartment movies, (particularly the Pattern Viewer movie) would navigate to the help screen on pressing the next button, even when they were not supposed to.
This turned out to be a pretty interesting issue. Here is an image to help understand what was happening:

I hope it is readable. This is the D4 messaging hierarchy. Specific events are passed to the various scripts in a specific order.
Now there are these 4 scripts that can act on an event -> movie script (Applied to the whole movie), frame script (a score script applied to a whole frame), sprite script (a score script applied to a certain cell to a sprite) and the castmember script (script attached to a castmember).

Turns out, there were some quirks of both D3 and D4 about handling these messages. Explaining theme here would be a lot (these blogs are meant to be a quick summary of what I was up to), but I made 2 test movies as sev said it would be important in understanding exactly how things work and what is wrong with our implementation. You can check them out at github.com/scummvm/director-testsΒ and load them in Director 3.1 and Director 4 to play around.
djsrv had also done some digging with the message hierarchy, and she seemed to quickly understand what was wrong. She sent a patch to be applied and see if it works. Turned out that code worked (it basically rectified our event handling). So the code that solved this issue was djsrv’s.

Next, QuickDraw shapes were not showing up in D4 apartment movies. This one had a very easy fix, but I went looking for the cause in a completely different direction, checking potential resources we might not be loading, why the shapes didn’t have a CastMember assigned (as they were QuickDraw sprites, duh)

Now, QuickDraw sprites don’t have a castmember assigned as they are dealt with in the channel (That’s how I perceived it). While looking at the code for instances of handling QDShapes, I found that something was changing the spriteType of QDShapes from Shapes to CastMemberSprite. I looked deeper, and it turned out that we changed the spriteType od sprites based on their associated castMember for Director 4 and above. As QD sprites have no castmember assigned, their spritetype falls back to the default.

After this was done, I took up loading Windows Font for the mcluhan-win target.

This target used 3 fonts in .FON file format. First issue was – we use a fallback font when we can’t find the specified font. But we don’t return this information (we do display a warning though). There is a check in this movie where it queries whether the specific font is installed or not. We used to fulfil this check even when we do a fallback to some other font.

Next -> implement loading of windows fonts for director, and use them in director movies.

Now, this issue took longer than expected (and I don’t know if it is completed or not). One major reason was monsoon.
My city has been flooded due to constant downpour from 2 days.(by flooded, I don’t mean the houses submerged and emergency situation, I mean the roads are submerged, fallen electricity lines and telephone lines). There were 2 instances of electricity and internet outages that lasted hours (the second one was around 22 hours)

I had discussed this with sev and djsrv about this issue so I was able to work on them, but with hiccups. And I don’t know yet if it is complete (as stated previously).
I added loading of FON fonts to the MacFontManager for this and looked up some documentation of FON format to also extract the font name (Though it works for FON files with one font in the FONTDIR, I didn’t write it for all entries). Then adding of quirks and other things. One thing that bothered me was that these components are used commonly among engines (like WAGE, PINK and MTROPOLIS use the MacFontManager), and there were some instances that used constant pointers or passed parameters by value instead of by reference, which made an elegant implementation difficult. I couldn’t change the argument type or the return type, as it would mess up 50 other things in other engines, so I wrote it (though it looks bad to me. I believe it would become better after a review)

This turned out to be a long post. This week, when I picked up the apartment issue, I thought of solving a bug a day. Nearing the end of the week, it didn’t quite turn out to be that way, but this was a happening week. As always, I got all the guidance and support from my mentors and the Director Engine dev team.

I am looking forward to an amazing week now. Also, I will be going back to my uni this week. So there won’t be any blackouts then πŸ˜€

Thanks for reading.

 

PS: Turns out the image is not legible. You can check it out here: https://imgur.com/a/EOEgZMc