Categories
Uncategorized

Week 5: Teenagent, Agent Mlíčňák, Юнагент

This week I continued to work on adding Russian, Polish and Czech strings. Last week was spent with extracting those strings from the executables, and this time I worked on making the engine load them. The task was a bit challenging and it took a lot of trials and errors the get certain things right. Let’s break down everything I did.

First of all, I had to think how I would store and then load the language specific data. Initially I thought maybe I could fit the data into in their respective locations in the original .dat file, but when looking at Polish and Czech executables, which are much larger, I realized that would not work. So I ended with adding all the strings at the end of original .dat file. In the engine, I added Segment object for each of the items, and made the engine to read from them instead of the data segment.

I started with loading and displaying Credits and Item names, as these two were the easiest. For the loading part, I introduced two Segment objects containing these two resources and made them read the data from .dat file:

I also added Resources::precomputeCreditsOffets() and Resources::precomputeItemOffset() to precompute offsets after the loading is done. This is identical to how dialog offsets are computed and is needed so that the engine can get to correct location where credit/item data start when it asks for a particular credit/item number.

Next, I added message strings. Adding them was also quite easy, and took the same approach as the one above. The only thing that needed to be carefully taken care of was combine error message. In the .exe they don’t come together with the rest of the messages. In fact this message is the last part of the combining table section. However, for the consistency, I placed this message as the last item in messages segment.

Speaking of combination messages, I added them after this. Each combination consists of the following members:

struct {

   byte _obj1Id;

   byte _obj2Id;

   byte _newObjId;

   Common::String _combinationString;

}

I split this structure to two: one containing the first three bytes which are the same for all languages, and the one containing just the combination strings.

After that, I worked on dialogs. Initially I thought it would be the same as with other strings, but at the time I forgot about dialog stacks. Because of this, the dialogs for English and Russian versions were fine, but some dialogs in Polish and Czech versions were completely off the context. Turned out, that some dialogs should be popped from dialog stacks and shown only when certain events are triggered. They were working for English and Russian versions, as the code for reading the dialog stack data was still reading it from data segment, not from the segment that was dedicated to it. After realizing this, I added stack dialog stacks as a resource to .dat, added code for loading it and correct dialogs started popping out.

Lastly, I worked on adding scene object names and descriptions. This part was the trickiest. First of all, I realized during extraction, I made an error, and didn’t not consider cases with items with default description. That is, after the null byte, these items contain 01 byte, which indicated that the objects will be given the default description name – “Cool.” (English), “Miodzio.” (Polish), “Bezva.” (Czech), “Вещь.” (Russian). Once I realized this, I fixed it here.

Another important thing to point out is that this kind structure is a part of savefile, and the objects and their members (including names) are modified in runtime. The last part about the names is crucial, as certain objects, namely four – “girl”, “robot”, “boy”, “bowl” are modified changed to their “real” names – “Anne”, “Mike”,  “Sonny or whatever”, “body”. I implemented the support for this, but forgot crucial thing – I didn’t set enough space for the initial names, so that when they are changed, it does not overwrite description part. Because of this, I was getting constant crashes when trying to load the older saves (before changes in the pr). After finding about this, I was able to fix the issue and thus, preserve compatibility with old saves.