为什么存在WinQuake以及它的工作原理
Why WinQuake exists and how it works

原始链接: https://fabiensanglard.net/winquake/index.html

## WinQuake的故事:它为什么存在以及它是如何工作的 WinQuake是为了解决在Windows 95上运行原始*Quake*时遇到的性能问题和技术限制而产生的。虽然*quake.exe*可以在DOS和Windows 95上运行,但在Windows下会因虚拟化开销而导致性能下降25%。访问Windows的TCP/IP堆栈也需要一个复杂的解决方法。重要的是,*quake.exe*由于与虚拟DOS机器不兼容,在Windows NT上表现不佳。 *Winquake.exe*旨在通过提供对Windows API(如Winsock)的直接访问,并利用各种“后端”来处理输入、音频和视频,来解决这些问题。不同的模式——如“max”、“fastvid”和“safe”——配置这些后端以实现最佳性能,用速度换取功能。 *WinQuake*灵活性的核心在于它的视频后端,从安全的GDI渲染到利用SciTech的MegaGraph Graphics Library (MGL)和DirectDraw的高性能选项不等。MGL及其“WinDirect”技术允许绕过标准的Windows图形界面,直接访问硬件。 最终,*WinQuake*通常可以匹配甚至超过原始DOS版本的性能,提供显著改进的体验,并展示了对向后兼容性的承诺,即使在现代Windows系统上仍然存在。

Hacker News 新闻 | 过去 | 评论 | 提问 | 展示 | 工作 | 提交 登录 为什么WinQuake存在以及它的工作原理 (fabiensanglard.net) 73 分,由 wicket 发表于 7 小时前 | 隐藏 | 过去 | 收藏 | 2 条评论 progmetaldev 1 小时前 | 下一个 [–] 对于我们这些在 Quake 发布时就喜欢它的人来说,这是一篇很好的文章。在尝试同时运行 Quake 和 Windows 95 的时代,调整你的性能是一项巨大的任务。我开始玩 Quake 是因为它有许多可用的 MAP 工具,以及多人游戏方面,以前在没有局域网的情况下很难让多人游戏正常工作。回复 01HNNWZ0MV43FF 26 分钟前 | 上一个 [–] 这不就是 SDL 旨在抽象的内容吗?虽然我想 SDL 更多地针对 Windows / Linux 的差异,而不是 Windows / Windows 的差异。回复 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:
相关文章

原文
Why WinQuake exists and how it works

Dec 3, 2025

Why WinQuake exists and how it works


When I took a look at the history of Quake binaries, they all made sense to me. quake.exe was the original release, able to run on DOS and Windows 95. Then came vquake.exe to support the hardware accelerated chip Vérité 1000. Later, glquake.exe generalized hardware acceleration to any vendor providing OpenGL drivers. And to revolutionize Internet deathmatch, id Software released QuakeWorld server and client (qwsv.exe and qwcl.exe).

However, I could not figure out the point of winquake.exe. Until now. Here is what I understood and a little bit of a dive into how it works.

Quake.exe performance


quake.exe runs on both DOS and Windows 95 but how well does it perform? A quick benchmark on my Pentium MMX 233MHz, Matrox Mystique PC (320x200 with 101 screen size) and sound on, showed the following numbers.

Configuration Framerate
quake.exe started from DOS 48 fps
quake.exe started from Windows 95 38 fps

So "framerate" is the beginning of an answer to justify the existence of WinQuake. quake.exe running from Windows 95 is roughly 25% slower than the same binary started from DOS. And that is to be expected. Windows 95 runs DOS applications in a virtual machine ("DOS BOX"), where memory access, interrupts, and signals are virtualized, which incurs overhead.

Another element of the answer comes from Quake Chunnel. quake.exe can access Windows 95 TCP/IP stack, but only via a convoluted tech from Mpath to bridge a "DOS BOX" to win32 dlls. By having a win32-only application, id Software had guaranteed direct access to winsock.dll.

Last but not least, id Software really wanted Quake to work on Windows NT. Despite their best efforts, the people at DJGPP could not make their DPMI client in quake.exe compatible with the NT Virtual DOS Machine (NTVDM).

Near pointers don't work under NT - which was a huge disappointment to iD and generated some conference calls to Microsoft.

How winquake.exe works


A fun way to start exploring is to first read WQREADME.TXT and then take a look at all the modes available in winquake.exe. They are configured with the script wq.bat.

Options for running WinQuake:
 wq max:      all features on, but doesn't work on all systems
 wq fast:     maximum speed, but doesn't work on all systems
 wq fastvid:  maximum video speed, but safer, probably slower sound
 wq fastsnd:  maximum sound speed, but safer, probably slower video
 wq safe:     very likely to run, but may be slower
 wq verysafe: almost sure to run, but probably slower, and no sound

Here are the numbers I got for each mode, still with the same Pentium MMX 233MHz machine and same configuration.

Configuration Framerate
wq max 42.4 fps 
wq fast 41.8 fps 
wq fastvid 45.0 fps 
wq fastsnd 41.8 fps 
wq safe 45.0 fps 
wq verysafe 40.0 fps*

Impressive. winquake.exe managed to bring up the framerate within 6% of quake.exe running on DOS. Mission accomplished. But how does it works?

winQuake.exe backends


Each "mode" is configured via command-line flags. This part reveals there are three types of backend for input controls, audio, and video.

max      winquake                                                              -dinput
fast     winquake 
fastvid  winquake -wavonly
fastsnd  winquake          -nodirectdraw -nowindirect
safe     winquake -wavonly -nodirectdraw -nowindirect 
verysafe winquake                                     -dibonly -nosound -nojoy

Amusingly, the mode that provides the highest framerate, fastvid keeps everything default but disables an audio backend!

"fastvid" was also the name of a tool to fix the Pentium Pro abysmal video write speed on chipset that shipped with buggy "Write Posting". The option in qw.bat has nothing to do with it.

Audio backends


WinQuake can send its sound effects (the music comes from CD tracks) using two audio backends (with -nosound disables sound effects altogether).

The two backends are DirectSound (dsound.h from DirectX) and what id calls wave sound which is in fact winmm.h, the Windows MultiMedia audio API, dating back to Windows 3.1.

If DirectSound is available, WinQuake uses it to provide the lowest latency. However this backend has a higher impact on the CPU and results in 10% lower framerate. With -wavonly, users can force usage of WinMM which results in higher latency but higher framerate.

Input Control backends


To read user inputs, WinQuake uses either DirectInput (dinput.h from DirectX) or the legacy Windows API winuser.h.

By default WinQuake uses winuser.h but usage of DirectInput can be requested via -dinput for slightly smoother motion and responsiveness to fast spinning motions. I suspect it was not enabled by default for cases where DirectX was not installed or perhaps fear of driver problems.

Joystick inputs are handled with joystickapi.h. Likewise, it seems drivers may not have been stable since id provided a way to disable it with -nojoy.

Video backends


The part that was the most interesting to me was the video backends. WinQuake can operate in five modes using GDI, VGA, VESA, Accelerated VESA, or DirectDraw.

DIB video backend


The Graphics Device Interface (GDI) (wingdi.h) is the foundation to render anything on the desktop in Windows 95. Applications usually did not use it directly but instead called winuser.h (which in turns used low-level wingdi.h).

WinQuake can render to a Device-Independent Bitmaps (DIB) which is a surface to be blitted towards a window though GDI. The surface can be of any dimension so there are no "display mode" to detect here, WinQuake hardcodes its DIB modes to square-pixel resolutions 320x240, 640x480, and 800x600.

Because it is using Windows "by the book", DIB mode is the safest mode that should always work. It is also the slowest way to render to the screen because WinQuake first renders to a DIB that is then sent to the GDI and then sent to the video card.

While slower, it is not devoid of hardware acceleration. Many graphic cards wanting to perform well under Windows 95 had hardware acceleration implementation of crucial functions such as bitBlt.

Finally, DIB mode is the only one able to render in "windowed" mode. Every other mode takes over and renders in "fullscreen" mode. Note that DIB can also render in pseudo-full screen if WinQuake is started with dibonly but this is "faked" with a borderless window covering the whole screen.

SciTech's Multi-platform Graphics Library (MGL)


For everything not DIB, WinQuake uses SciTech's MegaGraph Graphics Library. It was a rather expensive lib ($499 in 1997, $1,000 in 2025)[2] but well worth its price because it brought order into the chaos that was the world of video systems in 1997 if a game operated outside GDI.

WinQuake could find itself having to deal with the following types of video systems.

1. VBEAF        : VESA Accelerator Function
2. VBE2         : VESA Linear Frame Buffer for direct to VRAM write/read.
3. DirectDraw   : Only available if DirectX is installed.
4. StandardVGA  : That good ol' VGA video mode.

When it starts, WinQuake registers the drivers it wants MGL to load (see registerAllDispDrivers). MGL then lists all supported resolutions and pick the highest performance drivers to access each of them (in the order list above).

void registerAllDispDrivers(void) {
  /* Even though these driver require WinDirect, we register
   * them so that they will still be available even if DirectDraw
   * is present and the user has disabled the high performance
   * WinDirect modes.
   */
  MGL_registerDriver(MGL_VGA8NAME,VGA8_driver);

  if (useWinDirect){
    MGL_registerDriver(MGL_LINEAR8NAME,LINEAR8_driver);
    if (!COM_CheckParm ("-novbeaf"))
      MGL_registerDriver(MGL_ACCEL8NAME,ACCEL8_driver);
  }

  if (useDirectDraw) {
    MGL_registerDriver(MGL_DDRAW8NAME,DDRAW8_driver);
  }
}

The list of modes and which driver was selected by MGL is available via the command vid_describemodes in Quake console. In the screenshot below, we can see almost the full house of drivers VGA8.DRV, DDRAW.DRV, LINEAR8.DRV, and the windowed DIB modes.

Quake fast mode.
Quake dibonly mode.
Quake nowindirect mode.
Quake nodirectdraw mode.

I had never heard of VBE/AF before reading MGL source code. As far as I understand, it never gained much traction and few vendors wrote drivers to support it.

Many games used MGL: WinQuake, Hexen II, Grand Theft Auto, Maui Mallard in Cold Shadow, Total Mayhem, Balls of Steel.

DirectDraw video system


Microsoft was very much aware that GDI was fine for applications but not enough for video games. Already in Windows 3.1 they had released a game developer SDK called WinG to give a more direct fullscreen access to the screen. The second version of WinG was renamed DirectX and contained the 2D fullscreen API which they called DirectDraw.

Although safer and more reliable, Microsoft Windows imposed many restrictions on applications. One result of this situation was that games, and other high-performance graphics applications, could no longer access the hardware resources directly in order to maximize performance and expand functionalities. For several years game programmers continued to exercise the craft in DOS, and Windows users had to switch to the DOS mode to run games, simulations, and other graphics programs. The resulting situation implied a major contradiction: a graphical operating system in which graphics applications would execute with marginal performance

The first effort in this direction was a product named WinG, in reference to Windows for Games. WinG was first made available in 1994 and it required Win32 in Windows 3.1. Its main feature is that WinG enabled the game programmer to rapidly transfer bitmaps from system memory into video memory. This made possible the creation of Windows games that executed with much better performance.

Microsoft renamed the new version of the Game SDK, calling it DirectX 2. Other versions later released were named DirectX 3, DirectX 5, DirectX 6, and currently, DirectX 7.

- Feng Yuan, "Windows Graphics Programming Win32 GDI and DirectDraw"

In terms of performance, DirectDraw was a step up from GDI but it was also not guaranteed to work due to driver bugs or if the user had not installed DirectX. It can be disabled with nodirectdraw.

WinDirect video system


Readers may have picked up on something written earlier that was blatantly wrong. Direct access to the hardware is forbidden to Win32 applications. So how is MGL able to bypass GDI/DirectDraw and directly hit VBEAF, VBE, and VGA?

That is possible thanks to the secret tech from SciTech called WinDirect. How it works is explained in SciTech MGL Reference Guide v4.pdf.

What is WinDirect?

A key component of the SciTech MGL, WinDirect is a runtime package for DOS and Windows 95 that provides direct access to the display hardware for both 16 and 32-bit applications. Traditionally Windows applications have had to perform all graphics output using the standard Graphics Device Interface (GDI). Although the GDI is very extensive and powerful, it is also not particularly fast for the sort of graphics that real time applications like interactive video games require.

WinDirect breaks this barrier by allowing high performance applications to shut down the normal GDI interface, and to take over the entire graphics display hardware just like you would normally do under DOS. Once GDI has been shut down, interactive graphics applications can re-program the display controller and write directly to video memory. A WinDirect application can program any standard VGA graphics mode such as 320x200x256, it can re-program the controller and run standard VGA ModeX style graphics, or it can call the standard VESA BIOS services to run high resolution SuperVGA graphics.

- MGL v4 Programmer Guide[3]

MGL v4 programmer guide, is a treasure strove of information. If, like me, you wondered what were these WDIR32.DLL and WDIR16.DLL libraries that came with WinQuake, the doc mentions them (WinDIRect). Likewise, the doc describes PMPRO16.DLL and PMPRO32.DLL as DOS extender independent API for protected mode services. Michael Abrash's Zen Timer is also mentioned in there :)!

WinQuake source code does not include MGL. Only the headers and a pre-compiled 32-bit MGLLT.LIB (MGL Lite) are provided to allow compilation. SciTech did eventually publish the source in 2000[4] but it is no longer available. What was uploaded on GitHub[5] is v5 which by then had dramatically changed (e.g: WinDirect was gone).

Luckily a kind soul has mirrored MGL v4. If you want to do your own digging, install mglb405.exe and mgls405.exe. Or just download my installation, src.rar.

Putting it all together


Overall, winquake.exe was often able to find a fast rendering path, either through DirectDraw or WinDirect. The fallback to DIB mode was not ideal but still a win compared to quake.exe. Add to that the ability to select a sound backend to optimize for framerate or audio latency and the result was a damn good experience that completely justified the effort.

More than 30 years later, you can still run winquake.exe on Windows 11. Fullscreen does not support widescreen but the windowed mode still works flawlessly. As much as Microsoft has been questionable lately, their commitment to backward compatibility is impressive.

References



*
联系我们 contact @ memedata.com