Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Old Games Launcher

0.00/5 (No votes)
31 May 2012 1  
A DirectDraw game launcher & DosBox frontend written in C#

Introduction

Recently, I've been trying to play some good old games like Diablo I, Starcraft, Age of Empires. The problem with these games is that they use DirectDraw API for rendering graphics. This is problematic, because since the arrival of DirectX 10 DirectDraw APIs are only emulated, they don't get real hardware acceleration.

Modern CPUs can calculate these primitive graphics without any speed problem. However these games use only 256 bit color graphics. So if you try to run Age of empires or any old game, the colors will be messed up.

This problem can be solved very easily. All you have to do is close explorer.exe before starting your game and then execute it, when you have finished gaming. I'm a lazy person, so I decided to write an application that does this job for me. As I was coding the application I decided to add Dosbox support to the program, because I like DOS games too, and I haven't found a decent front-end for it, so that's how Old games launcher was born.

User Interface

The application is written in C#, the user interface is Windows Forms. I know WPF is way better and it's the future, but I can design and code in Windows Forms much faster, than WPF. In a future version, I might do a full rewrite using WPF, but for now the Windows Forms UI does its job just fine.

I added some internet features to the UI, which allow single click cheat search for the game, Wikipedia lookup, or general Google search.

Data Management

The program stores the game configurations in XML format. The XML is produced with XML serialization. For each game, 3 properties are stored:

  • The Game's name (string)
  • The Game's executable path (string)
  • A Boolean flag indicating that the executable needs to be started trough DosBox

The executable's icon is not stored, it's generated dynamically. If the program is a Dos program, the icon is simply a built-in command line icon, because dos executables don't contain any icons. In the future, if I find a decent icon library for games, I will add an option to have unique icons for dos games.

All management routines are defined in the class GamesManager. This class handles serialization, icon generation, and everything that's related to the game data management. To keep the code simple and efficient, I used LINQ where I could.

DosBox Management

To make thing easier for users, I decided to embed the DosBox installer into my application. This way, they only have to install one program. DosBox is embedded as a zip file among the application's resources. For zip file extraction, I use the SharpZipLib library from Icsharpcode. The library's zip handling routines are also built into the main executable of the program.

All my DosBox related routines are packed into a class named FileManager. This class handles the installation and uninstallation of DosBox. The program installs DosBox into a folder named oldgameslauncher. This folder is created in the user's documents directory. This way, there's no need for administrative privileges to install the program. All files related to Old Games Launcher are located in this folder too, so it's easy to backup whole configurations.

In a future version of a program, I might add an option to use a custom DosBox installation for advanced users.

The extraction code looks like this:

public void InstallDosDox()
{
    try
    {
        MemoryStream ms = new MemoryStream(Properties.Resources.db);
        string basedir = _storageroot + "dosbox";
        string target;
        using (ZipInputStream zi = new ZipInputStream(ms))
        {
            ZipEntry file;
            while ((file = zi.GetNextEntry()) != null)
            {
                target = Path.Combine(basedir, file.Name.Replace('/', '\\'));

                if (file.IsDirectory) Directory.CreateDirectory(target);
                else
                {
                    using (FileStream fs = File.Create(target))
                    {
                        int size;
                        byte[] data = new byte[2048];
                        while ((size = zi.Read(data, 0, data.Length)) > 0)
                        {
                            fs.Write(data, 0, size);
                        }
                    }
                }
            }
        }
    }
    catch (IOException ex)
    {
        MessageBox.Show("DosBox Install failed.\r\n" + 
        ex.Message, "DosBox Installer", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

DdrawHack

Ddraw hack is basically another way to launch DirectDraw applications. At the moment, it's a partial reimplementation of the DirectDraw API in OpenGl. Because it's a partial implementation, it does not work with every game at the moment. But if it works, then there’s no need to close explorer.exe before starting the game. I added an option to install & uninstall DirectDraw hack to the games. But be advised. This is only an experimental feature. It's very likely it will not work at the moment with most of your games.

Starting the Executable

The start-up logic is displayed on the following flowchart. For the waiting part, I used a Timer class which checks every second that the executed program is running or not. If it's not running, that means that it can start back the explorer.exe.

Starting back explorer.exe was a bit tricky. If explorer.exe is not running, and you try to start a Process with the name explorer.exe, you will end up with a Windows Explorer window only. This way, you don't get back the shell. The trick is that you have to set the Process's working directory to your Windows directory.

Points of Interest

A detailed article of the DirectDraw problem on the website of DirectDraw hack can be found at  http://sol.gfxile.net/ddhack/.

Update of 2015-03-14

A slightly updated version with bugfixes and a lot more can be found at https://github.com/webmaster442/old-games-launcher. Originally, I planned to do further improvements to the program, but in the last two years I hadn't had the necessary time to work on it. So feel free to fork the repository and use the code. :)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here