Let me take you to the time warp!

More Director games are ready for public testing!

ScummVM has made huge strides in Macromedia Director support. Many Director 3 games are now fully completable, and several Director 4 games are also now playable. 18 new games are officially supported, and we could use your help testing them. We also welcome reports of any other Director games which are fully playable or completable. To test these new games, please use the latest daily build of ScummVM. Any bugs or problems can be reported to the issue tracker.

Some highlights from the new list of games include:

  • Chop Suey by Theresa Duncan, an important classic of "girl games".
  • Eastern Mind, the cult classic from artist Osamu Kato.
  • Ganbare! Inuchan, based on the comic by singer Kenso Kato, which was the first Director 4 game to be fully completable.
  • Over-Ring-Under, by the same developer as Alice: An Interactive Museum. ScummVM's new support for CD audio in Director games lets players enjoy the soundtrack by Carl Stone.
  • The first five games by Japanese indie developer iTA-Choco Systems.

The full list of games for testing is:

  • The Better Dead Ratification (Mac/Windows)
  • Chop Suey (Mac, Windows)
  • Eastern Mind: The Lost Souls of Tong Nou (aka Tong Nou) (Mac/Windows)
  • Fukuoka Go-Round (Mac/Windows)
  • Ganbare! Inuchan: Rock'n Roll-hen (Mac/Windows)
  • Ganbare! Inuchan: Sekai no Tabi-hen (Mac)
  • Henachoco 01: Henachoco Derby (Windows)
  • Henachoco 02: Saitei Birds (Windows)
  • Henachoco 03: Difficult Book Game (Mac/Windows)
  • Henachoco 04: Ano Subarashii Bento o 1-do 2-do (Mac/Windows)
  • Henachoco 05: Yaken Rodem (Mac/Windows)
  • Japan Art Today 07: Takashi Murakami - A Romantic Evening (Mac)
  • Majestic Part 1: Alien Encounter (Mac/Windows)
  • Nemurenu Yoru no Chiisana Ohanashi (Pippin)
  • Over-Ring-Under (Mac)
  • Pepperon Mura no Shiki (aka Op avontuur in kabouterstad and Valmaison au fil des saisons) (Mac/Windows)
  • The Seven Colors: Legend of PSY・S City (Mac)
  • Time Gal (Mac/Windows)

Escape from Hell

Time flies, I didn't notice that my last post is already 3years old... 

In the meantime, I have worked on several engines, with other devs... But today, I passed an important step in the development of Escape from Hell, an old games from Electronic Arts. I loved its spirit when it was released, played it a bit but never managed to go really far in it. So, I worked on it based on good memories and, of course, that this game is particularly obscure and unknown.



I created a PR on 23/11/2022. The game was mostly reversed, as usual without sound, but it wasn't working so well. It was riddled with bugs, savegames weren't implemented, a lot of functions and variables were using generated names... In short, it was good, but clearly not enough to be sure I would finish it some day. I didn't want to have (yet another) unfinished engine merged in master... So the PR was tagged Not To Be Merged. I got a nice pile of comments from Eugene, that was helpful to improve the engine :)




Today, exactly 2 months later, I finished implementing the last sound function, and music has been working for two days. I have given a name to all the functions and most of the variables, savegames are working, and I squashed a lot of bugs in the process...I'm now confident that the engine will be finished soon, so I modified the PR so that the team knows it's worth looking at it and consider a merge after some more polishing :)



So, don't hesitate to build it and give it a try :) It's a keyboard only RPG game, it's hard, but it's fun and you end teaming with various bad guys, such as Stalin or Gengis Khan... :)

Have fun!




 

Christmas holidays roundup

 Welcome to 2023, everyone. It's now mid-month in January, and I'm back from my long overdue Christmas holidays. Unfortunately :). Whilst I did end up having to spend some of my time taking care of work, I still got significant time to rest, read some novels and, of course, muck around with ScummVM stuff :). As with several previous years, I mostly ended up fiddling around with my disassembly of the early Legend games, and trying to re-implement them in ScummVM.

Thankfully, I was finally able to make some proper progress this year. Working further on my disassembly of the first Gateway game, I started a new iteration of the Legend engine in ScummVM using the latest meta engine/detection code, and gradually pulled in the work I'd previously done in the prior version of the engine. Then using it as a basis, I started implementing the code for the main text window. This included all the logic for caching text, line wrapping, and the -MORE- indicator. When it was done, I finally had the basis for displaying game messages.

Once that was done, for the first time, I started looking at the actual engine implementation. And I made progress, stumbling on a set of methods that implement what seemed like a basic C++ class hierarchy in C, with a table of 734 "objects" that were each one of eight different categories/types. Each type having a given amount of currently unknown data values. The only field of these structures that is currently known is a "method index" into a table of functions. Whilst the bulk of objects have a unique function, there are a few that don't have one, or share the same method. This is also how I know the code was a manual implementation of classes, since the function for getting the method index is basically a big switch statement that reads the appropriate offset, which is different for each category. If it was proper C++, they'd have a common base class and the field would be the same for all of them.

And these methods being pointed to.. what are they? It seems to be nothing less than all the per-game custom logic. With a bit of experimentation, I found that the first category was for rooms. Changing rooms in game is basically a matter of changing the room object being pointed to, and executing some code in the room for entering it. There's a global "room object num" that has the starting room by default, but by changing the value during startup in the DosBox debugger, I was able to change the room I started in.

Funnily enough, I tried changing the "room" to one of the other category types, and realized that it's type was for items. It seems the core engine has some resiliency, since by setting it to the item, the game told me that I was now "in" the item, as if it were a room :). Presumably, the other categories may represent other types of game entries, like non-inventory scenery or room exits, and their internal functions will have the logic for looking at items, moving to new rooms, etc.

This is all a big deal, since it means that when I have time free to work on it, I now have a solid starting point for figuring out game logic, and the methods they call in the engine to do the various things. Once I spend a bit more time figuring out the sentence parser, I'll be able to rapidly progress in finally supporting the Gateway game and, likely in the future, other early Legend games as well. Though it's going to be a pain having to manually implement and test each and every object function in each game. It's a good thing I have the patience to do that kind of thing. Though come to it, if I figure out all the engine methods the game calls, maybe Ghidra can assist in quickly producing readable C code.

As a final treat, a screenshot of the current engine. The listbox, font drawing, and other elements were pulled in from work done in prior years, and they still need work. Mostly, I focused on the text area, and better understanding how the game works:



Hail, traveler. Welcome to Farr.

Most new visitors don’t know about Mrs. Riddenbutter’s, but you should do yourself a favor and enjoy some of her hospitality and a tankard or two of her ale. Double-click on her door to open it, and step inside. Riddenbutter works the bar, and the smart traveler should speak with her. Drop an idea on her to get her chatting. Like most people, she likes to talk about this and that and the other thing, and she’ll also frequently respond with information that’s more local in nature.

Yes, the ScummVM team announces support for Halls of the Dead: Faery Tale Adventure II, a marvellous work by our GSoC’21 student Yuri Guimaraes aka a-yyg, who ported the original SAGA2 engine from 1997 by The Dreamers Guild.

Please assist us with testing this game. Take your old dusty CD and feed it to the ScummVM. As usual, you will need the latest daily build of ScummVM. If you encounter any bugs or problems during your gameplay, please file them on our issue tracker.

Seasons Greetings

 With the end of the year upon us, I thought it was time to do a blog post. And then I double-checked, and realized that I hadn't actually done a blog post since the start of last year. Awkward! So, yes, it's definitely well past time that I did a new post :) Things have obviously moved on since the last time I posted. In that time, the AGS engine has been merged into master, and is now officially part of ScummVM. I also spent some finishing the game Chewy Esc From F5, and it now too is finally part of the official releases.

My passion has always been reverse engineering, and due to certain real world considerations, I wanted something simple to work on for the last six months. I ended up choosing Might and Magic 1 for several reasons. I had already done some minor initial work on it, and found the disassembly areas I'd already looked at fairly straightforward. Plus, we already supported the Xeen games. I figured that if M&M1 were supported, M&M2, which I think is closely based on 1, would also be easy to support in the future. Plus, Xeen was closely based on M&M3, so it would be easier to support that as well. So we could eventually end up supporting all the Xeen games 1 through 5. And since I know there's projects implementing M&M6 and later games, maybe one day they could be merged in, and ScummVM could support the entire series. And then maybe onto Wizardry and Final Fantasy :)


.Plus, given my familiarity with the Xeen engine, I was very interested in the possibility of introducing an "enhanced" mode to M&M1 that brought the user interface of the Xeen games to the primitive user interface of M&M1. With cleaner visuals for the various dialogs and niceties like the minimap, it could encourage people who never played the original to finally try out the game that started the entire series.


So, how is my work on the game progressing? As of today, I'm finally closing in on finishing re-implementing the original. All the user interface and game logic is done and tested, and all that's left is debugging the combat subsystem. Just last night I finished fixing the code relating to party members attacking the monsters, and now I need to start working on the code for when monsters attack the party. Apart from that there'll just be general testing.

Though there are a few other limitations remaining. I wasn't able to figure out the PC speaker code it uses for sound, so the game will be soundless. At least for the original un-enhanced version. Since the original only had sound in a few places, like when bumping into a wall, or a few notes when a party member is killed in combat, I don't consider that as a major loss.  I was also never able to properly figure out entirely how the original did image decoding and handled the EGA palette. The engine has it's own decoding that I figured out from trial and error, but it does mean that the monsters appear with the wrong colours. Unless I can figure out exactly how the original did the image rendering, I may simply have to use one of the online wikis to see the colors of each monster, and set them up in ScummVM to be correct..

Anyway, I'm hoping to at least get the remaining bulk of combat debugged before my Christmas holidays, and then worry about playing around with doing an enhanced version in the new year. As has been my habit in previous years, I'll likely find something else to do during my holidays. I'm kind of thinking to return to work on the Legend engine again. That seems to be my default fallback project. And who knows, one of these days I may even actually finish re-implementing one of the games :)

So seasons greetings to everyone, and I hope both myself and you all will have a good 2023 to look forward to.


Drill a 3D alien moon, become an interplanetary hero!

Driller aka Space Station Oblivion (in the US), the FIRST supported game of the Freescape engine, is ready for public testing!

Published in 1987 by Incentive Software Limited, this revolutionary new engine allowed players to explore a solid 3D graphic environment with complete freedom of movement for the very first time in videogame history.

A new threat emerges after humanity abandoned a dying Earth to establish a new home on planet Evath. Evath's moon Mitral has turned into a gigantic gas time bomb. A meteor is also due to impact Mitral in the next several hours. You were chosen to secure each of Mitral's 18 sectors by positioning a drilling rig over the gas pockets in each sector before the meteor strikes.

Solve challenging riddles by relying on geological clues, intuition, or good old trial and error. To survive your mission, find Rubicon crystals to restore energy and destroy (or avoid) the Laser Beacons and Skanners left behind by the Ketars. Good luck!

Our reimplemented engine features graphics using software (TinyGL) or hardware mode (OpenGL) at arbitrary resolution. The initial Driller support is limited to DOS (EGA mode), Amiga and AtariST releases, but we hope to be able to add more soon! Please contact us if you have some other release.

To play any of these supported releases, you will need a daily development build. As always, please submit your bug reports to our issue tracker.

Welcome to Adibou's magical wonderland

We are pleased to announce that ScummVM now supports Adibou 2, a popular educational game developed by Coktel Vision in 1996.

Designed for children from 4 to 7 years old, the world of Adibou is warm and full of surprises. It offers an intelligent and appealing introduction to essential knowledge like reading and math.

Whether you have young kids in your family, or are keen on reliving your childhood memories for a while, fetch the latest daily build of ScummVM, your own copy of Adibou 2, and start learning having fun with Adibou, Plop, Robitoc and Kicook!

You must copy the content of your Adibou “Environment” CD into the game directory added to ScummVM. Then, for any Adibou Application you want to add, just copy the content of their CD into a freely named subdirectory of the main game directory.

Only Read/Count 4-5 years, Read/Count 6-7 years applications are supported for now, but we hope Science, Music and English will come soon.

Currently ScummVM is aware of several Adibou versions in French, German and English, let us know if you own any language/version not yet registered. Please also report to the issue tracker any glitch you may encounter.

ScummVM 2.6.1 "Incremental Escapism" is here!

Escapism increases with yet another ScummVM release!

The ScummVM Team is thrilled to announce the immediate availability of ScummVM 2.6.1.

ScummVM 2.6.1 is a maintenance release mainly focused on improving the new features and engines we introduced in our previous release.

This update includes upgrades for the following engines:

  • AGS
  • AGOS
  • Asylum
  • Ultima
  • SCI
  • SCUMM
  • Tinsel
  • Toltecs
  • Toon

Other improvements include upgrading the icon-based grid view in the ScummVM launcher and fixing OpenGL render graphic corruptions.

Finally, Android users will be able to properly use a mouse on virtual screens, and Windows users will not have any duplicated icons folder issues.

You can find all of this goodness available for a number of platforms on our downloads page. If you are using Windows, macOS, the Ubuntu Snap package or the FlatHub repository, the auto-update robots will assist you in updating to ScummVM 2.6.1.

As always, the detailed list of improvements is available here.

Thank you for your continuous support — happy adventuring!

GSoC Final Report

Welcome!

Google Summer of Code 2022 has now ended, so this post will wrap up everything that’s been done and what is left to do.

The branch of my repository with the latest code for The Immortal can be found here: https://github.com/Quote58/scummvm/tree/immortal/engines/immortal


What has been done

– Initial analysis of the source code and ScummVM engine skeleton [relevant post] [relevant commit]

The original plan was to continue the implementation started in a previous GSoC for the DOS version of the game, however after taking a look through the source code for each version and discussing it with my mentor, the plan changed and I began work on implementing the Apple IIGS version instead.

– Support for ProDOS with Common::Archive [relevant post] [relevant commit]

The first challenge that presented itself when I began work on the Apple IIGS version was the file format for the game itself. The Immortal was originally packaged as ProDOS disks, which was an issue because ScummVM did not have support for reading this file format at all. Adding support required learning about and understanding the way ProDOS files work,  and experimenting until I had code that could parse the entire disk and list the files within. Once it was possible to get and return files from the disk with a file name, I was encouraged to integrate this with the Common::Archive class in ScummVM, and proceeded to do so.

– Compression Routines [relevant post] [relevant commit]

Once the file could be read by the engine, I decided to begin by tackling something that looked fairly self contained. The compression/decompression routines did not seem to be tied in to any other functions within the engine, and so could serve as a way to get comfortable with what I would be doing in the rest of the engine, through something with a clear purpose and input/output. In the linked post, I talk about the process of beginning to translate the assembly of the engine into C++, with the compression routines as the example.

– Initial engine and subsystem skeletons [relevant post] [relevant commit]

After the compression functions were written, the next step was to start analyzing the files in the engine and begin to understand the main path of the game logic, the connections between different files, and ultimately create the initial engine skeletons. This meant creating the outline of immortal.cpp, kernal.cpp, and logic.cpp, and creating the necessary function stubs for everything along the way.

– Palette processing [relevant post] [relevant commit]

While creating the skeleton for kernal.cpp, I decided to implement the main palette processing functions. There are not too many functions related to this, and it was a core component of the engine, so I felt it was good to implement along the way. It also served as an example of how the assembly code makes heavy use of bit manipulation and interesting math/programming principles.

– Scope and engine outline [relevant post]

One part of translating the engine that took some time to get sorted out, was the general structure of the engine itself. It isn’t initially clear how each component of the engine relates to each other, but it is important for knowing how to structure the translation, what data types to choose, how to manage scope, etc. The linked post goes over the entire process of sorting through the files and determining the general scope and relation of each component in terms of ‘layers’ in the engine. This was important for the translation going forward, as it could inform decisions about how each new component that was translated related to the whole engine.

– Story subsystem [relevant post] [relevant commit]

The ‘story’ subsystem in the game is crucial, as it defines many of the important aspects of each level of the game. It defines what and where the objects, enemies, and more are in each level, as well as the dialog strings, the sprite animations, and more. The way it is implemented in the source code is unusual, and the linked post goes into detail about it.

– Cycles [relevant post] [relevant commit]

‘Cycles’ are the way that this engine handles sprite animations, and the linked post goes over the oddities with them.

– Flameset [relevant commit]

‘Flamesets’ are the torches that you find on the walls in each level. They are not objects or enemies, but are in fact their own little subsystem consisting of a sprite cycle, and code for interacting with fireballs, and even dimming the screen when they are ‘off’.

– Sprite rendering [relevant post] [relevant commit]

Sprite rendering involved many different subsystems and took some time. This is because the method for preparing and drawing sprites is a bit unusual, and translating it accurately was a challenge. The post goes into detail about some aspects, but there are several others throughout which detail the process of understanding them.

– Text parsing and printing [relevant post] [relevant commit]

– Hit gauge [relevant commit]

This acts as the wizard’s health bar in the game, and is drawn with sprites from the font sprite sheet.

– Implemented many functions for Kernal, Logic, Level, Room, Sprites, and more, creating the skeleton of the engine in a way that supports a continued, accurate translation


What is left to do

I had hoped to have some of the map drawing in time for this post, but unfortunately the map data is stored in multiple file types (.CNM and .UNV) which require unpacking and processing before they are usable, and the formats are specific to the Apple IIGS version of the game. I am working on it, but it will take more time to decipher.

  • Drawing level data from maze files with drawchr (requires deciphering the .CNM and .UNV files)
  • Implementing an input layer through ScummVM (the engine code currently references ‘actions’ and has function stubs that are called for input, but functions for getting input from ScummVM need to be written)
  • Object and Monster subsystems
  • Music and sound implementation
  • Filling out the rest of the static and dynamic story entries (the first level is written out and the structure is there, it just needs the data for the other levels to be written out) (the static data for Str and Cyc are included, but Motive, Program, and ObjType still need to be written out)
  • Filling out remaining functions in kernal.cpp, logic.cpp, level.cpp, and room.cpp
  • Implementing motives, pickups, and other object/enemy structures and their related functions

Conclusion

My time with Google Summer of Code 2022 has been wonderful, and in some ways I am sad for it to be over. However I am also grateful to have been a part of it this year, as I have learned a lot and have gotten to contribute to something I think is meaningful. ScummVM is a great program, and a great community.

I was hesitant at first about making these blog posts, but I ended up enjoying and learning from them. It allowed me to strengthen my understanding of the code and concepts at hand, and it served as a good organizational tool, allowing me to keep track of progress each week.

I will continue to work on The Immortal, building from I have done the past few months towards a complete implementation of the game. And if possible I will continue to update this blog with progress.


 

Lastly, I want to say Thank you. To Google and ScummVM for this opportunity, to my mentor Criezy for the advice and code reviews, to Sev and all the other ScummVM members that helped me (especially with Git!), to my brother for pushing me to apply for GSoC in the first place as well as his support and help along the way, and to anyone that has read any or all of these blog posts or simply followed the progress in any number of ways. I am truly grateful to all of you for this past summer.

Weekly Update – Text Rendering

Welcome

 

As shown above, text rendering is now implemented enough to display the introduction to the game. It’s kind of neat, because every time I had tested the game ever since implementing the logic system, it was trying to display this introduction sequence. It was just calling a function that couldn’t render text until now. Similarly, after these text sequences, it loads the first level from story, getting the basics of the room set up, but it can’t display anything until I implement the tile drawing (and some ‘universe’ properties for getting relative positions and whatnot).

There are still a few things to do for text rendering, but it can even handle ‘formatted’ text, which means the string has denoted at the start that it will use automatic page breaks and spacing. For example:

For this kind of text sequence, the game will actually check the distance before drawing a word, to see if the word will fit on the current line. If not, it will start a new line, and if there is no room there either it will clear the screen and start at the top. Very neat stuff.

The process of making text render is surprisingly complicated, but not for the reason you might think. The actual text parsing is fairly straightforward. It is the individual letter drawing that gets complex. To understand why, I need to mention first what’s going on with the text drawing at all.

For any given text, the game ‘writes’ it out to the screen. Whether it is the intro text, where it fades in to a fully rendered text screen, or it’s a dialog sequence that draws across the screen at a certain speed. In all cases, the same system is used. To draw a letter, whether it’s part of a string, or just a character on its own (ex. the password ‘certificate’, or the health bar), the game uses a virtual ‘Pen’ to do it. By which I mean, the source specifically calls it PenX and PenY. I think this refers to two things. 1. The coordinates are relative, and 2. Each letter is drawn individually, in a natural way. The first is pretty simple, ‘Pen’ coordinates are relative to the edges of the viewport. So any coordinates you give to the character drawing function will automatically assume the edges of the screen are included. The second, refers to both the fact that each letter drawn gets a potential delay (which can be influenced by what buttons are held or not held down), and that letters are drawn relative to their own size, and the size of the other letters. For example, you can see that the letter ‘i’ is much thinner than ‘m’, but it fits snugly between other letters as if they were a uniform size. The thing is, when you put together all of the sprite offsets and pen movements, there is a ton going on to draw a single pixel of a letter. The process looks something like this:

Starting with a Pen of (0,0), a text sequence starts by clearing the screen (drawing a black rectangle at the viewport), and then setting the penX to 8 and penY to 4. This is just to give any text a bit of space. Keep in mind that the screen edges get added on when the Pen becomes coordinates for the sprite drawing function.

After this, we start the string. The first 4 characters of the intro string are spaces, which simply add 8 pixels to the PenX position.

Next, the letter is a capital E, and all capitals get 8 pixels of extra space added to the X. This is because every letter will add 8 pixels to the PenX after they have drawn, to cover the basic width of a letter. However wide letters like m and w add an additional 8, and this applies again if the letter is a capital, as they are twice as large in this font. Like I mentioned before however, some letters are smaller, and actually subtract a number of pixels from the Pen. For example ‘t’ subtracts 3 pixels to make sure it is drawn closer to the last letter. This is all taken into account in the sprite sizes, but we’ll see that in a moment.

Now we are about to draw the sprite, but we’re in the middle of where we know the letter gets drawn, why is that? Well along with the Pen and screen parameters, the sprites have their own individual offsets and spacing. For letters, they have a centre X of 16 pixels. This means that before drawing, the sprite game will subtract 16 pixels from whatever X position it is at.

This leaves us pretty far away from where we know the sprite draws. But before we solve that, the next step is turning the X and Y coordinates into a pixel index (the original game used a mix of byte and pixel positions, and had to convert between them. This is because the virtual screen buffer where sprites draw contains two pixels per byte, for more info on that see the post just before this one. For ScummVM, the equivalent screen buffer is stored as one pixel per byte). After this, we can start looking at the sprite data itself, which begins with a scan line offset of 20 pixels. This offset puts our index right where it needs to be to draw the first two pixels. Following that, each scan line defines the difference in position to get to the first pixel of the next line.

Putting this all together, we can see that there are many steps to translate a Pen position, to the actual sprite being drawn.

But it ensures that text renders like that, and not like this:

Next

This is now the final week (19 – 26), so this week will be both working on the next code (which I’ll mention in a moment), and also cleaning up the code a bit, getting the commits uploaded, and then making the final GSOC blog post for the submission. The code that I will try to get working this week is for drawing the map tiles (which does not use the sprite function at all, contrary to what I thought before due to sprite properties of some kind being referenced there). This first requires loading in the ‘maze’ data, and then implementing the drawing routines for tiles. These are quite complex, and ultimately I may need to just write a function for now that interprets the data on its own, and fully implement the source process in the future. Either way, I will do what I can in the time remaining. Thanks for reading!