AZHP is an open source implementation of Electronic Arts' Need For Speed: Hot Pursuit from 1998 and the Modern Patch v1.6.1.
There are multiple goals this project tries to achieve:
- Learn how games were made in an era when things had to be done in the code, and not through fancy game engines like today.
- Have a fully playable game implemented end-to-end, including resource management, audio, and video rendering, as well as support of large screen resolutions.
- Eventually, to support 64-bit compilation for modern systems, and provide an avenue for development of modern renderer implementations such as DirectX or Vulkan.
- Also, eventually, to support modern input devices that do not comply with DirectInput, and even port to Linux or Mac.
The original game was compiled by Watcom C/C++ compiler, it contains the following sting: WATCOM C/C++32 Run-Time system. (c) Copyright by WATCOM International Corp. 1988-1995. All rights reserved.
.
Examination of the game files, indicates that three calling conventions were used.
- The game was compiled with Watcom compiler, and uses watcom calling convention internally and stdcall to call renderer and sound modules.
- The sound module was compiled with Watcom compiler,
eacsnd.dll
, uses watcom calling concention internally and exports methods with stdcall convention. - The original DirectX 5 renderers were also compiled with Watcom compiler with watcom calling convention internally and stdcall for callbacks to the game itself.
In order to be able to run the code not only in the modern operating systems, but also in legacy environments, such as Windows XP, the code base has to abstain from usage of modern C++ language features.
Modern Visual Studio makes the binary dependent on modern runtime libraries that are not available in the legacy systems, therefore the game won't work. In order to make the code work on legacy systems please see detailed instructions on compatibility.
The sound system module, eacsnd.dll
, is a module that is used by the game to manage sound and sound effects playback. The module is only responsible for playback, and has no insight into anything else. The module calls functions back from the main game to acquire data, signal events, or log messages.
Based on the structure sizes, the original module uses DirectSound version prior to 7, since no other inputs or hints were given, I selected version 5 for the project, and it aligns well with the release dates.
The original game requires the sound system to be present, no graceful error handling is happening if the file is missing. Moreover, the game mostly expects the module to be valid as well, it does not perform checks whether all required methods were imported correctly, and just assumes they were.
One more thing regarding the callbacks, some are required to be called during the Serve
call, without it the game goes into endless loop when player attempts to start a race.
The renderer modules were implemented with minor changes, such as omission of write-only variables, making calls to functions when result is not used, as well as addition of configuration file and reading values from it, which is useful in a few cases.
The original game shipped with two DirectX 5 renderers with slightly different design and capabilities. I added all of them as well as the patched version from the modern patch for completeness. Unfortunately DirectX 5 is so far away in hte past that I was not able to make this renderer work without some tweaks here and there, and it will require major changes in the game itself so that 16-bit rendering is not used. On my test environments I ran into an error where SetDisplayMode fails to set resolution in 16-bit mode, this error leads to renderer not creating surfaces, which leads to inability to create a Direct3D device from which one cannot recover gracefuly. Having said all this, it is great that other renderers are available and do work. Here is the outline of DirectX 5 renderers:
- DirectX 5 3DS is a renderer based on the orignal unversioned file
d3da.dll
that came with the original game in 1998 and was located in3dSetup
folder. Even though it was capable to render the game it was not intended to do so. - DirectX 5 A is a renderer based on the orignal file
d3da.dll
version: 1998.08.10.1148 (6552.8.16.4424) that came with the original game in 1998. - DirectX 5 M is a a renderer based on the DirectX 5 renderer
dx5a.dll
from the modern patch. Since the patch is a binarry patch to theDirectX 5 A
, I untangled it as well, for completeness.
The original game had no DirectX 6 renderer, thus the one you see here is a renderer from the modern patch, which in its turn is based on file d3da.dll
version: 1999.01.15.1121 (6553.1.21.4385) that came with Need For Speed: High Stakes in 1999. See AutoZone High Stakes DirectX 6 3DS renderer details for additional information.
The original game had no DirectX 7 renderer, thus the one you see here is a renderer from the modern patch, which in its turn is based on file d3da.dll
version: 2001.01.18.1651 (8193.1.24.5713) that came with Need For Speed: High Stakes in 2001 with the patch 4.50. See AutoZone High Stakes DirectX 7 A renderer details for additional information.
- My Abandonware for providing Need For Speed: Hot Pursuit.
- VEG.BY for providing modern patch for the game.
- GamePressure for providing demo version of the game.
- This is not a complete game. Please purchase software you like!
- The source code in this repository is mostly produced by reverse engineering the original binaries. There are a couple of exceptions for reverse engineering under DMCA -- documentation, interoperability, fair use. See goals section for the interoperability and fair use cases. The documentation is needed to support those. Also please see an article about software preservation.
- Need For Speed, Need For Speed: High Stakes, DirectX, OpenGL, Vulkan, and others are trademarks of their respective owners.