WEEK 3: importFileInto and the PICT file format

This week revolved around implementing importFileInto command for D4. I didn’t think it would take this long but one thing led to another.
So at the start of this week, we figured out that Director also uses the PICT file format for it’s BitmapCastMember. This was found in the “importFileInto cast” workshop movie. sev asked me to write a general PICT renderer based off WAGE engine’s sprite renderer.
I ported WAGE’s sprite rendering into Director, but it didn’t work. I checked the PICT file we had, blend1.pic
Looking at the bytes of the file, I found that it was a PICT version 2 file, with word offsettinng instead of byte offsetting (1 word is 2 bytes here). While the WAGE based renderer was not accounting for word addressing. Also, while debugging why the renderer doesn’t work, the code logic didn’t fit in with the raw hex data of the PICT file I had. It was as if it looked at the wron opcodes, or wrongly read other data.

So I looked for other implementations of a PICT renderer. I found this really good image decoder, deark. This worked great with the PICT images and was written in readable C. I asked if I must switch the current implementation to something based off this on the discord channel.

Here, eientei pointed me towards image/pict.cpp, which had a basic PICT renderer similar to deark’s implementaion, but it only had support for PICT version 2 and for bitmaps (many opcodes like the ones for primitives were simply skipped). The PICT renderer worked for the files we had, but as the images were 32 bpp, the movies had to be forced to run in 32 bpp to run correctly.

Not 32bpp
32bpp
Notice that you can clearly distinguish three prominent columns. This gave away what was wrong

So, sev then implemented a naive ditherer, and Floyd-SteinBerg ditherer to dither 32bpp images to 8bpp.
My next step was to add PICTv1 support to ScummVM too. sev found a PICTv1 image “Face.pict” (can be found here). I added byte offsetting and the version and Rect opcode in the existing image/pict.cpp, and It showed some results. Apparently all the tests we used till now had bitmap data in them, the only thing that works in ScummVM’s PICTDecoder. I would find an example with primitives and add them too.
The decoding worked, but it had the wrong palette. sev then proceeded to fix it, as I wasn’t able to grasp the solution to this fully and he said that it is a short fix and I can see the changes once he does it. And it is in a semi-complete state as of now (it works in 32 bpp, but palette mapping is not working)
Last night, I was made aware of the fact that I must not use _loadedCast indiscriminately to manipulate the CastMembers. This has an important reason. Every version of Director is different from the last one in some way. It turns out that D5 had multiple casts, instead of the single + shared cast of D4. We already have CastMemberID, which has 2 integer fields, member and castLib. While member referred to the ID of CastMember, I wasn’t sure about what castLib did. Now this is something I think would be my next task -> implementing multiple casts and integrate _loadedCast and _sharedCast in them.
I also pushed some shoddy work yesterday, which was a total let down. I am very sorry for what went down then.

The BUILDBOT had encountered some issues this week, which were fixed. It then revealed some build which were failing due to my changes. I pushed the relevant fixes for the failing builds.

This week was full of learnings, but the code pushed was less than what I intended at the start of the week (I feel it is that way). I mentioned to sev about starting bug hunting in Meet Mediaband, but he told me to keep it on hold for the moment. My first work tomorrow morning would be to work on multiple casts (I must discuss this with sev too once) and then I must have a discussion with sev about tasks, so we can continuously build the Director Engine.

I must sign off now. Thanks for reading. Looking forward to a great week ahead of me.

Leave a Reply

Your email address will not be published. Required fields are marked *