Whilst it's nowhere near as spectacular as adding support for Discworld 2, the latest SVN code now supports the original Discworld 1 Demo.
This demo is somewhat interesting in that it was built at an early stage during the development of the first game. As such, it used a more primitive version of the source code used in the final game. Luckily, it didn't prove too hard to cross-reference a disassembly of the demo executable and identify commonalities between it and the DW1 v1 source code, and from there work out what had changed.
The demo version I used during development was downloaded from Adventure-Treff.
There were actually two demos released for DW1 - this first one contained only the two 'rooms'.. the Fishmonger's and Alley, and the single objective of getting the belt buckle. Please note that this version does not have any sound.
The second demo released apparently contained most of Act I, and featured full voices and SFX. If anyone knows where a copy of that version can be located, I'd be interested in making sure that that version also works with our Tinsel engine.
Sunday, December 14, 2008
Tuesday, December 2, 2008
Discworld 2 support added to SVN
Well, it's been a little over three months since my last posting, and now my current efforts are finally complete.. as of last night, Discworld 2 support has been committed into the ScummVM trunk.
First things first - setup instructions will probably be added into the main README shortly, but for those of you who just can't wait to get it up and running need to do the following steps:
copy the contents of both CDs into a folder on your hard disk, and rename the ENGLISH.* files on both CDs into ENGLISH1.* and ENGLISH2.* respectively. That goes for other foreign language versions the same, with whatever the language name being.
Remember that Discworld 2 isn't officially supported by ScummVM yet. To play it, you'll need the latest daily build from at least 2/12/08, or build it yourself. We also don't have a Discworld category under the ScummVM Bug Tracker, so any issues would be best discussed in the IRC channel or on the forums.
Special thanks go to DrMcCoy, who pitched in and implemented the changes to the sound/music handling for Discworld 2. Also to the rest of the team who participated in the Discworld 1 development, who provided the occasional code additions and testing during integration of the Discworld 2 code.
In case anyone's been wondering about my progress on the M4 engine, well, my apologies, but wouldn't you know that barely a few days had passed after my last blog posting when we got the Discworld 2 source. So I never really had a chance to delve much further into the graphics system like I said I would. Never fret, though, it's still a long term goal to finish disassembling Rex Nebular and start adding support for it, although I'll probably put it on hiatus again if the team gets given the source code for any other game that needs implementing. As fun as reverse engineering is for me, it's nice to work on a project where you can see rapid results from your work.
What's next for me? Now that the code's been publically released, I plan to move onto adding support for the Discworld 1 demo. I've already been spending some off time working on a disassembly of the executable, cross-referencing methods against the Discworld 1 source, and it shouldn't be long before I can start adding demo-specific code to the Tinsel engine.
Oh, and of course, I've still got copies of LittleBigPlanet and Fallout 3 on the shelf waiting to be played. They've been calling out to me in the middle of the night, saying 'Play me, play me', but I've been firm.. I wasn't going to play them until Discworld 2 was finished. Now that it has, I expect to spend some quality time this Christmas traversing the wasteland, and blowing the crap out of stuff. :)
First things first - setup instructions will probably be added into the main README shortly, but for those of you who just can't wait to get it up and running need to do the following steps:
copy the contents of both CDs into a folder on your hard disk, and rename the ENGLISH.* files on both CDs into ENGLISH1.* and ENGLISH2.* respectively. That goes for other foreign language versions the same, with whatever the language name being.
Remember that Discworld 2 isn't officially supported by ScummVM yet. To play it, you'll need the latest daily build from at least 2/12/08, or build it yourself. We also don't have a Discworld category under the ScummVM Bug Tracker, so any issues would be best discussed in the IRC channel or on the forums.
Special thanks go to DrMcCoy, who pitched in and implemented the changes to the sound/music handling for Discworld 2. Also to the rest of the team who participated in the Discworld 1 development, who provided the occasional code additions and testing during integration of the Discworld 2 code.
In case anyone's been wondering about my progress on the M4 engine, well, my apologies, but wouldn't you know that barely a few days had passed after my last blog posting when we got the Discworld 2 source. So I never really had a chance to delve much further into the graphics system like I said I would. Never fret, though, it's still a long term goal to finish disassembling Rex Nebular and start adding support for it, although I'll probably put it on hiatus again if the team gets given the source code for any other game that needs implementing. As fun as reverse engineering is for me, it's nice to work on a project where you can see rapid results from your work.
What's next for me? Now that the code's been publically released, I plan to move onto adding support for the Discworld 1 demo. I've already been spending some off time working on a disassembly of the executable, cross-referencing methods against the Discworld 1 source, and it shouldn't be long before I can start adding demo-specific code to the Tinsel engine.
Oh, and of course, I've still got copies of LittleBigPlanet and Fallout 3 on the shelf waiting to be played. They've been calling out to me in the middle of the night, saying 'Play me, play me', but I've been firm.. I wasn't going to play them until Discworld 2 was finished. Now that it has, I expect to spend some quality time this Christmas traversing the wasteland, and blowing the crap out of stuff. :)
Wednesday, July 23, 2008
Well, it's been a little under two months, and now the Tinsel engine has been released to an eagerly awaiting public. I just hope people don't get too distracted playing it that they forego testing the other games for the 0.12 release. :) Currently Discworld 1 is supported, but not the demo. Kudos to everyone else involved in bringing the conversion to ScummVM to fruition so quickly.
On a more technical note, those of you who are proficient with using the debugging console may wish to experiment with the console in this game.. there are several commands, such as "scene", which allows you to jump to any particular scene number. Another nice one is the "sound" command.. I particularly like "sound 5931". :)
Given the amount of time spent on the Tinsel engine, I haven't had much time to work on the disassembly of Rex Nebular. So there hasn't been much to talk about on my blog. But now I'm back into it again. When last I left, I was starting to plunge into the depths of the dialog display code. This actually proved a useful starting point because:
1) The difficulty dialog is the first thing displayed by the game as it starts, which makes it easy and quick to trace to when running the game in the debugger.
2) We already more or less know both the screen and sprite format used by the engine, which makes it easier to understand and decode the related routines.
3) It also uses font display, which again, allows me to quickly identify the appropriate routines.
4) It allows me a starting point for identifying various other routines, such as mouse/cursor handling, event loops, and graphics routines.
As you can see, the dialog code provides a useful starting point for understanding core functionality used by the game. By identifying these routines, it will make it easier later on to understand other game routines that make use of them. The only problem is that the dialog display code seems to be unreasonably complicated - it seems they tried to used the same code to potentially handle various dialog text, such as headers, control options, and savegame names.
On a more technical note, those of you who are proficient with using the debugging console may wish to experiment with the console in this game.. there are several commands, such as "scene", which allows you to jump to any particular scene number. Another nice one is the "sound" command.. I particularly like "sound 5931". :)
Given the amount of time spent on the Tinsel engine, I haven't had much time to work on the disassembly of Rex Nebular. So there hasn't been much to talk about on my blog. But now I'm back into it again. When last I left, I was starting to plunge into the depths of the dialog display code. This actually proved a useful starting point because:
1) The difficulty dialog is the first thing displayed by the game as it starts, which makes it easy and quick to trace to when running the game in the debugger.
2) We already more or less know both the screen and sprite format used by the engine, which makes it easier to understand and decode the related routines.
3) It also uses font display, which again, allows me to quickly identify the appropriate routines.
4) It allows me a starting point for identifying various other routines, such as mouse/cursor handling, event loops, and graphics routines.
As you can see, the dialog code provides a useful starting point for understanding core functionality used by the game. By identifying these routines, it will make it easier later on to understand other game routines that make use of them. The only problem is that the dialog display code seems to be unreasonably complicated - it seems they tried to used the same code to potentially handle various dialog text, such as headers, control options, and savegame names.
Friday, May 23, 2008
It's a real pleasure to be able to be able to return to proper disassembly work after the interval I had to spend writing the delinker tool. Subjectively, I know that writing the tool was a necessary step that would save me issues in the long run, but it was still annoying to have to write and then spend all the time fiddling with it to get it work, particularly since I'd never really bothered to look at the structure of executables, and was learning from scratch.
Getting stuck into Rex Nebular, I've started debugging it using the DOSBOX debugger. I was a bit unsure about using it at first, but it's turned out to be an excellent tool. Back when I was disassembling Lure of the Temptress, I made do with DEBUG, which wasn't bad, but obviously had issues with trying to debug graphics programs.. I'd actually had to hack the game executable to stop it setting graphics mode so that I could use DEBUG to trace through all the startup code. Now with DOSBOX, I can trace anywhere in the program, since the debugger itself is in a separate window, which is wonderful.
About the only real annoyance remaining is the RTLink library itself. Although I do have a full disassembly based on a processed executable, I still need to do my debugging on the original executable (if the game worked without the extra space it provides, they wouldn't have needed it in the first place). The issue is that due to the way RTLink works, a call through a proxy stub can actually unload the calling code, which then gets reloaded when the called function exits.. but not necessarily in the same place.
Which means that you might try stepping over a function call, and suddenly the entire game sequence will play out, because the location returned to after the function call may now be at another segment address. Confused me at first, until I happened to trace out of a method and realised what was happening. :)
Getting stuck into Rex Nebular, I've started debugging it using the DOSBOX debugger. I was a bit unsure about using it at first, but it's turned out to be an excellent tool. Back when I was disassembling Lure of the Temptress, I made do with DEBUG, which wasn't bad, but obviously had issues with trying to debug graphics programs.. I'd actually had to hack the game executable to stop it setting graphics mode so that I could use DEBUG to trace through all the startup code. Now with DOSBOX, I can trace anywhere in the program, since the debugger itself is in a separate window, which is wonderful.
About the only real annoyance remaining is the RTLink library itself. Although I do have a full disassembly based on a processed executable, I still need to do my debugging on the original executable (if the game worked without the extra space it provides, they wouldn't have needed it in the first place). The issue is that due to the way RTLink works, a call through a proxy stub can actually unload the calling code, which then gets reloaded when the called function exits.. but not necessarily in the same place.
Which means that you might try stepping over a function call, and suddenly the entire game sequence will play out, because the location returned to after the function call may now be at another segment address. Confused me at first, until I happened to trace out of a method and realised what was happening. :)
Wednesday, May 14, 2008
My first posting
Welcome, everyone, to my new blog. I figured that since blogs have been becoming popular in the ScummVM community lately, I might as well start my own as well. My interests lie in disassembling and reverse engineering old adventure games, and then re-implementing them in ScummVM.
For this inaugural blog post, I'd like to talk about one of my latest projects - working on the MADS/M4 engine. I'm concentrating mainly on the MADS side of the engine at the moment, which was the game engine used for the three games - Rex Nebular, Dragonsphere, or Return of the Phantom, what the current status is of the engine.
I've been concentrating primarily on disassembling Rex Nebular - the game itself is split into a series of executables to save space:
The next big step now was to start disassembling the main game executables to figure out all the in-game logic. This was when I'd hit a big stumbling block.. In order to properly understand a game, you have to be able to disassemble it in a dissassembler in it's entirety, so you can start identifying methods and variables, and gradually build up an understanding of how the game works. In the case of the actual game executable, though, all three games had been compiled with an overlay manager called RTLink/Plus, which was designed to save memory by swapping parts of the program code in and out of memory on the fly at runtime.
This therefore made the game difficult to disassemble, because:
1) The functions calls and jumps between code in different segments went via an intermediate table which was dynamically filled in at runtime
2) The data segment was in the middle of the program - this posed a problem because programs typically have the data segment at the end of the program, to allow for uninitialised data areas - space for variables which don't have an explicit value set at startup, so don't need to be part of the executable image.
As such, I was forced to write a program, which I've named rtlink_decode to handle these executables. I'm really quite proud of it - it takes in an executable, and presuming that it detects that is was compled with RTLink/Plus, creates a new executable with the following changes:
1) It detects all the dynamic segments and adds in relocation entries to the executable so that all segment references within these segments are treated like normal code segments
2) Processes the table used for inter-segment calls to fix them to go to the correct segment (what RTLink would have done dynamically at runtime wherever it loaded a segment)
3) Shifts the data segment to the end of the executable, and adjusts any data segment references in the executable to point to the new position.
The result is a new executable which was able to be fully disassembled by IDA Free - which I strongly recommend as a wonderful disassembler for anyone who's thinking about experimenting with reverse engineering.
Now that I've got a clean complete disassembly to work with, I can start figuring out the game logic. This time, though, I won't be starting from scratch - there is shared code between the game executables and the menu, credits, and animation executables, so I've already been able to identify a lot of runtime library methods, as well as other MADS methods I'd previously already figured out.
Nevertheless, it's likely still going to be a while before there's enough disassembled that any major functionality can be implemented into ScummVM, so you'll need to be patient.
For this inaugural blog post, I'd like to talk about one of my latest projects - working on the MADS/M4 engine. I'm concentrating mainly on the MADS side of the engine at the moment, which was the game engine used for the three games - Rex Nebular, Dragonsphere, or Return of the Phantom, what the current status is of the engine.
I've been concentrating primarily on disassembling Rex Nebular - the game itself is split into a series of executables to save space:
- mainmenu.exe - Which contains the logic for the main menu
- animview.exe - Which contains the logic for displaying cutscenes, like the intro and ending animations
- textview.exe - Which contains the logic for displaying scrolling text, as in the credits and quotes.
- nebular.exe - The actual game itself.
The next big step now was to start disassembling the main game executables to figure out all the in-game logic. This was when I'd hit a big stumbling block.. In order to properly understand a game, you have to be able to disassemble it in a dissassembler in it's entirety, so you can start identifying methods and variables, and gradually build up an understanding of how the game works. In the case of the actual game executable, though, all three games had been compiled with an overlay manager called RTLink/Plus, which was designed to save memory by swapping parts of the program code in and out of memory on the fly at runtime.
This therefore made the game difficult to disassemble, because:
1) The functions calls and jumps between code in different segments went via an intermediate table which was dynamically filled in at runtime
2) The data segment was in the middle of the program - this posed a problem because programs typically have the data segment at the end of the program, to allow for uninitialised data areas - space for variables which don't have an explicit value set at startup, so don't need to be part of the executable image.
As such, I was forced to write a program, which I've named rtlink_decode to handle these executables. I'm really quite proud of it - it takes in an executable, and presuming that it detects that is was compled with RTLink/Plus, creates a new executable with the following changes:
1) It detects all the dynamic segments and adds in relocation entries to the executable so that all segment references within these segments are treated like normal code segments
2) Processes the table used for inter-segment calls to fix them to go to the correct segment (what RTLink would have done dynamically at runtime wherever it loaded a segment)
3) Shifts the data segment to the end of the executable, and adjusts any data segment references in the executable to point to the new position.
The result is a new executable which was able to be fully disassembled by IDA Free - which I strongly recommend as a wonderful disassembler for anyone who's thinking about experimenting with reverse engineering.
Now that I've got a clean complete disassembly to work with, I can start figuring out the game logic. This time, though, I won't be starting from scratch - there is shared code between the game executables and the menu, credits, and animation executables, so I've already been able to identify a lot of runtime library methods, as well as other MADS methods I'd previously already figured out.
Nevertheless, it's likely still going to be a while before there's enough disassembled that any major functionality can be implemented into ScummVM, so you'll need to be patient.
Subscribe to:
Posts (Atom)