January 15, 2023
TL;DR – this article is longer than any other blog post I’ve published to date, so be ready for a long read. If you aren’t currently
interested in a deep dive through the game’s history, internals and fixes, scroll down to the Changelog and download
section for a download link.
- Introduction
- Chapter 1: In search of a perfect executable
- Chapter 2: Regional releases and their oddities
- Chapter 3: Fixes, so many fixes
- Chapter 4: The perfect remaster – adding an HD interface
- Chapter 5: Merging regional releases together
- Changelog and download
- Credits and acknowledgments
October 2022 was the 20th anniversary of Colin McRae Rally 3.
A little over two months later, I’m happy to reveal the biggest SilentPatch since GTA San Andreas.
In this release, developed together with Bekoha, we deliver more than just a set of fixes – with full
widescreen support, numerous compatibility fixes, new technical features, Quality of Life improvements, and a scratch-made high definition
UI optimized for 4K displays, we bring an experience comparable to an unofficial remaster of this classic 2002 rally game.
Originally, this project didn’t start as a SilentPatch. Instead, I only intended to document the different releases of the game,
but given the anniversary timing and the attention Colin McRae Rally 3 received around that time, it was hard to pass on an opportunity
to give it a new life, especially once Bekoha expressed interest in retouching the game’s fonts and UI.
For this reason, this blog post details the entire journey – from scavenging for different versions of the game,
documenting them, through the process of fixing the game, and finally merging regional releases together.
Feel free to take a break between chapters, as it’s going to be a lot – it’s the longest post published on my blog to date.
This post may get technical at times, but don’t get discouraged; I intend it to be clear and informative for everyone – players, game developers, and reverse engineers.
But first, a few words about the game for the uninitiated. Colin McRae Rally 3 is a racing game from Codemasters, released originally
for the PS2 and Xbox on October 25, 2002, later ported to PC by Six by Nine Ltd.
and released there on June 13, 2003.1 It was received well and was succeeded by two more sequels in 2003 and 2004
before the franchise moved on to a Colin McRae DiRT series.
Unlike Colin McRae Rally 2.0, where the game shined on PC, CMR3 was an enhanced console port. Nonetheless, I have fond memories from playing
this game as a kid (although they’ve blurred together with memories from CMR04 and CMR2005). Curiously, back in the day,
this was considered a sub-par port,
and some people did not enjoy the long wait for the PC port, especially since by then CMR04 was just a few months away from release.
I find this comment the most amusing…
Unfortunately it’s a sign of the times and it’s sad to see Codemaster’s, once big supporter’s of the PC, becoming member’s of the lazy developer’s club.
…since it sounds like something that could have been said online in July 2022, not July 2003 – I guess some things never change 😜
It’s commonly known that DRM on retail discs sucked. The three leading DRM solutions all came with a varying level of breakage,
and these days, two of them are intentionally disabled by Windows; furthermore, one of those DRM solutions is so contrived
it can make a Windows 10/11 machine unbootable (shout out to TOCA Race Driver 2 & 3). Much like I did
for the TOCA Race Driver games, I wanted to know if the trilogy
of later Colin McRae Rally games were all released DRM-free somewhere:
- Colin McRae Rally 04 is easy – much like TOCA Race Driver and TOCA Race Driver 2, it was re-released in Italy by FX Interactive,
opting for “physical” DRM (ring on the disc’s surface to make copying unreliable and time consuming) instead of a software solution. - Colin McRae Rally 2005 was released DRM-free on GOG.com, so even though the game has since been delisted, getting a hold of the DRM-free executable is not hard.
- This left only Colin McRae Rally 3 in an unknown state, as at that time all CMR3 discs submitted to Redump had SecuROM DRM – except for the Polish release.
I initially brushed off that hint, since I thought this listing is incomplete or incorrect. After all, I own a Polish CMR3 release from back in the day – it uses SafeDisc2,
making it impossible to launch without workarounds or a no-CD executable, and it comes on three discs, while this listing only had two.
However, turns out that this wasn’t an error, as a later re-release of the game did indeed come on 2 CDs:
Anyone around with this specific version of Colin McRae Rally 3? I suspect this 2x CD re-release (compared to a 3x CD original) might be DRM-free, or at least might contain just a simple CD check. pic.twitter.com/n7MQIAuTmJ
— Silent (@__silent_) October 8, 2022
With the help of Krusantusz, I got access to this executable for analysis. While it indeed is DRM-free, its usability with assets of the “international” version is
limited – with the range of issues ranging from a hardcoded French co-driver (replaced with Polish in the actual release)…
Turns out this release is indeed fully DRM-free, and its executable also works with an English version! Well, almost, and to get what’s the catch you need to watch with sound on.
I hope it’s patchable, as DRM-free exes > no-CD exes all the way https://t.co/6bABq0Atvy pic.twitter.com/tinKdKicbR
— Silent (@__silent_) October 8, 2022
…various UI issues…
…through crashes on various screens, e.g. Telemetry and Controls. While salvageable, this means that the Polish release has received a non-trivial amount of code changes.
Shortly after that, I also bought my own second hand copy of the eXtra Klasyka release, so now I’m a proud owner of two CMR3 PL copies:
If the rabbit hole of different versions ended here, this would have been a story of how I created an international DRM-free executable by “internationalizing” the Polish one
and removing CD Projekt’s modifications to it (more on that later). There is one more version, though – CMR3 was also re-released in Germany on a single DVD. As SecuROM worked with DVDs
just fine, we expected this release to have DRM identical to the original – however, Memorix101 proved us wrong.
Together with RibShark we tracked down a copy for sale and submitted its metadata to Redump – at which point it became clear
that this re-release is so late, its disc was mastered after the release of Colin McRae Rally 2005!
At this point, I’ve already been “internationalizing” the Polish executable, so this work was technically rendered useless (for now). Regardless, thanks to the German version,
we got The Perfect CMR3 Version we wanted – an easy to install, DRM-free, future proof release that ensures the game remains accessible indefinitely.
My initial goal was done.
Note: Although the DVD version was only sold in Germany, its content is identical to the international release,
so I don’t consider it a regional release per se.
Polish (3 CD) release
As mentioned earlier, the Polish release is more than a straightforward text and speech translation. Aside from making Polish the only
language in the game, CD Projekt (or Codemasters) introduced several changes to the international version, localizing the game further:
- Localized onscreen keyboard and keyboard typing – the international version displays a basic keyboard regardless of a selected in-game language:
These screenshots are from a patched game, but you get the idea.
- Menu cubes received new graphics to match Polish wording:
Polish cubes are exceptionally rude.
- The Secrets screen was modified to refer to CD Projekt’s resources rather than the Codemasters’ ones – this is what resulted in a previously shown “Call your Germany”
issue if a PL executable is used with English localization:
- By the way, have you noticed how Polish fonts are spaced further apart than international ones? Odd change, but I assume they had a reason to do so.
- Polish introduces 40 new localization strings for texts that were previously hardcoded to English. This is what caused an unpatched PL executable to crash with English localization.
- As other languages have been removed, the Language screen is renamed to “Co-driver’s voice” and gives you a choice between Nicky Grist, the original English co-driver,
and Janusz Kulig, the voice of a popular Polish rally driver.
Polish (2 CD) re-release
Around a year after the original release, Colin McRae Rally 3 was re-released in Poland under an eXtra Klasyka label (as you may have noticed above).
Aside from being completely DRM-free, it also ships on 2 discs instead of 3. While I initially thought this is solely due to better compression,
this isn’t the case – the changes in this release are:
- The removal of Nicky Grist as a selectable co-driver
- The change of the Polish co-driver’s voice from Janusz Kulig to Janusz Wituch
I couldn’t find any in-game comparisons online other than the Polish dubbing wiki,
so here is one:
The removal of Nicky Grist explains why the game was now shipped on 2 CDs – while localized co-drivers only use one-shot samples that
are played at specific triggers during the stage, Nicky Grist’s pace notes are full audio recordings, created for each stage individually.
This makes Grist’s notes sound much more natural than the other co-drivers, at the cost of much higher file size – while each localized
co-driver is typically between 1.5 MB and 2 MB in size, Grist’s pace notes are 435 MB!
What about Janusz Kulig, though? We will of course never know for sure if this change was dictated by licensing,
but one more plausible reason may be a little clearer for those familiar with the Polish rallying scene.
For those unfamiliar, it’s best to show it on a timeline of what I think has happened:
- June 26, 2003 – The original PL Colin McRae Rally 3 featuring Janusz Kulig gets released.3
- February 13, 2004 – Janusz Kulig, a Polish rally driver, dies in a road accident after his car collides with a train on a level crossing.4
- After April 2004 – Colin McRae Rally 3 gets re-released in eXtra Klasyka, featuring Janusz Wituch – a prolific voice actor, also starring
in TOCA Race Driver and TOCA Race Driver 2.3 5
While there is no definite proof to support that claim, it seems reasonably likely that CD Projekt quickly opted for a new co-driver after Kulig’s death.
Their choice to feature Janusz Wituch may or may not have been related to the fact he was presumably recording lines for TOCA Race Driver 2 around that time – as
it was released in Poland on June 24, 2004.6
Czech release
A Czech release, published by CD Projekt, also exists – albeit the details on it are sparse:
Albeit much like the Polish release it was released by CD Projekt in eXtra Klasika, I don’t know if it ever was released outside of it (it likely was, though).
From the technical side, this Czech release is much less interesting than the Polish one – compiled on August 31, 2004,
it’s not a special version but rather a translated international release replacing Spanish with Czech. None of the changes from CD Projekt are present in this release,
although it’s clear that it must have been translated from Polish, not from English – as the Czech translation file contains (now unused) strings introduced in the Polish release!
That said, there is something interesting about this release, and I only noticed it during the final tests of SilentPatch – although the contents of the Czech
executable appear to be identical to the international executable, it has at least one unique UI bug, not present anywhere else! I have no idea how this happened,
but the results screens for time trials are completely broken in this release.7
I’m disappointed, as this screen was not even changed for the localized release – it’s a completely unwarranted regression.
In this section, I want to highlight the most interesting and unusual improvements present in the patch. This is not a full changelog – for that,
refer to Changelog and download.
Fixes & improvements
Console versions of CMR3 included a Widescreen option in Graphics Options, switching the aspect ratio from 4:3 to 16:9. While this option is gone from the PC versions,
it’s still functional – it’s just that this option is underwhelming to begin with (also in the console versions), as it only corrects the 3D aspect ratio,
and the only UI element it corrects is the co-driver arrow. That said, it’s not the worst, as it opts to fix the aspect ratio by increasing the horizontal FOV,
rather than by shrinking it vertically:
Curiously, the PC demo did list 16:9 resolutions, unlike the full version of the game – but unlike the console versions, it is Vert-;
the co-driver arrow also appears to be broken. In my opinion, it’s possible that because of issues like this it was decided that the full
version should limit the available options:
SilentPatch doesn’t rely on the stock widescreen support at all – instead, much like in
SilentPatch for Colin McRae Rally 2.0, I scale the game to arbitrary aspect ratios.
The entire UI and menus are positioned dynamically, ensuring that everything looks consistent regardless of resolution. This required an obscene amount of work,
as literally all the UI and menus had their layouts designed with a constant 4:3 aspect ratio – therefore, SilentPatch takes control of nearly all the UI and menus
to keep elements aligned consistently regardless of the aspect ratio:
For more screenshots showcasing widescreen support, check the next chapter.
The PC version of Colin McRae Rally 3 had a strange bug where the sun would flash in random colors
(WARNING: rapidly flashing colors) if the FSAA (anti-aliasing) option was enabled. This happens regardless of whether anti-aliasing is enabled in-game, or forced externally;
dgVoodoo would also not help resolve it, proving that it’s not a Direct3D 9 bug.
I tracked down this issue to the game’s occlusion queries that would return values much higher than what the game had expected when multisampling is enabled
(due to queries returning the number of samples, not pixels).
I find it hard to blame the developers for this, as even the official Microsoft docs got it wrong! Since then,
I have submitted a pull request to correct the docs, and my proof in form of a fix for CMR3
was enough for the change to be accepted 😃 This link also includes a more technical writeup on this issue, in case you want to learn more about it.
Interestingly, this bug has been “fixed” officially in the sequels, but I was able to verify that it’s not fixed “properly”8 – instead of accounting for
the value of multisampling, the game now clamps the result of the occlusion query to (0.0 - 1.0)
. On one hand, this prevents the sun from being miscolored;
on the other hand, sun occlusion is now wrong with multisampling enabled, which means the sun visibility increases quicker the higher the multisampling value is.
This isn’t the only issue related to the sun rendering – aside from broken colors, the sun occlusion would cause a consistent and noticeable hitch every time
the sun would either appear on screen or go off screen:
This bug, fixed only in Colin McRae Rally 2005, is caused by the game waiting for the sun occlusion query to return its results as soon as it’s finished.
I don’t need to provide pseudocode, as the code flow looks nearly identical to
this Query State sample code from MSDN.
The important memo that the game ignores goes as follows (emphasis mine):
Note that applications should pay special attention to the large cost associated with flushing the command buffer because this causes the operating system
to switch into kernel mode, thus incurring a sizeable performance penalty. Applications should also be aware of wasting CPU cycles by waiting for queries to complete.Queries are an optimization to be used during rendering to increase performance. Therefore, it is not beneficial to spend time waiting for a query to finish.
If a query is issued and if the results are not yet ready by the time the application checks for them, the attempt at optimizing did
not succeed and rendering should continue as normal.
In this case, the game waits for the query to finish twice per frame, therefore forcibly syncing the CPU with the GPU two times per frame for no reason.
With this in mind, it’s strange that this hitch isn’t more consistent than that – the sync is done every frame, and so technically it should be blocking each time.
This is exactly what happens when dgVoodoo is used to make the game use Direct3D 11, but I couldn’t get it to ever happen in Direct3D 9 – perhaps due to a runtime
or a driver level optimization/hack:
These timings are even worse than by default, but in a way, they also make “more sense”.
The fix is trivial in theory, but a little harder to implement – instead of always waiting for the latest result, the game should keep the old sun
occlusion data (and not start another query) for as long as the new result is not ready. This means that the value of the sun occlusion (and therefore, its brightness)
lags behind the camera by 2-3 frames. However, in practice this is not noticeable during gameplay, and resolves any hitches completely:
The stutter struggle is no more.
Something I only noticed just now when writing this post: I don’t know if the huge difference in CPU9 and CPU11 usage is related to this fix.
However, it likely is – the old code essentially included a CPU spin lock waiting for the GPU, and the quote from the docs I included above specifically
points out “wasting CPU cycles by waiting for queries to complete”.
Thought we’re done with issues caused by anti-aliasing? So did I, but as it turns out – I was wrong.
Car shadows in CMR3 are simple but effective. They are essentially rendered in two phases:
- Render the car from the sun’s perspective, with depth testing and writing disabled, and with no color – always drawing full white.
- Take the 256×256 car shadow render target, downsample it to a smaller 128×128 target, and then upscale it again to achieve a blur effect. Repeat this step n times (8 in the stock CMR3).
Although the effect isn’t complex, it seemingly breaks with anti-aliasing enabled – upon starting the game with FSAA, shadows were there but they were too sharp;
even worse, changing the display mode with FSAA enabled would make the shadow vanish entirely for that game session:
From left to right – Shadows without FSAA (looking correct), shadows with FSAA (too sharp), shadows after changing graphics options (not there at all).
Turns out the issue lies in the “softening” pass. In theory, both shadow passes should be performed with depth test and depth write disabled;
this means that all draws should go through regardless of depth, and depth should not be updated by these draws.
Although the game sets up the depth states for shadow rendering correctly, an error in the 2D drawing functions made downsampling perform with a depth test enabled.9
Furthermore, in cases where a render target has no depth buffer associated with it, the game’s graphics engine uses a fallback instead and binds the backbu