让我们像 1997 年那样编译 Quake
速览
本文介绍了如何重现 1997 年编译经典第一人称射击游戏 Quake 的过程。通过回顾当年的构建环境与工具链,展示了复古计算的魅力。这一过程对于理解早期图形渲染和底层编程具有技术参考价值。
AI 深度解读
让我们像 1997 年那样编译 Quake
背景
1997 年是计算机图形学与游戏开发史上的一个转折点。id Software 凭借《雷神之锤》(Quake)确立了 3D 游戏引擎的新标准。然而,随着项目的推进,开发环境也在不断演变。
据 John Carmack 回忆,Quake 的最初可执行文件(quake.exe 和 vquake.exe)是在运行 NeXT 系统的 HP 712-60 工作站上编程,并通过在 DEC Alpha Server 2100A 上运行的 DJGPP 进行交叉编译的。1996 年 6 月,尽管游戏已经发售,但 id Software 因 NeXT 平台的停滞不前而决定切换开发栈。随后,他们转向了运行 Windows NT 的 Intergraph 硬件。
接下来的版本,包括 winquake.exe、glquake.exe 以及 QuakeWorld(qwcl.exe 和 qwsv.exe),均是在 Windows NT 环境下使用 Visual C++ 4.X 开发并编译的。
本文旨在重现 1997 年构建 Quake Win32 二进制文件的历史体验,通过详细的步骤指导,让现代开发者能够穿越回那个充满挑战与魅力的软件开发生态。
核心内容
环境选择:复古开发的四种路径
为了达到不同程度的历史准确性,作者提供了四种构建环境选项:
- 寻找 Intergraph RealizM Dual P6-200MHz 工作站:难度极高,几乎不可能找到。
- 寻找双 Pentium Pro 机器:难度依然很大,但找到 W6-LI 型号是可行的。
- 使用典型的 90 年代末 PC:即所谓的“Quake PC”,这是最接近普通玩家体验的方式。
- 使用 Oracle VirtualBox 创建虚拟机:作者实际测试了此方案,分别在 Windows 98 SE 和 Windows NT 4.0 环境下运行。
安装 Windows NT 4.0
- 安装过程:由于光盘可引导,安装过程相对简单,耗时约 30 分钟。
- 界面特色:Windows NT 的启动屏幕极简主义,自豪地显示检测到的 CPU 数量(Windows 95/98 仅支持单 CPU)和内存大小,没有任何花哨的动画。
- SMP 支持陷阱:向系统添加第二个 CPU 后,Windows NT 不会自动检测。必须重新安装操作系统以获取支持对称多处理(SMP)的 HAL(硬件抽象层)。在 W6-LI 主板上,不仅需要添加另一颗 Pentium Pro,还需要加装稳压器。
- UI 风格:Windows NT 4 使用了与 Windows 9X 相同的 UI 主题。相比之下,早期的 Windows NT 3 使用与 Windows 3.1 相同的 UI 元素,视觉效果较差。
安装 Visual C++ 6.0
虽然 Quake 的 Win32 版本最初是用 Visual C++ 4.X 编码的(1996 年中最新),但到 1999 年项目已迁移至 Visual C++ 6。
- 获取资源:由于互联网尚未普及,软件通常带有产品 ID 以防止盗版。可以通过 Internet Archive 或 winworldpc.com 找到安装光盘镜像。
- 安装界面异常:安装程序界面显得空旷,进度条位置尴尬。这是因为 Microsoft 未预料到开发者会在 1280x1024 的高分辨率(当时 21 英寸显示器常见分辨率)下运行,该界面仅在 640x480 或 800x600 分辨率下显示正常。
- IDE 的崛起:安装过程展示了“Visual Studio”概念的雏形,将多种开发环境整合在一起,随后成为微软统治级的 IDE。
获取源代码与构建陷阱
- 严禁 FTP 传输:切勿从 GitHub 获取源码或通过 FTP 传输文件。这会导致工作区文件(
.dsw)格式错误,导致 VC++6 无法解析项目,且不会报错,只会显示空白,浪费大量调试时间。 - 正确获取方式:应下载
q1source.zip。该文件原位于 id Software 的 FTP 服务器,现由 Jason Brownless 维护的 Quake Official Archive 提供。 - 文件传输:在虚拟机中可通过拖放传输,或使用 Quick ‘n Easy FTP Server(兼容 9X/NT)。
- 解压工具:需使用 WinRar v2.50,该版本在 9X/NT 上运行良好。
- 打开项目:在 VC++6 中选择“Open Workspace”,然后选择
WinQuake.dsw。注意区分现代 Visual Studio 的.sln/.vcxproj与 VC++6 的.dsp/.dsw格式。
解决构建失败:汇编器与 Service Pack
点击“Rebuild All”后,构建会失败,因为 VC++6 无法汇编包含 Michael Abrash 手写优化代码的 .s 文件。这些文件依赖于 ml.exe 汇编器,该汇编器包含在 VC++6 Processor Pack 中。
- 安装 Service Pack 5 (SP5):
- 直接运行
setupsp5.exe会失败。 - 必须先安装 MDAC 2.5。无需单独下载,只需运行
vs6sp5.exe解压后文件夹内的mdac_typ.exe即可。 - 再次运行
setupsp5.exe即可成功安装。整个过程如同《猴岛小英雄》解谜游戏般令人费解,充满了 90 年代的典型特征。
- 直接运行
- 安装 Processor Pack:
- 安装 VC++6 Processor Pack (
vcpp5.exe)。 - 确认 VC++6 的 bin 文件夹中出现了
ml.exe(与cl.exe并列)。 - 重新打开项目并再次执行“Rebuild All”,构建成功。
- 安装 VC++6 Processor Pack (
运行游戏
构建成功后,需复制 PmProXX.dll、WdirXX.dll 以及 id1 文件夹,游戏即可启动。甚至可以使用 QSpy 工具运行和调试 QuakeWorld。
关键要点
- 历史环境的复杂性:90 年代的软件开发环境远比现代复杂,涉及交叉编译、特定的硬件依赖(如 Intergraph 工作站)以及复杂的操作系统配置(如 Windows NT 的 SMP 支持)。
- 文件格式的兼容性陷阱:通过 FTP 或现代工具传输源代码可能导致工作区文件(
.dsw)损坏,这是当时开发者常见的痛点。 - 依赖链的脆弱性:Visual C++ 6.0 的构建依赖于特定的汇编器(
ml.exe)和 Service Pack 补丁,且补丁安装顺序有严格要求(先 MDAC 2.5 再 SP5),体现了早期软件生态的不成熟。 - 分辨率适配问题:当时的软件界面设计未考虑高分辨率显示器,导致在 1280x1024 分辨率下安装界面显示异常。
- 开源与归档的重要性:Quake 源码的保存依赖于社区维护的官方档案(Quake Official Archive),而非现代意义上的 GitHub 托管,强调了数字遗产保护的价值。
- IDE 的演进:Visual C++ 6.0 在当时提供了“Go to definition”、断点、堆栈跟踪等强大功能,尽管缺乏智能感知(Intellisense),但已是当时的梦幻工具。
意义与影响
这篇文章不仅是一份技术教程,更是一次对软件开发生态演变的深度回顾。它揭示了从 90 年代中期到后期,开发工具链从 Unix/NeXT 环境向 Windows/Visual Studio 环境迁移的历史必然性。
对于现代开发者而言,这种“复古编译”体验具有多重意义:
- 理解底层原理:通过手动处理汇编文件、配置 HAL 和解决依赖问题,开发者能更深刻地理解
