旧游戏启动器






4.74/5 (14投票s)
用 C# 编写的 DirectDraw 游戏启动器和 DosBox 前端
引言
最近,我一直在尝试玩一些不错的旧游戏,例如《暗黑破坏神I》、《星际争霸》、《帝国时代》。这些游戏的问题在于它们使用 DirectDraw
API 进行图形渲染。这很成问题,因为自从 DirectX 10 出现以来,DirectDraw
API 仅被模拟,它们没有真正的硬件加速。
现代 CPU 可以毫无速度问题地计算这些基本图形。但是这些游戏只使用 256 位彩色图形。所以如果你尝试运行《帝国时代》或任何旧游戏,颜色将会出错。
这个问题可以很容易地解决。你只需要在开始游戏之前关闭 explorer.exe,然后在游戏结束后再重新执行它。我是一个懒惰的人,所以我决定编写一个应用程序来为我做这件事。在我编写应用程序时,我决定为该程序添加 Dosbox 支持,因为我也喜欢 DOS 游戏,而且我找不到一个像样的前端,这就是旧游戏启动器诞生的原因。
用户界面
该应用程序是用 C# 编写的,用户界面是 Windows Forms。我知道 WPF 更胜一筹,而且是未来,但相比 WPF,我可以用 Windows Forms 更快地设计和编码。在未来的版本中,我可能会使用 WPF 进行重写,但目前 Windows Forms UI 很好地完成了它的工作。
我在 UI 中添加了一些互联网功能,允许单键点击搜索游戏秘籍、维基百科查找或一般的谷歌搜索。
数据管理
该程序以 XML 格式存储游戏配置。XML 是通过 XML 序列化生成的。对于每个游戏,都会存储 3 个属性
- 游戏名称(
string
) - 游戏可执行文件路径(
string
) - 一个布尔标志,指示可执行文件需要通过 DosBox 启动
可执行文件的图标不存储,它是动态生成的。如果程序是 Dos 程序,图标就是一个内置的命令行图标,因为 dos 可执行文件不包含任何图标。将来,如果我找到一个像样的游戏图标库,我会添加一个选项为 dos 游戏提供独特的图标。
所有管理例程都定义在 GamesManager
类中。此类负责序列化、图标生成以及与游戏数据管理相关的所有内容。为了保持代码的简单和高效,我在可能的情况下使用了 LINQ。
DosBox 管理
为了使用户更容易,我决定将 DosBox 安装程序嵌入到我的应用程序中。这样,他们只需要安装一个程序。DosBox 作为 zip 文件嵌入在应用程序的资源中。对于 zip 文件提取,我使用 Icsharpcode 的 SharpZipLib
库。该库的 zip 处理例程也内置在该程序的 मुख्य 可执行文件中。
我所有的 DosBox 相关例程都打包在一个名为 FileManager
的类中。该类负责 DosBox 的安装和卸载。程序将 DosBox 安装到名为 oldgameslauncher 的文件夹中。该文件夹在用户的文档目录中创建。这样,安装程序无需管理员权限。与 Old Games Launcher 相关的所有文件也位于此文件夹中,因此很容易备份整个配置。
在程序的未来版本中,我可能会为高级用户添加一个使用自定义 DosBox 安装的选项。
提取代码如下所示
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 basically 基本上是启动 DirectDraw
应用程序的另一种方法。目前,它是 OpenGl
中 DirectDraw
API 的部分重新实现。由于它是部分实现,目前并非适用于所有游戏。但如果它有效,那么在启动游戏之前就不需要关闭 explorer.exe。我添加了一个选项来安装和卸载游戏的 DirectDraw
hack。但请注意。这只是一个实验性功能。目前很可能对您的大多数游戏不起作用。
启动可执行文件
启动逻辑显示在以下流程图中。对于等待部分,我使用了一个 Timer
类,该类每秒检查已执行的程序是否正在运行。如果它没有运行,则表示它可以重新启动 explorer.exe。
重新启动 explorer.exe 有点棘手。如果 explorer.exe 未运行,而您尝试启动一个名为 explorer.exe 的进程,您最终只会得到一个 Windows Explorer 窗口。这样,您就无法恢复 shell。诀窍在于您必须将进程的工作目录设置为您的 Windows 目录。
关注点
在 DirectDraw
hack 的网站上可以找到关于 DirectDraw
问题的详细文章,地址为 http://sol.gfxile.net/ddhack/。
2015-03-14 更新
可以在 https://github.com/webmaster442/old-games-launcher 找到一个稍有更新的版本,其中包含错误修复和更多内容。最初,我计划对程序进行进一步改进,但在过去两年里,我没有足够的时间来处理它。因此,欢迎您 fork 该存储库并使用代码。 :)