Monday, June 12, 2017

The player is finally home.. the long way round

It's taken so many nights spent slowly debugging the original executable versus my ScummVM implementation, but the final starfield puzzle of Starship Titanic is finally working.

I'm not 100% happy with how the starfield rotates to selected markers when you've locked them in, but frankly, given that I've spent multiple months on disassembling, implementing, and fixing just this one puzzle, I'm just happy at this point that it works at all.

So now with the starfield puzzle finally completable, I was able to initiate the endgame, and see the ending video and credits:
I have to say, there were times when I grew weary of implementing and testing all the matrix code that the puzzle required. But I guess I'm just too stubborn not to see it all the way through.

So what's happening next? Firstly, there are various minor bugs that I was aware of, but hadn't previously gotten around to fixing. I'm currently working into fixing them now For example, I fixed some jerking of text in the end credits, and some black boxes that briefly appeared over the flames in the canal. I've got some outstanding issues with NPC idle animations to look into. The Bellbot also won't currently bugger off if you tell him goodbye :) Once that's done, I'll give it another playthrough just to make sure before it's announced for public testing. So expect it to be soon. For those of you that don't have the game already, the current GOG sale has it discounted. So it's a very opportune time to pick it up.

On a final note, there are couple of things associated with the game that I don't have any immediate plans to spend time on:
* The QSound library the game uses for simulating sounds in a 3D space using standard stereo output. Many know my distaste of working sound code. So I'll leave it as a future exercise for someone else to work on. I've implemented the low level sound calls using mostly the same interface as QSound exposes, so it should prove convenient for anyone who chooses to do so
* The Indeo 4 decoder still doesn't handle cases where transparency information is embedded directly into the video frames, rather than as a separate video track. Since codecs are installed directly into Windows, I'm not even sure which DLL implements the decoder. I'll try and spend a bit of time trying to figure it out, but worst case, it may be something the game just has to live with. The game currently has "best guess" code that estimates what the transparencies should be. It's not perfect, but it's reasonably servicable for now.
* I don't have any near-term plans to do any further work on the German version. I'm simply too burned out over the game, and want to move on from it. I may return to it one day; I'd also welcome anyone else who wants to look into it themselves.


Saturday, November 5, 2016

There's been a Titanic amount of progress

Since my prior posting earlier in the year, there's been a great deal of progress in Starship Titanic. I decided to put aside the problem of reverse engineering all the Star Map classes until I had the rest of the game working better. In that respect, I've made great strides since, as of last weekend, I was able to complete the entire "prologue" of the game  That included using the computer, experience the crash, talking to the Doorbot, entering the ship, and viewing the Credits. Huzzah. \o/

I was going to prepare a video showing the intro, but with the most recent changes, there seems to be some instability showing up. It seems like something that was already present, just coincidental that the newer changes result in more frequent crashes. It's kind of hard to narrow down the cause, as there's also a problem with the implementation of the Indeo video decoder we're using for NPC videos like for the Doorbot, where it's reading past the end of the frame data. So it's difficult to track down the memory corruption, as warnings about the decoder are completely overwhelming everything else.

So for now, I'll present a screenshot of the amazing multi-color Doorbot :)

After thinking over matters, I've decided to keep progressing into the game, and come back to look at the problem later on. Part of the trouble I'd been having with the code was the sheer length of the intro as I got further and further into it.. requiring me to wait through several minutes of cutscene & conversation every time I made any changes or bugfixes. Even if the intro has suddenly become unstable, I still have savegames I made from beyond it, so I'm using them as a starting point to make further progress testing into the game.

Speaking of testing, I've had a major boon to my efforts to track down bugs in the code. I was previously stymied trying to test the original Windows executable in the IDA debugger, since it kept crashing on me. Plus running in compatibility mode full-screen didn't help either. And without the ability to see "valid" values in the original executable, I anticipated it would be difficult to track down errors in my code, since I wouldn't know whether values/state at any point in time were already wrong on not.

Luckily, though, I stumbled on a solution. Using the Visual Studio "Attach to Process" allowed me to attach to the game executable without it crashing, unlike IDA. At least, for the majority of the time. Though switching from the game to the debugger and back again caused severe corruption of the full-screen display. Luckily, though, there had been some previous discussions about running the game in a window - I was able to use a utility called DXWnd that intercepted the game's DirectX calls and forced it to run a window. The result wasn't perfect, in my opinion, for anyone wanting to play through the game, but it's worked well enough for my purposes, in conjunction with Visual Studio.

As a result, I'm now making much better progress than I had anticipated, and hunting down bugs is in general much easier than I'd anticipated. Let's hope that stays the case.. my next major gameplay milestone is to complete more extensive conversation with the Deskbot to get myself a room. The basic yes/no detection for the Doorbot worked pretty smoothly first time I tried it. The Deskbot, though, is using more of the conversation parser - I've already located and fixed some problems with it. Let's hope that there won't end up being too many.

On a final note, the one downside of my surging progress with Titanic is that I'm currently spending less time working on finishing my Xeen engine. I'd originally anticipated the frequent roadblocks trying to hunt down bugs in Titanic would have me growling in frustration, and switching to Xeen for awhile to unwind a bit. Now with the ability to debug the original executable, that hasn't really happened so far, and hopefully won't happen. I'll probably end up spending more time right now focused solely on Titanic, and see if I can't get the bulk of the game with the exception of the final starmap working by the end of the year. Then I'll be in a better position to alternate between working on Xeen and trying to disassemble the remainder of the Starmap classes.


Sunday, July 17, 2016

PET is PrETty much done

Hi all. Been a while since my last posting; and a hectic last couple of weeks. After flying down to Florida for a 4th July long weekend getaway, I was barely back before I had to get ready for a work trip to the west coast. Then I get back to two days of company photo-shoots, which kind of disrupted getting back to normal work; but no sooner than they were done, I come down with a cold and had to stay home for several days. And was too sick to even really use my computer until now. :(

Nevertheless, despite all of that, work has been progressing on Starship Titanic since my last posting, and I've made a lot of progress. Firstly, there's the PET User Interface. This was one of the major areas that still had to be investigated last time. Since then, I've spent a lot of time figuring out how everything works, and re-implementing it all in my ScummVM engine. Behold the fruits of my labor:

Code for all the various areas has been pretty much all implemented. You can enter text in the conversation tab, and click stuff in all the others. There's just a few minor visual and functionality glitches here and there, such as the dials in the above image. Some of the tabs, like the Remote and Rooms tabs, are mostly untested at the moment.. it will be easier to test when I have more of the game logic implemented, and can properly test them with live data. Saving and Loading is also waiting on me to finish the saving and loading code.

As before, I was aided somewhat in implementing the PET by how clean the class hierarchy was designed, and the fact there were various internal error messages scattered about the code to give an indication of the classes' original names and purposes. For example, the code has a single common class CPetGlyph for the square glyphs used in all the different PET tabs, and CPetGlyphs for the collection of glyphs, with all the logic for scrolling and rendering. Individual PET areas simply derived from that, and instantiated whatever glyphs were needed, be they action icons like for Save, Load, and Quit, or inventory items that can be selected.

Once the PET was pretty much done, I started looking into the conversation handling and text parsing. To begin with, I worked one of the easier, self contained areas of vocabulary loading. All the vocab data for Starship Titanic is held in a resource inside the game executable called STVOCAB.TXT. It holds the data for an impressive 4700 words! A lot of these come down to synonyms for common words, and in fact even includes foreign language words, like "ein" as a synonym for "a". Each word entry in the file also contains data for what kind of word it is (such as action, adjective, etc.), as well extra information that is used by the parser to uniquely identify the words. The vocabulary loader builds up  the data for each word in turn, building a master list of overall words support by the game, and a linked list of synonyms for each word.

Once I did that, I started looking into the input processing code that gets called when a line of text is entered in the PET. First of all, the game calls some pre-parse methods. These take care of a bunch of standard processing of the line, including:

  • lowercasing everything and removing extra spaces between words
  • Conversion of numbers from textual formats into decimal. That was surprising.. the game has special code in place so you can enter numbers like '42', 'forty two', or even 'LXXIII'. That's right.. the parser is so sophisticated, it even handles roman numerals. :)
  • Expanding common contractions like "it's" to "it is".

Once preprocessing is done, it then breaks down the entered sentence into a series of words. Each word is checked against the word synonym lists to identify the known word for each entered word. Here again, the parser has extra complexities that surprised me. It can not only find word matches based on exact word matches, it has two fairly complicated routines that can identify various forms of pluralization, as well as common word prefixes like 'super', 'anti', 'counter', etc. and find matches on the word without the prefix. At the end of this process, the entire input has been broken done into a linked chain of recognized words, and the real handling of figuring out the player's input can be done using custom logic for each NPC script.

At this point, whilst I had made some inroads on NPC script handling, I somewhat started drifting on what area I worked on. Strangerke had been looking at some of the core game scripts to add me in writing game logic, so to make things simpler in the long-run I went back to the main CGameObject base class, and spent some time figuring out all the remaining unknown methods. Quite a few of the methods were basically stubs calling PET Control methods, so my prior work on the PET was a great help.

Next, there was a bunch of CGameObject methods calling movie code, so I decided it was finally time to figure out what it was doing. I was able to properly implement the game's OSMovie class which handles movies, and it's AVISurface which handles the low level AVI files. It was actually interesting in that some videos have a second video track - I haven't 100% disassembled the movie drawing code, but my impression is that pixels in one are transparent, and in the other are not.  This required me to add an extension to our AVIDecoder to allow a callback method for selecting which streams the AVIDecoder would use. That way, I could set up two decoders in the AVISurface class, one with the audio and first video track, and the second with the second video track, if present. This neatly avoids the limitations of one video track per decoder. The replacement movie code is all implemented now, but apart from cursor loading working (the cursors are stored frame by frame as a video), movie playback is still crashing, and will have to be debugged further. But at least I know what the bulk of the movie methods are now.

Finally, I moved onto the Star Control class. This is what implements the game's starmap control.. with PET mostly implemented, NPC scripts partially implemented, and movie handling more or less done, only it and sound are left unlooked at. And as I've mentioned previously, sound handling has a lot of spatial processing for sounds that I may simply not implement - the AVIDecoder already handles video sound, and I'm hoping to hook up the other sound methods to simply use standard ScummVM sound decoders. So that makes the star control the only remaining large area to look into.

Oh boy, and what a large area it is. Even basic identification of classes was already bumping up to nearly 30 classes all specific to just the star control. I felt greater and greater dismay the further I looked into it. Honestly, it was like Hopkins FBI all over again, where they included a full Wolfeinstein 3D style minigame in the PC release. In that case we were lucky, and could simply ignore it. Not so much in this case - all the classes will have to be implemented.

As I've looked into it further, and worked on classes that don't depend on others (so are self contained, and in theory easier to figure out), some of them have started to make sense. There's matrix and vector classes.. somewhat surprisingly, two versions of each, one for floating point numbers and one for doubles. I can only assume back in the day there was space vs speed considerations for having both types; I've not yet reversed all the methods, so I don't know if they can be merged in the future. I've also identified two "star points" classes that use large lists of spatial data that was hard-coded in the executable. Hopefully, the other remaining classes won't be too hard to figure out likewise.

So, all in all, things are going good. I'm starting to feel better, and I'm making inroads on the last major area of the game. Once I get that out of the way, it'll be a matter of finishing off the NPC scripts, implementing miscellaneous methods here and there such as sound handling, and then implement the game logic. Which, with all the core engine implemented, will hopefully be a straightforward, if slow process.

Tuesday, April 12, 2016

Implementing Starship Titanic in ScummVM

What began as a casual lunch-time activity (spread across many, many lunches), my work on Douglas Adam's Starship Titanic is finally starting to see significant results. See below for an example of the current progress from the start of the game:

You can't get as far as the ship crashing into your house yet, but at least you can fiddle around with the computer and, more importantly, use the television, and see Douglas Adm's visage scolding you to get on with the game. :)

I was originally attracted to working on the game more for technical reasons then the actual gameplay for several reasons. Firstly, because it was a Windows game.. my previous disassembly work has all been on DOS games, so I thought it would make a nice change of pace. Secondly, the original executable relies on compatibility tweaks to run on modern Windows systems and, according to the GOG forums, multiple people have had trouble getting it to run at all. And thirdly, the ease of disassembly.

The game has, in my opinion, the cleanest and most well thought class structures of any game I've worked on. Part of this clean hierarchy involved the bulk of classes in the game deriving from a common "CSaveableObject" base class that defines, amongst other things, the name of the class. The entire game state is laid out as a tree sturcture, with CRoomItem objects for rooms, CNodeItem objects for positions within a room, CViewItem for the different directional views within a node, and game objects under each view. Saving and loading games, including loading the initial game state for new games, is then a simple matter of dumping the hierarchy to and from disk.

Because of this, it's made it somewhat easier to reverse engineer how the classes are implemented. Since the game loading code needs to be able to locate and create classes by their textual name, it meant that I was able to properly identify and name all the classes the same way they were in the original source code (which I don't have access to). Since the original uses C++ classes and inheritance, it's meant that when I've identified the meaning of a virtual method, I could apply the same name to the same method in all the other objects. So, for exmaple, when I identified the methods for saving and loading an item's fields, I was able to focus on those same methods in all the other classes to handle loading the entire game state.

So as you can see from the above video, progress on the engine is going well. I have all the core logic in place for loading the initial game state, displaying views, and moving between them. I've also been able to graft some of the original's movie class, that handles playing AVI videos for all the game's animations, to use the existing ScummVM AviDecoder. Although there's still parts of CMovie that I don't understand. And there also isn't any background sound yet. Apart from that, there's two main areas left to be handled: firstly, all the hardcoded game logic. If there's one thing that I find a pity, it's that rather than using some kind of scripting system, they chose to implement all the game logic in code. So all the various interactable objects in the game have their own code that will need to be slowly implemented.

The other main area remaining to be figured out is the PET control that provides the game's user interface. Particularly the conversation system, where you can converse with the characters within the game. I've already made some minor in-roads into implementing display of the PET, and various error messages in the original executable have given me some ideas of various classes in the conversation system. But it will still take a while to fully implement the game. Plus of course, dispute recently working on it quite a bit in my off hours, work on this game has primarily been a lunch-time diversion, so it's somewhat limited by my work's totally unreasonable policy that lunch should be limited to only a single hour each day :)

Thursday, November 5, 2015

The intricacies of disassembling RTLink/Plus

Finally, after many years of half-hearted attempts, I've finally rewritten my RTLink decode tool practically from scratch to handle disassembling the RTLink/Plus overlay management used by the later Legend entertainment games. See rtlink_decode for the result. The original version of the tool was pretty dodgy, and pretty much hardcoded to only handle the MADS games (Rex Nebular, Return of the Phantom, and Dragonsphere). In this posting, I'll go into more detail of what RTLink/Plus was for those who may be interested.

In the latter days of DOS gaming, game developers started running into a problem. Namely, that their executables were starting to hit the limits of main memory. Not every game could, or would, take advantage of scripting game content, so having all the game logic in the main executable caused the size to bloat. So what to do if your executable was now too big to fit in memory? This was the problem RTLink/Plus was designed to solve.

RTLink is essentially an overlay manager. It splits a program's compiled code into multiple different segments, and allows them to be loaded in as needed, and then replaced when code in other segments needs to execute. RTLink can handle recursive segments, with individual segments split up into their own set of swappable sub-segments. It also allows for multiple different "loading areas" in memory that can independently have their own set of segments. See this article for more general information about RTLink.

Before I go into more details of the problem this posed for disassembly, let's go over how RTLink implements the overlay manager in code. So far, I've encountered three different variations on RTLink being used in executables. What I'll call variation 1 & 2 seem to be the most common form of RTLink in games I've examined. When a program is compiled with either of these versions of RTLink/Plus, one of the segments in the code will contain the RTLink logic, as well as two main areas: the dynamic segments and the function thunks.

The segment list is a list of the dynamic segments within the application. It contains the following information:
  • The segment in memory where the dynamic segment should be loaded
  • Whether the segment is stored in the application or a secondary overlay file (Variation 1 only, version 2 only ever uses the executable).
  • The file offset and size of the segment
  • The number of relocation entries the segment has; Variation 1 only. Variation 2 has it as part of the starting header for the segment pointed to.
When a segment is needed, the above details are used to read the segment's data from file, and load it into the correct place in memory. The data for a segment consists of two parts: an initial header area, and the date/code for the segment. For variation 1, the header area simply consists of a list of relocation entries. Whereas for variation 2, the details of segment size and number of relocations are provided in a header at the start of the segment, before the relocations list.

A segment's relocation entries are used for the same purpose as relocation entries in a standard application - executables can be loaded at different locations within memory, so all segment references need to be relative to the starting point of where the program is loaded. By keeping the relocation entries for each dynamic segment together with the segment data itself, it's easier for RTLink to apply any needed segment adjustments each time a dynamic segment is loaded.

This is fine to handle shifting the segments in and out of memory, and allow them to have valid memory references, but what causes them to be loaded? The answer is the method "thunks" area of the RTLink segment. When dealing with dynamic segments, you can't just do a far call to some offset in the area of memory segments are loaded in.. you couldn't be sure that the segment you want is actually loaded, or still in memory and not unloaded by some other segment. For this purpose, the thunk list is present.

For every method in a dynamic segment that is referenced by any other segment, a thunk/stub method is created. These consist essentially of the following: a call to the RTLink manager to load the correct segment for the method, a far jump to the method in the correct memory location in the loaded segment, and a following 16-bit value specifying which segment the thunk is for. This way, the thunk method acts as a wrapper, ensuring the correct segment is loaded and passing control to the method to execute.

For variations 1 and 2, the thunk methods have some minor differences, such as version 2 using far calls to the RTLink segment loading code, and having an optional word after the segment index. The segment selector in the far jump call is also already loaded with the memory segment in variation 1, whereas in version 2 it's normally 0 initially, and then set to the correct segment when the thunk method is called. This allows variation 2 to dynamically load the segment in different places in memory, whereas variation 1 is limited to a single specific loading point.

The RTLink segment loader method also mucks around with the stack to push a new intermediate return address on the stack for when the method that's jumped to finishes. This return address points to a code fragment that also handles the case where a method in a dynamic segment calls a method in another one.. in that case, it handles reloading the original segment, so that the original caller's code can be safely returned to.

Put altogether, this scheme allows programs of practically any size needed. As the program grows, the code simply needs to be split into more and more dynamic segments which will get loaded only when needed, and remain on disk when not. Great for having big programs, but not so great for those of us interested in reverse engineering the game by disassembling the executable.

There were several problems to be solved for disassembling such games, which I'll go into now.

A standard IDA disassembly doesn't have all the code

Well, it wouldn't. If you try to disassemble an RTLink/Plus compiled game, IDA will give you an error about unused data at the end of the executable. This will be for one or more RTLink segments. Additionally, as previously mentioned, some of the code for the program can also be stored in a separate OVL (Overlay) file.

Well, I could just load the raw data for them into the disassembly, right?

Well, no. That wouldn't help much, because of all the thunk methods. They all have their references to the same area of memory where segments are expected to be loaded. If you were doing things manually, you'd need to get the details of each segment from RTLink, manually load the code and/or data into new IDA segments, and then manually adjust the thunk methods to point to those methods.

You'd also need to worry about the dynamic segment relocation entries. If you manually loaded the code for a segment, you'd have to read the list of relocation entries for the dynamic segment and manually adjust each relocation entry within the segment. Segment selectors may point to code within the segment (or another sub-segment within the loaded overall RTLink segment), to a low memory area of the executable that remains static in memory, or to the data segment (at a higher memory segment). All in all, you'd have to be extraordinarily patient to all that by hand.

So that's why you wrote rtlink_decode, right? That's what it does?
Yes and no. A bit part of what it does is indeed doing the above to create a new executable suitable for disassembly. This includes laying out all the dynamic segments sequentially (without their segment headers and relocation lists), handling relocation fixups, and the thunk methods adjusted to point to their methods in the decoded executable. However, another problem crops up in the handling of the data segment.

In my experience with RTLink, I've come across across two types of data segments:
  1. In the case of the later Legend Entertainment games, the executable has a single RTLink segment, with the remainder of the segments coming from an OVL file. The single executable segment is for the main data segment as well as a few other miscellaneous segments.
  2. In the case of the MADS games, the data segment isn't an RTLink segment, but all the RTLink segments follow it in the executable.
In both cases, we have a problem doing a proper disassembly. Executables are normally expected to have the data segment at the end of the program, because the data segment may be longer than the end of the executable. For example, a game's data segment may only have 1Kb of pre-set values which are stored in the executable, but it still requires 40Kb of unallocated/uninitialized space. That's why you'll frequently see, when you do a disassembly of a program, areas at the end of a data segment with '?' mark values, indicating the memory isn't part of the executable, so doesn't have any specific value when the program starts.

So if we did just lay the segments end to end, the data segment, coming before other dynamic segments, would end up being shorter than it should be, and a lot of the references to data within it would end up wrapping onto the following dynamic segments in the reworked executable. To avoid this,  the rtlink_decode tool ensures that the data segment falls at the end of the generated executable, after all the other segments. This, however, causes it's own share of problems. All the existing references to the data segment refer to where the data segment was expected to be loaded in memory, not to where the data segment actually is in the new executable. Because of this, all the references to the data segment in the executable have to be adjusted accordingly.

Ouch! Sounds fiddly.

It is. And took a lot of messing around to get right. Even then, that's not the entirety of the picture. For Companions of Xanth, the Legend game I used for testing when rebuilding the tool, the data segment has some extra gotcha's.. It contains segment references into the middle of the memory area RTLink segments are loaded into. Presumably these are used in some special controlled circumstances when a specific segment (or segments) are loaded to access particular data. But it's impossible to know without understanding the game a lot better. 

Worse, the presence of the references were screwing up some of the loaded dynamic segments in the disassembly, causing them to be split in half. To handle this, the tool explicitly looks for such "bad" references in the data segment, and removes the relocation entries for them. This way, the value in the data segment will remain as a static word, and the segments don't get incorrectly split up. The user can always then later manually set up a pointer to an appropriate segment if they wish. This handles the bulk of such errors, but Xanth at least, there are still references in the low part of the executable (that remains static in memory) to locations within the RTLink segments. Since I can't know which particular RTLink segment is meant to be loaded when the code they're in is called, these few remaining references will have to be later manually adjusted as well.

So that's it?

Yep. After all these years, I'm finally able to generate a (mostly valid) "decoded" executable, and produce a clean disassembly of Companions of Xanth. I also, initially, had two separate versions of the the tool, one the old hacky version for MADS games, and the legend variation for Legend-style RTLink usage. I've since updated my tool to properly handle MADS games, so now there's only the single rtlink_decode tool, and it can handle both variations 1 and 2.

Oh, wait.. what about the 3rd variation you mentioned?

Ah, yes, I didn't really get into that, did I. This version seems to be somewhat different than the other two variations. In this case, the RTLink code is stored in a separate file, and then loaded into memory. It then shifts part of the program downwards in memory, and uses it's own relocation table to manually process relocation entries on the shifted code. This variation is proving tricky to disassemble, so whilst I have located the segment list, I still need to:
  • Figure out how relocation data is encoded. I think I've located the correct data in the executable, but the code RTLink uses to update relocation entries is pretty nasty and overcomplicated.
  • How much of the start of the executable to remove so that the produced executable doesn't have any of the old code at the start of the executable that gets overwritten
  • Find the thunk methods, and see whether the existing code will handle them.

Hopefully I can quickly figure out the remaining details for the third variation soon. The goal is to have a tool that both myself and others can use in the future to help them disassemble any game that used RTLink/Plus. Then no-one else will have to go through all the frustrations that I did trying to deal with this %#@! thing.

Saturday, October 31, 2015

Sherlock Testing Resounding Success

Hi everyone,

It seems like the testing of the Sherlock games has been a success. There were lots of bug reported, and all the ones reported so far have been fixed. The foreign language versions haven't all been fully tested yet, but hopefully now the immediate crashes with conversations and inventory in both Serrated Scalpel and Rose Tattoo foreign language versions have been fixed, and the rest of the games can be tested. I'd like to thank everyone who's tested so far for your efforts, and feel free to post any more bugs you come across. Though hopefully there won't be too many more to find :). And if one else has copies of either game, particularly different foreign versions, any other testers would be appreciated.

Right at the moment I'm at the sweet point where all the outstanding bugs for Sherlock have been resolved, so unless new ones come in, I can turn my attention to other things.

So, whats coming next for me? Several things:

Serrated Scalpel 3DO

Serrated Scalpel 3DO still isn't completable. There are some areas, such as the darts game to fix up, and there are still some differences in sprite positioning that would need to be accounted for. It's somewhat constrained by the fact that we don't have any original source for it, and I don't have any experience with reverse engineering 3DO games. It may simply be a case of do as best we can with hardcoded fixes as necessary.

The 3DO version also has a few missing things compared to the PC version; notably it lacks the journal the PC version has. A "nice to have" for the future would be to reintroduce it, so that the 3DO version could be the definitive version of the game, containing all the PC version functionality as well as the video for all conversations. We'd likely create a tool that extracts necessary graphics for UI buttons and the journal background from the PC version, and produce a Dat file that ScummVM can use automatically when playing the 3DO version.

RTLink Overlay manager

Next, there's the RTLink/Plus overly handling in Companions of Xanth. I'd previously had some luck writing a tool to process Rex Nebular and create a flat executable with all the segments suitable for disassembling, but doing the same for Companions of Xanth proved elusive. Over the years I made several attempts, but none bore fruit. Until now. As of yesterday, I was finally able to write a new version of the tool that successfully generated a flat executable that could be disassembled. So one day, after a great deal of disassembly work, ScummVM may support the game.

My only disappointment is that RTLink/Plus seems to have had quite a number of variations. Rex and Xanth's RTLink mechanism were fundamentally similar, with all the RTLink code, segment list, and method thunks/stubs in the executable and/or overlay file. For several other games with RTLink that I tried, however, they seem to use a bizarre alternate method where a file called '' is loaded, then an '.RTL' file for the game, and finally only then the game executable. Which means that my tool doesn't work with them, and I'd need to figure out this new mechanism from scratch if I want the tool to be general-purpose enough to handle any RTLink game anyone might want to use it on in the future.

Guess that can be another long-term project to muck around with. Hopefully it won't take as long as it did to finally get Xanth properly disassembled. :). I'll probably make another posting in a day or so about RTLink in more detail, for those that are interested.

Might & Magic, World of Xeen

Next there's my work on re-implementing Might & Magic - World of Xeen (and Clouds of Xeen, Dark Side of Xeen, and Swords of Xeen). With some free time last weekend, I finally returned to working on them, and likewise was finally able to properly disassemble the  algorithm the original used for scaling. So as of now, sprites are now correctly scaled, as before I was only using a rough guess scaling code I'd nicked from another game engine. I've also fixed some other drawing bugs for drawing outdoor areas (outside town). So as of now the game scenes now display properly! :)

That's right, you can now walk around, fight monsters, go visit the various buildings in town, and even leave the town! In fact, most of the functionality for the games are already implemented. Apart from lots of testing and minor bugfixes that will be needed, only the following major areas remain to be implemented:

  • Introduction/ending sequences for the games
  • character management, and title screens.
  • Sound. I'm hoping I can simply slot in one of ScummVM's audio decoders without much further work.
  • Savegames

At the moment I'm concentrating on getting World of Xeen (which combines Might & Magic 4 and 5 together) working. But then afterwards I'll implement separate support for 4 and 5, as well as for Swords of Xeen. It might even be feasible to handle Might and Magic 3 - Isles of Terra as well, since I'm given to understand the engines are nearly the same.

Those interested in following the progress can see it at the brand-spanking new RogueVM Github account. That's right; after all the years of idle talk, I've finally set up a place to properly store RPG related game engines. No website yet, but at least it's a start. :) I'll likely spend the near-term focusing mostly on finishing support for the game before I move onto any other adventure games, considering how far along the engine is already.

Return of the Phantom

Strangerke has put a lot of work recently into implementing scene logic for Return of Phantom, the next MADS game that was published after Rex Nebular. There are quite a few stubs for missing engine functionality that was added in though. So when I do return to working on adventures, it will likely be to assist him in completing the game.


Monday, July 6, 2015

Rose Tattoo is in progress

Hi all,

Work is progressing well on Rose Tattoo, and as of tonight I hit a major milestone.. the entire game intro sequence is now completable. See the screenshots below:

There are still some minor graphic glitches at various points, and one of the scenes which is a double-side scene isn't properly scrolled horizontally yet, but even so, it's a great step forward in supporting the game. We're actually lucky in that Rose Tattoo implemented all of the introduction using standard game scenes. So it saved a lot of effort implementing manual introduction code like had to be done for Scalpel.

Now that the introduction is working, more or less, I'll be devoting more time to implementing the game-play. I'd already been spending some of my working on it, so some interaction is possible.. you can look at objects, open up the inventory, and conversations with characters are partially working. The game map is also already implemented, so you can get to other game locations as well.

On another subject, I had good luck implementing the original EA logo at the start of Serrated Scalpel. I was able to complete support for it in the TsAGE engine, and then used that as a basis for copying necessary code into the Sherlock engine. With some most welcome assistance from others, the EA logo at the start of the game now displays when you start the game, just like the original does.

Finally, on yet another tack, there have been some promising first steps towards supporting the 3DO version of Serrated Scalpel by m-kiewitz, with some assistance from clone2727.  The 3DO was a superior version of game, and included 16-bit color, video portraits, and full speech for every conversation in the game. Supporting this would be great. It would be nice if, one day, the 3DO version could be re-released with ScummVM, so a wider audience could properly enjoy the game.