Jekyll2024-03-14T20:20:24+00:00https://cookieplmonster.github.io/feed.xmlSilent’s BlogA blog and portfolio of Silent10th anniversary of SilentPatch!2023-12-29T19:00:00+00:002023-12-29T19:00:00+00:00https://cookieplmonster.github.io/2023/12/29/silentpatch-10th-anniversary
Has it been ten years already? Exactly a decade ago, I opened a new thread on GTAForums about my fix-mod for GTA III and GTA Vice City:
The first releases were relatively small mods – SilentPatch 1.01 for GTA III included 12 fixes, while the one for GTA Vice City – just 6!
The first fixes for San Andreas spun off my various experiments in VCS PC Edition; in the end, the patch for SA was released considerably bigger,
with just over 30 fixes. Ever since then, these patches tripled in size, which is an achievement considering I initially said I’d not update them with any more fixes 😁
During that time, SilentPatch went through a lot. Some of the moments I remember the best are:
The release of Rosenberg’s Audio Fix and Road Reflections Fix on November 10, 2012 and November 24, 2012 respectively.
Those two small modifications are essentially “proto-SilentPatches” and have directly influenced the decision to make a bigger “fix compilation” mod a year later.
The release of SilentPatch for San Andreas on June 16, 2014, after it had “leaked” a day prior.
The release of SilentPatch for Colin McRae Rally 2.0 on August 8, 2015 – the first non-GTA patch.
The first SilentPatch update with an update name released on December 28, 2019, turned out to be named rather unfortunately:
The Corona Update.
The SilentPatch that, to date, went the most viral due to the obscurity of a bug it fixed: SilentPatch for Mass Effect.
SilentPatch with the biggest scope of changes to date: SilentPatch for Colin McRae Rally 3.
Not only it introduces so many improvements it could be called a “remaster”, but it’s also notable for having been playtested by two ex-Codemasters developers
who originally worked on the game in 2003!
Nowadays, SilentPatch spans over 25 games of various ages and genres – dating from games released as far back as 1998, to games released just two months ago
as of the time of writing this post.
Celebrating 10 years of fixes
As the SilentPatch name lives as its own “brand” now, I’ve created a page specifically dedicated to it:
About SilentPatch
On this page, I included a list of all supported games and an explanation of what SilentPatch is – as more often than not, once a patch reaches
a community previously unaware of my work, people assume “silent” shall be taken literally, and these patches mute sounds in the game 😅
I have updated the timeline of the SilentPatch history.
I highlighted the most important events related to those, mostly focusing on the GTA patches due to their historical significance,
but also listing all the other supported games, as well as some other events that directly led to the creation of, or influenced the shape of SilentPatch.
The legend for colours is as follows:
Blue – SilentPatch events.
Green – miscellaneous events directly related to SilentPatch.
Pink – events related to other modifications, which were relevant for SilentPatch development nonetheless.
Orange – ‘community spotlight’ events.
I recommend viewing the timeline fullscreen!
Last but not least, a formal announcement – The original SilentPatches for GTA games will become open source in January 2024! 🥳
My interest in these games has lowered over the years, but I still want to give these original patches a proper sendoff – therefore,
they are going to receive a new update together with a full repository history publishing on GitHub. You’ll not only be able to see the current
state of the code but also follow it throughout most of the development cycle!
To clarify – I don’t intend to say this is going to be a definite final update for those SilentPatches. However, considering that they were
last updated in 2020, this is highly likely.
What’s next?
As always – I’m not sure. SilentPatch has been thriving as a “brand” and I’ve expanded into many more games, so I hope it continues.
I’ve recently also been taking contracts to help re-release older games on modern digital gaming platforms that I suppose can be called
“official SilentPatches”; even though they don’t carry the name, internally they work just like SPs, patching the game’s code at runtime 🙂
That said, I have very high hopes for 2024 – if everything goes well (and it still might not), perhaps next year we will see the first
game officially released carrying the SilentPatch name… Fingers crossed!
A brief look around the game’s code reveals the game has 11 previously unknown cheat codes, with 12 more prototype-only cheat codes that are locked by default!
The game locks them behind a check against the serial hardcoded in the executable – and only allows to use those cheat codes on the prototype (ULET/ULUT) builds.
Most of the cheats are quite standard and not that interesting, but the Stronger special ability effects cheat is an exception – it makes a Roar ability look quite entertaining:
Additionally, the 5 secret biker head models appear to be reused from the PSP version of Midnight Club 3: DUB Edition:
The obfuscation algorithm
The cheat strings use an obfuscation algorithm to “hide” them, presumably to make them harder to spot when disassembling the executable.
The algorithm used is simple and reversible – to document all the cheat codes, I wrote a small decryption program, and later simplified it and cleaned it up
with the help of Nenkai.
The encryption and decryption routines are as follows:
]]>Fan research vs official fix – EA Sports WRC decal rendering on GeForce GTX 10 series cards2023-12-22T20:30:00+00:002023-12-22T20:30:00+00:00https://cookieplmonster.github.io/2023/12/22/ea-sports-wrc-geforce-gtx-10-series-bug-pt2
On December 14, 2023, Codemasters released the v1.4.0 update for EA Sports WRC.
Among countless fixes, two items align with the fixes previously published in SilentPatch:
Fixed an issue where Fanatec and location event plates would appear stretched when using NVIDIA GTX 10 series GPUs.
Fixed an issue where framerate would drop to below 10 fps when using the Livery Editor on NVIDIA 10 series GPUs.
This was somewhat expected, since by the time I released SilentPatch last month, I’ve had the opportunity to get in touch with Codemasters
and share my findings in as much detail as possible. I was later informed that the issue was fixed internally and was given an OK to publish
SilentPatch as a stop-gap solution for the affected users. My efforts have also been highlighted on the official EA Sports WRC Discord 🙂
In the end, everyone won.
With this out of the way (and with SilentPatch officially deprecated), I was curious about the approach used for the official fix.
In this short article, I’ll dissect the official fix and compare it with mine.
The official fix
Let’s start with a recap. When I figured out the root cause of the original bug, I outlined two possible approaches that could be taken here:
Make the SRV typeless by defining the stride explicitly and setting the format to DXGI_FORMAT_UNKNOWN. This approach does not require modifying the shaders.
Modify the shader the same way I did, replacing StructuredBuffer<uint> with Buffer<float2>. This way the shader handles the existing input buffer layout correctly,
regardless of the GPU vendor/generation, and a current way of accessing the buffers is used.
In my fix, I went for the second approach, because replacing shaders is a much easier task than tracking down specific resource creation.
However, I was under the impression that the official fix would adopt the other approach, as that would’ve fixed all similar broken cases.
Surprisingly, I was wrong – with the v1.4.0 update, the buffer definitions remain unchanged:
Notice that the resources still have a defined format and are not UNKNOWN.
Instead, automatic variable names from RenderDoc immediately show that Codemasters changed the shaders themselves – in v1.3.0, the automatically generated name
of the first bound resource was structuredbuffer0, in v1.4.0 it’s texture0, indicating that the way the resource is accessed by the shader has changed!
Indeed, looking at the shader assembly of the fixed shader, it now looks identical to the shader from SilentPatch – which means my suggested solution of changing
the shader inputs was used as-is:
Is this the best solution? I can’t say this with absolute certainty of course, but I am somewhat surprised at the approach taken.
However, the other solution (making the buffers typeless) may have introduced problems with other shaders, so perhaps the current solution
was thought of as the safest.
However, I have a few more points to raise about this fix. It technically is complete, but it could have been done better, as I believe the current solution
is not complete, and DirectX specification is still violated by those shaders:
texture1 is of type R8G8B8A8_SNORM, but the shader accesses it through Buffer<float4>. If my knowledge of HLSL is correct,
the sampler used here should have been Buffer<snorm float4>.
structuredbuffer2 and structuredbuffer3 still use StructuredBuffer<> samplers, despite those buffers not being typeless.
In an ideal case, they should also have been changed to use Buffer<>. This is most likely a violation of the DirectX spec.
texture0 is of type R16G16_FLOAT, therefore the shader could have leveraged GPU’s support for 16-bit floating point values if the resource was sampled as min16float2.
This type combines compatibility with specialization – as it leverages native support for half-floats on supported hardware, and falls back to full floating point values otherwise.
Other fixes in the v1.4.0 update
The changelog of this update is massive, but I’d like to highlight two other things:
Aside from the aforementioned changes, the Livery Editor performance is now improved on all PC configurations.
Before this update, the editor was slow for everyone since the game was re-rendering all decals to an 8192x8192 render target every frame.
In v1.4.0, this is only done when the decals are added/removed/moved/scaled.
This update introduced the Central European Rally, a new location in the Czech Republic.
Unfortunately, this has introduced a critical issue with the existing Career Mode saves, making saves from further WRC seasons unusable.
This is a gameplay issue that in a game of this scope is effectively un-fixable from the outside, and the fix addressing it is scheduled only for mid-January – so
it’s a bummer 😔
]]>Fixing EA Sports WRC decal rendering on GeForce GTX 10 series cards2023-11-22T18:20:00+00:002023-11-22T18:20:00+00:00https://cookieplmonster.github.io/2023/11/22/ea-sports-wrc-geforce-gtx-10-series-bugTL;DR - if you are not interested in a technical dive into the graphical glitch fixed by SilentPatch, scroll down to the Download
section for a download link.
Ever since the newest WRC game from Codemasters and EA was released on November 3, 2023, I’ve had a lot of fun playing it.
Although my GTX 1070 is close to its end of life, I managed to find a good compromise between performance and quality somewhere in the middle ground
between Medium and High graphical details, and I’m able to play the game comfortably.
Throughout my playthrough, I’d also post a few screenshots on social media, such as those – you’ll see later why I bring it up.
You may already be able to spot what’s wrong with those screenshots, but at the time I completely missed all the clues.
I had already overheard the news about some people being unable to use the Livery Editor, but I didn’t put too much thought into it until I tried to use it myself.
I tried to put a decal on my car, but without much success:
Two questions come to mind: where is my decal, and why is the game running at 8 FPS?
I shared this screen on Discord in hopes of finding someone else with the same issue, and one person pointed out that other than the decal, I am missing something
else – the driver number and the driver/co-driver names are completely missing from the side window! Sure enough, all cars were broken for me in one way or another,
but I think Vauxhall Nova takes the crown with just how gloriously unusable it had become:
Indeed, it seems that I hit the very Livery Editor bug I was warned about. A thread in EA Answers HQ
has entire pages of people reporting this bug, with one interesting point – everyone disclosing their PC specs in that thread is playing the game on GTX 9xx or 10xx series!
It would seem that no other GPU vendor and/or generation except for those is affected. While Maxwell (9xx series) cards are not officially supported by the game, Pascal (10xx series)
are, as the game’s minimum system requirements list the GTX 1060. Additionally, this issue is partially mentioned in the current version
of the Known Issues page, although it’s more widespread than the thread says:
On GTX 1060 GPU the Fanatec and Flag Decals on vehicles have stretching glitch
Now scroll up. See all these weird “scratches” and lines on these cars and rear windshields? Only then did I realize that the broken Livery Editor
and these are actually related – the artifacts on rear windshields are the flags and driver numbers, while “scratches” on cars are most likely the rally-specific/Fanatec decals!
Me being me, I didn’t want to just continue playing the game in this state – it was time to set up RenderDoc.
Investigation and debugging
For this investigation, I took a frame capture of the aforementioned Nova. These decals are rendered only once and not every frame, so capturing the exact frame required
a few attempts. I then remoted to another PC with RTX 3070 and opened the same capture on it. Usually, RenderDoc captures are not guaranteed to work across different PCs
with different graphics cards, especially with low-level APIs like D3D12 used by WRC, but in this case, a capture from the GTX 1070 PC played back on the RTX 3070 PC just fine
(the opposite crashes the D3D12 device, though). Not only that, but on that PC the very same capture also… did not display the bug!
Cases like this are always interesting and reminiscent of my Far Cry investigation. RenderDoc captures the record of every single D3D command
issued by the game in the frame, together with the input data; then, previewing events in the capture involves replaying the saved sequence of events up to the point of the selected event.
In other words, if two PCs show different results on the same capture, the bug is not the matter of the game setting things up differently between hardware,
but rather the hardware itself interpreting the given commands and data in a diverging way!
RenderDoc’s Mesh Viewer provides another clue – apparently, these draws take the car’s body mesh as input, and it obviously looks the same across different hardware…
…but the outputs look… let’s just say, drastically different.
Oh no.
The above comparison concerns the body decals, but it’s the same for nameplates on windows. This is how they render:
Or presented in a different view, highlighting one of the draw calls in pink:
I initially feared that this could be a low-level D3D12 issue (missing synchronization, etc.), but the issue persisted when running the game in a D3D11 mode
through a -dx11 command line argument. With this in mind, the first obvious culprit is a vertex shader, especially since they are shared between backends.
RenderDoc gives an option to preview the shader assembly, and the vertex shader used for these decals is not too long:
Nothing seems obviously wrong here, and any attempts at debugging this shader in RenderDoc failed since the shader interpreter did not manifest this issue
when stepping through the shader assembly (or in other words, the output positions matched the expected result, not the “broken” result from Pascal cards).
However, RenderDoc also gives an option of replacing shaders on runtime, so I could debug this issue by editing the shader in-capture.
Unfortunately, re-assembling shaders is not possible in newer APIs (used to be possible back in D3D8/D3D9 days), so to be able to do that,
I had to reimplement the entire shader in HLSL. I rewrote it exactly in the way I understood the above shader assembly, and the result was surprising – the bug was gone:
Yes, it’s technically the exact same screenshot as above – but since it’s a render of the very same RenderDoc capture, they look 1:1 identical.
I initially thought I rewrote the shader 1:1 to the original, so I started investigating the differences. The only two different components were the output position and TEXCOORD2,
and the shader derives both from the same input. Therefore, I could isolate the changes down to only the writes to o3.
In my shader, I declared the t0 sampler as StructuredBuffer<half2>, as that’s what I thought the original shader did. However, this results in the generated code looking slightly different:
My custom shader samples the buffer with a stride of 8, and uses these values directly.
It’s reasonable to assume that this difference is responsible for my accidental bug fix, but I couldn’t confirm it until I figured out why
is the generated code different. I initially thought it was maybe because the original shader was compiled with support for 16-bit floats and mine wasn’t,
but then my colleague and I casually chatted about this issue with pointed out that for Unreal Engine games, it’s common to declare their input buffers with
type uint and manually extract the half-floats, like so:
What is the result of mirroring this approach in the affected shader? This time, the generated shader assembly is line-to-line identical to the original shader, stride of 4 bytes included.
And when it comes to rendering, well…
The same disclaimer as above applies.
Just to be clear – what the original shader is doing is not always wrong, but in the case of the current setup it is, and I don’t know why it works on the other
GPU vendors and architectures. Maybe it’s worked around via a driver-level hack that is not enabled for the Nvidia 9xx and 10xx series.
What is the setup that makes sampling the buffer as uint not work? RenderDoc presents it as a set of four typed buffers:
There are two problems with this approach:
When accessing the buffers via StructuredBuffer, it is assumed that the buffer is laid out in an arbitrary structure with a predefined stride.
It is explained nicely by János Turánszki in their Dynamic vertex formats post,
but the main clue is provided by MSDN:
The SRV format bound to this resource needs to be created with the DXGI_FORMAT_UNKNOWN format.
This is clearly not the case with the above setup, as RenderDoc reports the format of the first bound buffer as R16G16_FLOAT.
However, even though this mistake is technically a spec violation, it’s not causing rendering issues on my end – StructuredBuffer<half2>
and StructuredBuffer<float2> both work “fine”, even though they are incorrect.
Another much worse mistake is the buffer format itself. Because the SRV of the first buffer has a predefined FLOAT type, sampling it as uint is forbidden
and this is what causes the rendering glitches on my GPU! With typed buffers, it doesn’t matter that the data is technically the same if it is to be
read as bytes directly – SRV format and sampler type must match, with no exceptions. The fact it works elsewhere is either due to sheer luck, or an existing driver-level hack.
With this in mind, it is clear that there are two possible fixes for this:
Make the SRV typeless by defining the stride explicitly and setting the format to DXGI_FORMAT_UNKNOWN. This approach does not require modifying the shaders.
Modify the shader the same way I did, replacing StructuredBuffer<uint> with Buffer<float2>. This way the shader handles the existing input buffer layout correctly,
regardless of the GPU vendor/generation, and a current way of accessing the buffers is used.
Are any other shaders broken in the same way? At least one more shader is – in the Livery Editor, the user has an option of painting the roof/bonnet/mirror/spoiler in different
colors to the rest of the body. On the below comparison, all these parts should be orange, but due to an identical bug in the paint shader this doesn’t work on the 10 series:
The liveries used here are not identical, so this is only about the colored parts.
Putting the fix into the game
OK, but now what? I have a theoretical fix for this issue ready, but it’s all isolated to RenderDoc captures. Having technically solved this issue,
I wanted to put it in my game to have a stop-gap solution for this bug until it’s been officially fixed.
It then struck me I already released a very similar modification 3.5 years ago
– Gold Filter Restoration for Deus Ex: Human Revolution Director’s Cut largely relies on replacing shaders on runtime,
much like what I would need to do here. It’s only done for D3D11, but that is not an issue, since I can run the game using this API via a command line argument.
Unreal’s D3D11 implementation might be a little bit less performant than D3D12, but that’s fine for the time being – I prefer to trade a bit of performance for
correct visuals.
Gold Filter Restoration seems like an ideal base for this fix – it acts as a D3D11 wrapper, no different from ReShade.
No code is hooked in the game, so if WRC uses an anti-cheat, it’s extremely unlikely to become upset at this.
In practice, this approach is easy to code and reliable. A wrapper around ID3D11Device lets me intercept the vertex shader creation,
so the two broken shaders can just be replaced with my custom implementations, and the game is none the wiser:
With this one single change, liveries are working in-game as they should 🙂 Additionally, the aforementioned horrible performance of the Livery Editor
is resolved – on my GTX 1070, resulting in an uplift of 5 FPS → 55 FPS while editing decals!
One more thing – the fix is technically ready as-is, but I wanted to make extra sure it cannot cause any conflicts if this issue gets fixed officially in the future.
If the devs fix this bug by modifying the shaders, their hashes will change, and they will not be intercepted with my replacements.
However, if they opt to fix the SRVs instead, it could result in a conflict.
To avoid this, I “gated off” this SilentPatch. If the user attempts to run it on a game build that is newer than what is public at the time of writing this post,
they’ll be greeted with a warning message instructing the user to remove my fix and remove the command line argument:
If the next official patch doesn’t address the issue, I will update my fix against that future patch. It may be annoying for the end user, but it’s the only way
to be completely sure no unintended side effects occur.
Download
The modification can be downloaded from Mods & Patches. Click here to head to the game’s page directly:
For those interested,
the full source code of the mod has been published on GitHub, so it can be freely used as a point of reference: See source on GitHub
]]>Exploring the history of Juiced through prototypes and PC demos2023-10-21T13:05:00+00:002023-10-21T13:05:00+00:00https://cookieplmonster.github.io/2023/10/21/juiced-acclaim-and-pc-demos
Usually, when I dissect games on this blog, I don’t give much attention to demos. However, due to its troubled
development cycle, Juiced is an exceptional case.
Because of the game changing publishers right before the original release date, the game has changed considerably
– and thanks to PC demos and leaked PS2/Xbox prototypes, we have a unique opportunity to experience the game in its original form.
This post is the first in the series of Research-style posts.
I intend to keep updating posts in this category as new information comes in instead of publishing new posts about the same game,
so keep an eye on this category from time to time 😉
In this post, instead of focusing on modifying Juiced, I want to showcase the game and its history through the evolution of
all 6 PC demos that are available online. They all have minor compatibility issues, so for that, I’m releasing
the first strictly demo-oriented SilentPatch with two clear goals:
Fix the demos just enough for them to be playable without compatibility issues. I wish to preserve those demos in their original state,
so I focused solely on critical bugs. This means that separate Quit and Quit Game options
present in the Acclaim demos are here to stay for the sake of history 😉 Despite the limited scope of this SilentPatch, it should still make for an entertaining
read – since the bugs I fixed range from incorrect math behind the field of view calculations, compatibility bugs, through (for the first time)
a possible compiler/optimizer bug breaking the game’s code!
(Optionally) unlock the demos as much as possible. Early demos had widescreen support from the console versions left unused,
and they all ship more content than was made available officially. Since I want to use those PC demos as a showcase of “the game that never came to be”,
I want everyone to enjoy them to the fullest.
Not interested in demos and you’d rather experience the full prototype builds? I have something for you too.
As part of my research, I was playtesting those builds too, and later I created several small patches for the PS2 versions – including a 60 FPS
hack and a patch to make those prototypes playable online via PS2Online!
The latest builds to surface online are developed so far that you can even play them through the Internet.
Chapter 1: Who was Juice Games? What is Juiced?
The history of Juiced and Juice Games isn’t told in full without mentioning Rage Software.
This British studio was responsible (among other games) for racing games like E-racer
or Off-Road Redneck Racing, however, they were also working on
Lamborghini – a racing game announced in May 2002
that promised to feature every single car model from this Italian automaker.1
Unfortunately, Rage Software
went bankrupt in January 2003, just before they could release the game.
Lamborghini became a lost media, with only an Xbox Demo surviving, at least until May 2022, when a nearly finished beta build
has been published on HiddenPalace.
Not long after, part of the Rage Software staff founded Juice Games.
Even on their official website,
they were always upfront about their Rage Software roots:
With a back catalogue that includes TFX, EF2000 and the critically acclaimed but unreleased Lamborghini,
Juice Games developed the multi-million unit selling Juiced franchise.
Sometime in 2003, the team secured funding from Fund4Games
and a publishing deal with Acclaim Entertainment (who needed a new racing title after losing
the publishing rights for Burnout) for their new game, Juice.
While the game was never officially referred to by this name, thanks to a very early prototype we know this name was in use at least until November 2003.
By the time Juice Games officially announced the game in January 2004,
it was already known by its final name and set for a Fall 2004 release. The development process under Acclaim was relatively well documented,
with multiple websites showcasing the game in its early state234, and with demos on all platforms releasing around July 2004.
In fact, you could say that they released one demo too many – on June 9, 2004,
a PC demo was released early by the German division of Acclaim,
then promptly delisted on June 11, 2004. and scrubbed from the internet thoroughly:
Juiced Demo
The Juiced demo was taken from the server because it does not show the final status of the game.
A new demo will be available as soon as possible. Thank you for your interest!
A “final” Acclaim demo was eventually released on July 14, 2004,
in a much better state than the first one. While Acclaim has done a good job replacing the early demo with a proper build,
some downloads survived thanks to Wayback Machine and we can experience this early demo with all its issues – but more on that later 😉
We’ll bring you more on Juiced as its early September release date approaches.
An Amazon listing attributed to Acclaim Entertainment exists
and lists the release date as September 7, 2004, although this listing doesn’t use Acclaim’s cover art.
Interestingly, THQ listings also exist and they have a different ASIN, but that may just be an US vs. EU Amazon.
Even the original box art was revealed.
September release never happened, though – instead, Acclaim filed for bankruptcy in October 2004
and the game’s future became unknown. This has all happened so late so some boxed copies of the game ended up turning up online years later, although there is no evidence of the game reaching the store shelves.
- work for Rage Software - develop a Lamborghini game nearly to completion - studio bankrupts, game never releases - move on to found Juice Games - develop Juiced for Acclaim nearly to completion - publisher bankrupts, new publisher modifies the game
Before long, THQ and Take-Two both bid to acquire rights to Juiced;
Electronics Arts also attempted to join the bid but failed to meet the deadline (and, honestly, it’s good that they didn’t manage to buy a direct competitor
to their own Need for Speed: Underground). THQ eventually won and moved the release date to Summer 2005,
giving Juice Games 5 more months to make changes to the game. If the reviews were to be trusted,
that new iteration was received better than the Acclaim’s version.
The public was also able to see the changes themselves first through a round of demos released in January 2005, then in May 2005, just before the game’s release.
The game was eventually released on June 13, 2005 in North America and June 17, 2005 in Europe.
This brief recap of the game’s history brings me to the clue of this article. Even though Acclaim’s Juiced and THQ’s Juiced are not entirely different games,
the game went through some significant design changes. With no known full PC builds surviving, demos is all we have on this platform.
In my analysis, I’ll go through all 6 known PC demos and compare them one by one in the order of their internal timestamps.
Chapter 2: Acclaim Demos
All 3 Acclaim demos have content parity, at least when it comes to officially unlocked content:
3 cars with an option to pre-tune them
1 selectable route in San Ricardo
When it comes to locked content shipped with the files, there are a few differences.
In SilentPatch & Enhanced PC Demo, all exclusive content is “ported” to the latest Acclaim Demo.
SilentPatch includes identical fixes for all 3 demos, and therefore I’ll be only highlighting them on the latest, most polished demo.
Screenshots included in this chapter are all taken with SilentPatch installed, as otherwise I would have to take them in 4:3.
However, this is the only modified visual aspect of those demos.
As mentioned previously, this demo was accidentally released online early, and it shows.
Acclaim’s attempts to scrub this version off the internet were mostly successful, as the above download link is virtually the only source I could find online.
This build has a range of issues, ranging from regular crashes, graphical artifacts,
and missing PC features, to an unimplemented Quit (Alt + F4 doesn’t work either!). Even ignoring all those, as far as I can tell,
a Nitrous button is completely unmapped in this build, and unlike later builds, this one doesn’t give the player an option to redefine controls.
It doesn’t even have a game icon.
Although this demo has 3 cars available by default, it also ships a 4th car – Toyota MR2. In SilentPatch & Enhanced PC Demo, this car has been made selectable.
Since I included this car in the mod package, it’s now also available in later demos.
Fonts don’t scale either.
Unlike later demos, a Videos menu entry is available, with 3 small game teasers available – although their appearance is slightly glitchy.
SilentPatch & Enhanced PC Demo unlocks all shipped content in this demo, but there is a twist – in this build, the Sprint races work differently. Rather than taking place on the straight section of the road,
much like drag races in other games (or Sprints in the final version of the game), these Sprints take place on small sections of regular tracks.
Considering that the game mode works identically to the final game (including forced manual shifting), I initially thought it was a bug. However, as found by Eagle,
the final game includes unused minimaps for the Sprint races, and one of those minimaps closely resembles a playable track in this build.
It’s just speculation, but it is possible that this demo represents a work-in-progress redesign of this game mode,
or it was just not finalized yet and used sections of the existing tracks as placeholders.
Credits: Eagle
I also have not fixed the crashes exclusive to this demo, so it is barely playable even patched. IMO this demo is not worth the effort, except for its rarity.
June 2004 Demo
Compilation date: Wednesday, 23 June 2004 09:22:06
Download links: DOWNLOAD,
MIRROR; the installer doesn’t allow picking an installation directory by default, see below for a fix
Worth testing: NO (just get the July demo)
This build is a prototype demo retrieved from Duffy’s Dreamcast Collection
– a bunch of prototypes from an ex-Acclaim beta tester Duffy, who passed away recently. Compared to the May demo, it’s much more polished – all issues I mentioned
(except for the texts not scaling to resolution) have been fixed. Comparison screenshots show several obvious differences.
Based on my observations, I could identify the following differences between May and June builds:
The title screen is slightly different, with PRESS ENTER relocated to the center of the screen.
New intro copyright disclaimers.
Car select UI has been rearranged slightly.
New keyboard button prompts.
Car names have been changed.
Reflections in the car select screen are slightly toned down.
Videos have been cut.
Sprint races (unlocked by SilentPatch & Enhanced PC Demo) now work like in the final game.
Exit Demo option has been added.
Race HUD has been slightly changed not to feature black backgrounds.
For some reason, motion blur is extremely overdone in this build.
Pre-race cutscenes have different camera angles.
Tire smoke is visible, while it was absent from the May build.
The configurator app is slightly more fleshed out, with Shader Model 2.0 added. However, that introduced a bug where the application requires the Windows XP SP2 compatibility mode to run
(fixed in SilentPatch).
Controls can now be remapped, although instead of an in-game remapper, DirectInput Mapper
((in)famously removed from Windows Vista and newer) is used. The game must also be running in the windowed mode, or else it obscures the mapper window.
Aside from the compatibility issues of the configurator app, this build also introduced a peculiar issue where the HUD flickers randomly. Since the July build was also affected,
I will explain this bug in detail below.
July 2004 Demo
Compilation date: Friday, 2 July 2004 17:00:06
Download links: DOWNLOAD,
MIRROR; the installer doesn’t allow picking an installation directory by default, see below for a fix
Worth testing: YES
This demo is similar to the June build, but with a few additional fixes:
Texts are now scaling to resolution.
The main menu has been slightly rearranged.
Excessive motion blur from the June build appears to have been toned down.
The bloom effect when activating nitrous is noticeably ramped up.
Lighting (especially on cars) seems to be a little darker, as evidenced by the comparison screenshots.
Fixes included in SilentPatch & Enhanced PC Demo
Since I want those Acclaim demos (especially the latest one) to be enjoyable to their fullest, SilentPatch includes several fixes for the most severe issues present in those builds.
As they are demos, they are inherently a work-in-progress product and so most of those issues shouldn’t come as a surprise, for that reason I also have not fixed any gameplay shortcomings.
I want those demos to be playable, but I don’t want to distort their “history” by “completing” them. Here are the highlights of this release:
All shipped content has been unlocked. This increases the amount of in-game content from 1 route in the Race mode and 3 selectable cars to:
4 routes in the Race mode + reverse variants + 1 Point-to-Point race.
Sprint race.
Showoff (Cruise) mode.
Solo mode.
Additionally, the users may enable all menus with an INI option but do note that most menus are not finished and will softlock.
3 teaser videos from the May demo have been included and re-enabled.
The laps limit has been lifted from 2 to 6, like in the console prototype builds from a similar timeframe.
In night and wet races, the limit of on-track cars has been lifted from 4 to 6. This appears to have been a purely performance-focused constraint,
and with modern PCs, we can easily brute force through it without any noticeable issues.
Widescreen from the console builds has been re-enabled and further improved. The default widescreen option slightly distorts the aspect ratio and appears horizontally squashed
compared to 4:3. SilentPatch corrects this and additionally supports arbitrary aspect ratios, which means ultra widescreen now looks as expected.
The configuration application can now also select widescreen resolutions when in windowed mode.
The default driver name Player1 can now be overridden via the INI file.
All known compatibility issues have been fixed. JuicedConfig.exe no longer needs Windows XP SP2 compatibility mode to run.
May 2004 Demo can now be quit by pressing Alt + F4.
All game settings have been moved from registry to settings.ini. This makes demos fully portable and prevents them from overwriting
each other’s settings.
June and July demos introduced a bug where the UI elements flicker randomly, with seemingly no fix.
In-game elements can also flicker like this (or worse), making for a miserable experience.
I initially suspected this is similar to an issue present in Scarface (this is the second post in
a row where Scarface gets a shout-out), and to make matters worse, applying an identical fix (removing the D3DLOCK_DISCARD flag when locking the vertex buffers)
helped. However, that turned out to be a red herring, as the game’s usage of this flag was correct. I later identified this issue to be a potential compiler/optimizer bug!x86 calling conventions have strict requirements regarding the state of the FPU…
The x87 floating point registers ST0 to ST7 must be empty (popped or freed) when calling a new function, and ST1 to ST7 must be empty on exiting a function.
…however, the game’s code ignores this requirement when calling into one of the Direct3D 9 functions, either by a mistake in handwritten assembly code (unlikely)
or due to a compiler bug:
movesi,eaxmovdwordptr[eax+24h],1callLockVertexBufferfldst(2); The code assumes this value was not changed by the above; function, but this is not guaranteed to be the case!movecx,[ebp+0]
I authored a fix where LockVertexBuffer saves and restores the entire FPU state, and lo and behold – the issue is fixed.
This is the first time I fixed a game issue that I suspect was caused by a compiler bug, but I’m not surprised too much;
I’ve already encountered such bugs multiple times in my programming career outside of reverse engineering games.
In-game music plays with crackles and pops in all 3 Acclaim demos. This bug, later fixed in THQ demos, occurs because
the game requests more data to be loaded from the disk after playback reaches a specific point in the audio track.
In the case of THQ demos, this happens when passing a mid-point of the 1-second-long chunk of loaded music, but in Acclaim demos this
marker is set to one byte before the end of the track. This obviously doesn’t allow the game to stream more data in time,
and that results in broken music playback. In SilentPatch, I mirrored the change made to the 2005 demos.
By default, the music crackles quite a bit.With SilentPatch, it sounds as expected.
Last but not least, an issue I did not fix (as I said earlier, I decided against altering the work-in-progress state of those demos beyond
the essential fixes), but I consider it worth mentioning anyway. For some strange reason, parts of the environment are darker when the HUD isn’t displaying.
This comparison is done with the HUD disabled via a hack, but you can replicate the same scenario by using a rearview camera (by default mapped to Space).
Furthermore, after Alt + Tab, this issue vanishes and the environments are dark regardless of whether the HUD is drawn or not.
I haven’t looked into this issue with PIX, so I am not sure which of the two states is “correct”, but in my opinion the darker state makes the affected objects
(especially the car) blend with the rest of the environment better.
This looks somewhat similar to the June/July comparison.
Demo installer issues
By default, June and July demos’ installers don’t include an option to change the installation directory and instead, they always install the game to
C:\Program Files (x86)\Acclaim Entertainment\JuicedDemo. Since these installers use InstallShield, I created a Transform file to re-enable
the Destination Folder screen.
I strongly recommend downloading it from Downloads and running the installer via run.bat,
instead of installing them to Program Files – it’s not a good idea, especially with such older, UAC-unaware games and with SilentPatch
redirecting settings to the INI file.
Chapter 3: THQ Demos
Just like with Acclaim, all 3 demos from THQ have content parity. However, this content has been entirely refocused and instead of
a free custom race form of the earlier demos, THQ demos are linear:
The initial race puts the player in a Nissan Skyline in a night 1v1 race against a Toyota Supra.
The player also gets an option to bet with their rival – a mechanic also present in the Acclaim version of the game,
but not covered by their demo at all.
After the race, the player gets a chance to freely tune their Skyline.
Once they are done, a second race against 3 opponents (this time set in the morning) starts.
After the second race, the demo ends.
It’s clear that this demo showcases the game better, as the player gets a taste of what the career mode looks like, and they can experiment with the game’s tuning system
on their own, instead of relying on auto-mod from the Acclaim demo.
January 2005 Demo
Compilation date: Friday, 28 January 2005 15:07:00
Worth testing: SOMEWHAT (slightly different from the final game, runs with nearly no compatibility issues)
Out of the box, this demo will refuse to boot on PCs with more than 4 logical CPU cores (fixed in SilentPatch).
However, this demo does not exhibit the compatibility issues present in the final game – that is, Alt + Tab does not crash the game
and the Juiced requires virtual memory to be enabled is not present.
This demo is also the only one to feature more than one executable – Juiced.exe is compiled with SSE2 instructions, but there is also Juiced_NOSSE2.exe.
The final game doesn’t ship multiple executables.
There isn’t much to talk about in this version otherwise, as it’s mostly identical to the final game.
However, while working on unlocking its content, I accidentally reached a semi-broken Career screen – despite its brokenness,
its layout is distinctly different from the final game, more resembling a career screen from the Acclaim prototypes!
April 2005 Demo (v2.0)
Compilation date: Thursday, 14 April 2005 15:54:25 (4 days before the full game)
Worth testing: NO (if you really want to try it, don’t bother without installing a v2.1 patch)
Content-wise, this demo is fleshed out further, but on the technical side it only gets worse – unlike the January demo,
this one includes all the incompatibilities of the final game 😕
Generally, this demo appears to be identical to the final game, with all design locked in place.
Based on my observations, I could identify the following content differences between January and April builds:
Copyrights have been updated from 2004 to 2005.
Car reflections have been updated.
Fonts and UI sounds have been replaced. As far as I know, the old UI sounds have later been used in Juiced: Eliminator.
Music in the garage screen has been updated to be different from the main menu music.
Weird changes have been made to widescreen support – in the January build, the game scaled properly to 16:9, but in this build (and the final game), scaling is incorrect!
According to PCGamingWiki, the Widescreen option in the full version
of the game is for 16:10, not 16:9. I’m not sure why they changed it, and why they didn’t leave both 16:9 and 16:10 as options instead.
May 2005 Demo (v2.1)
Compilation date: Wednesday, 18 May 2005 09:13:12 (30 days after the full game, 51 days before patch v1.01)
Download links: DOWNLOAD,
MIRROR; patches the above v2.0 demo to v2.1
Worth testing: SOMEWHAT (if you really can’t try the full game)
Officially, this patch exclusive for the demo version is supposed to only improve performance:
Juiced by Juice Games - demo v2.0 → v2.1 patch
It has come to our attention that some people may have experienced performance
problems with Version 2 of the Juiced PC Demo.
THQ are pleased to announce that a patch to update Version 2 of the demo to
Version 2.1.
PLEASE NOTE THIS PATCH WILL UPDATE VERSION 2 OF THE PC DEMO ONLY.
However, there is more to it – the demo patch was compiled 1 month after the initial PC version of the full game,
and it also seems to include more changes later seen in the regional releases in Czechia, Poland, and Russia,
and possibly also some fixes later rolled out in a v1.01 patch.
May demo supports EFIGS, Czech, Polish, and Russian!
But here’s the catch – while the demo’s code supports the additional languages and even attempts to pick them by default based
on the user’s system locale, they… don’t ship the language files! The result is that on my OS with a Polish locale selected,
I was consistently crashing on startup and couldn’t run this demo at all until I “reverted” support for those 3 languages with SilentPatch 🙃
This almost made me drop support for this patch until a trace with Process Monitor
revealed that the game tried to access controls_dx9_p.txt and failed. This, combined with the fact that the game booted fine on Windows Sandbox
(that did not use a Polish locale) proved that the issue lies there, and thus is trivially fixable by “cutting” those 3 languages from the demo. Phew.
Fixes included in SilentPatch & Enhanced PC Demo
All shipped content has been unlocked. Since these demos don’t include Custom Races, customization is done through the SilentPatchJuicedDemo.ini file
and concerns only the second race. The following options are available:
4 routes in the Race mode + reverse variants + 1 Point-to-Point race + its reverse variant.
Sprint race.
Showoff (Cruise) mode.
Solo mode.
Customizable time of day, weather, number of laps, and number of AI opponents.
Additionally, the users may enable all menus with an INI option but do note that most menus are not finished and will softlock.
The player’s starter car can now be customized by editing the scripts\CMSPlayersCrewCollection2.txt file. The following cars
are available: gtr, nsx, supra, vette_zo6, viper.
Demos have optionally been made endless. Instead of the game exiting after the second race, it returns to the garage and gives an option
of tuning the car again and starting another race. Combined with the aforementioned content unlocks, this lets the player try multiple different
routes and game modes in a single session, as the race configuration options in the INI file can be modified while the game is running.
The default driver name Player can now be overridden via the INI file.
A startup crash in the January 2005 demo occurring on PCs with more than 4 logical CPU cores has been fixed.
Juiced requires virtual memory to be enabled error from the April and May 2005 demos has been fixed.
Startup crashes in the May 2005 demo occurring when the OS locale is set to Czech, Polish or Russian have been fixed.
JuicedConfig.exe no longer needs Windows XP SP2 compatibility mode or a Windows compatibility shim to run.
This improves compatibility with environments where compatibility shims are not enabled by default, e.g. on Wine/Proton.
All game settings have been moved from registry to settings.ini. This makes demos fully portable and prevents them from overwriting
each other’s settings.
Chapter 4: PS2 Prototypes, briefly
As I mentioned earlier, many PS2 and Xbox prototypes of Acclaim’s Juiced have surfaced online. Although they all come from the tail end
of the game’s development under the original publisher, they seem to be slightly different from one another. However, comparing all these prototypes
in detail would be an enormous task, much bigger than the demo comparisons presented above (that already are quite lengthy). Most of the differences
are likely also purely technical and not that entertaining for a casual reader.
That said, during the course of the entirety of this research, I came across a few findings specifically in the PS2 prototypes
that warranted some attention, and I’m publishing them in the form of patches for the two prototypes that by the time of writing this
are available online – June 11, 2004 and July 28, 2004 builds.
60 FPS
While the Xbox prototypes and the final game (on all platforms) target 60 FPS, both PS2 prototypes are locked to 30 FPS.
This patch lifts the FPS cap, allowing the game to hit 60 FPS. When using this cheat in PCSX2, the default configuration tailored for the final version
of Juiced prevents these prototypes from maintaining a stable 60 FPS, even with an overclocked emulated CPU.
For an optimal experience, several settings should be changed as follows.
Please make sure to use Per-Game Settings to change those, as changing those settings globally is guaranteed to cause problems with other games,
including the final version of Juiced:
Set EE Cycle Rate to 130%.
Enable Enable Instant VU1.
Disable Enable Game Fixes (in the Advanced tab).
Progressive Scan
The July 28, 2004 build and the final version of Juiced include an option to switch the game to use Progressive Scan
by holding X + △,
while the June 11, 2004 build doesn’t implement this option yet. With this cheat, Progressive Scan is enabled also on this build.
Fixed Widescreen
Just like I mentioned earlier, all Acclaim’s versions of the game have slightly defective widescreen support and
the aspect ratio is “overcorrected”, causing the image to be squashed. With this patch, the widescreen proportions match 4:3 perfectly,
the same as I did for PC demos.
DNAS Bypass
On the PlayStation 2, online multiplayer was protected by Dynamic Network Authentication System (DNAS),
an authentication protocol that ensured pirated game copies couldn’t access the online functionality.
Sony kept this service up for long after the PS2’s end of life, but finally took it offline on April 4, 2016,
leaving unmodified games unable to play online. As DNAS was not responsible for the actual online functionality, only for authentication,
DNAS Bypass codes have been created for various games to circumvent the authentication entirely. Thanks to the PS2Online project,
the final version of Juiced has a DNAS Bypass patch that allows people to play online through OpenSpy, but that patch didn’t work for the prototypes.
With my DNAS Bypass, Acclaim prototypes can connect to OpenSpy and online play is possible just like in the final game! Prototypes and retail games see each other’s lobbies,
but they cannot enter them – so it is not possible to accidentally ruin someone else’s fun by joining their game with the wrong version of the game.
My tests were also done only on the June build; July build can go online too, but I’ve not had much success creating a lobby.
Downloads
f4mi has created a showcase of SilentPatch & Enhanced PC Demo and the improvements it makes to Acclaim’s Juiced Demo – check it out if you want to see the new content in action:
]]>SilentPatch for NFS2: Special Edition, NFS3: Hot Pursuit, NFS4: High Stakes and NFS: Porsche Unleashed2023-09-24T12:50:00+00:002023-09-24T12:50:00+00:00https://cookieplmonster.github.io/2023/09/24/silentpatch-need-for-speed-classicsTL;DR - if you are not interested in a brief explanation of the issues fixed by SilentPatch,
scroll down to the Download section for a download link.
Recently, after playing an emulated PS1 version of Need for Speed II with RetroAchievements,
I wished to revisit a PC version with an excellent Modern Patch
from Verok. Although this patch fixes a wide array of compatibility issues, I still ran into problems – I couldn’t map any buttons on my Xbox One controller, although I could map
the analog stick and triggers. Troubleshooting this issue quickly snowballed into the process of finding (and fixing) more bugs, many of which turned out to be shared across multiple games.
Therefore, what was intended to be originally a patch for NFS2: Special Edition now spans four Need for Speed games:
Need for Speed 2: Special Edition
Need for Speed 3: Hot Pursuit
Need for Speed: High Stakes (also known as Road Challenge)
Need for Speed: Porsche Unleashed (also known as Porsche 2000)
Since Modern Patches exist for all four supported games, I didn’t have to do much. However, during development I was also made aware of some issues introduced
by NFS2/Porsche Modern Patches (as far as we know, NFS3/NFS4 patches are spotless 🙂), so now I also patch the patch. Yo dawg…
Highlights
These old games are known to have issues with multicore CPUs. In the case of NFS3, Modern Patch fixes the race conditions and can run freely,
but the other games didn’t get this treatment so they’re being limited to run to just one core. This can lead to performance issues even on modern PCs,
as previously seen in Scarface – therefore, SilentPatch applies a similar approach to one previously used in Scarface.
In NFS2SE and NFS4, only the “problematic” movie decoding threads are pinned to the same core as the main game thread, while the other threads are allowed to run freely.
This results in a good compromise between stability and performance.
By default, SilentPatch is set up to use the configuration file from Modern Patch, so if you use these two fixes together, you’ll automatically get the best possible experience
with SilentPatch reading the configuration file of Modern Patch and overriding its affinity changes to my own. However, if you wish to change it, SilentPatch reads a SingleProcAffinity
setting from the INI file of the Modern Patch.
NFS2: Special Edition has an issue (fixed in the sequels) where controller button mappings don’t work with controllers reporting more than 15 buttons,
although the game should be able to handle up to 32 buttons. This rendered my Xbox One controller partially unusable, as it reports 16 buttons.
I fixed the issue and documented it in the NFSIISE project. As a bonus,
I also made the game not close if a controller was disconnected during the race, as the sequels never did that.
As good as NFS2SE’s Modern Patch is, it unfortunately also introduced at least one issue. Online races became a sub-par experience because they were rendered as if they were
a split-screen race:
This is a reconstruction, but this is exactly how online races used to look.
SilentPatch hooks into Modern Patch (if installed) and patches this issue.
Need for Speed: Porsche Unleashed can crash on some Windows 10/11 PCs while enumerating controllers on startup. Curiously, it’s a rare case where the game did nothing wrong
and the issue is a regression of the dinput.dll library introduced sometime during the Windows 10 lifecycle.
This affects many games using this version of the DirectInput library and the fix is to use a DirectInput-to-DirectInput8 wrapper. In SilentPatch, I also took an alternate approach and fixed it
by changing the device enumeration to only list gamepads, so the game does not require a wrapper to run. As a bonus,
this also fixed an issue where the game enumerated… more than it should, even with dinputto8.
For example, on my PC it would even enumerate USB audio and AIO devices:
This has only been a highlight of the most noteworthy issues. The full changelog for all supported games is as follows;
fixes marked with can be configured/toggled via the INI file.
Essential fixes:
Locked all (NFS3/NFS Porsche) or specific problematic threads (NFS2SE/NFS4) to one core, while allowing worker threads to use any CPU cores - combining good stability and performance. This option has to be enabled by adding SingleProcAffinity=1 to an INI file named like the game’s executable. This change is fully compatible with Modern Patches and overrides its single core-affinity solution.
(NFS2SE) Fixed a potential race condition on starting the movie decoding thread.
(NFS2SE) Fixed a bug preventing controller button mappings from working correctly with gamepads that report more than 15 buttons (such as the Xbox One controller).
(NFS2SE) Fixed the game closing when the controller disconnects during the race.
(NFS2SE, Verok’s Modern Patch only) Fixed an issue where online races were displayed only on the top half of the screen as if they were split-screen races.
(NFS Porsche) Fixed a startup crash due to DirectInput controller enumeration being broken under specific circumstances on Windows 10 and newer.
(NFS Porsche) Fixed severe performance issues on Windows 10 and newer when rebinding controls.
(NFS Porsche, Verok’s Modern Patch only) Fixed unresponsive keyboard inputs after Alt + Tab during the race.
(NFS Porsche, Verok’s Modern Patch only) Fixed a severe memory leak in OpenGL1 and OpenGL3 thrash drivers occurring after every race.
Miscellaneous fixes:
Alt + F4 now works correctly.
Num Lock, Caps Lock, and Scroll Lock don’t get forcibly disabled on game launch anymore.
(NFS2SE/NFS3/NFS4) Fixed issues with stuttery/unresponsive mouse cursor in menus when using mice with high polling rates.
(NFS2SE/NFS3/NFS4) Fixed a controller polling bug resulting in potential incompatibilities with DirectInput wrappers such as Xidi.
Enhancements:
Pasting text into text boxes now works with Ctrl + V.
The modification can be downloaded from Mods & Patches. Click here to head to the game’s page directly. Each game page also links to their respective Modern Patch,
which I strongly recommend using together with SilentPatch. That said, they are not mandatory and SP is compatible with stock games too.
For those interested,
the full source code of the mod has been published on GitHub, so it can be freely used as a point of reference: See source on GitHub
]]>Remastering Colin McRae Rally 3 with SilentPatch2023-01-15T15:15:00+00:002023-01-15T15:15:00+00:00https://cookieplmonster.github.io/2023/01/15/remastering-colin-mcrae-rally-3-silentpatchTL;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.
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 😜
Chapter 1: In search of a perfect executable
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
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.
…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:
Because why not?
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.
Chapter 2: Regional releases and their oddities
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
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.35
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.
Chapter 3: Fixes, so many fixes
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:
W I D E
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 256x256 car shadow render target, downsample it to a smaller 128x128 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 backbuffer’s depth buffer!
Therefore, downsample draws used this as depth:
You don’t have to know what a depth buffer is to realize that this looks nothing like a car shadow.
In theory, this should only make draws fail if the top left part of the screen was obscured (making the depth test fail),
but with FSAA it gets worse since it resulted in matching a non-multisampled shadow buffer with a multisampled depth buffer. I don’t know exactly if D3D9
is required to handle this mismatch correctly, but seeing how this can break shadows in multiple ways – I suspect the results here are undefined.
SilentPatch fixes this issue and goes a step further – admittedly, those “sharp shadows” look kind of nice, but at the same time, I didn’t want to disable
the softening pass entirely. Thankfully, Colin McRae Rally 2005 reduces the number of soften passes from 8 to 2, making shadows a little sharper.
I “backported” this change to Colin McRae Rally 3, making shadows a little more defined:
If you prefer to keep the stock, blurrier shadows, this change can be disabled from the SilentPatchCMR3.ini file – by adding these lines at the very bottom of the file:
[Advanced]SHARPER_SHADOWS=0
A few stages in CMR3 run next to lakes or across rivers. At the highest details, those come with a nice cubemap-based reflection and a subtle animation,
producing an appearance of a reflective, moving water surface. However, on PC those reflections don’t always look the same:
From left to right - normal water, water after changing graphics options, water after Alt + Tab.
Depending on your actions, reflections may appear darker or even be completely black. I investigated this issue in detail, and it is caused not by one,
but three separate bugs! While one of them is a nitpick and may not even affect visuals, the other two are worth covering.
Presumably for performance reasons, the reflection cubemap is rendered only once, and it contains the sky and the horizon. This creates an issue during a device lost event,
i.e. when minimizing a fullscreen game window – historically, a device lost event invalidates all render targets, so they need to be recreated after restoring
the game window. CMR3 is aware of that and gracefully recreates most render targets – but not the reflection cubemap! This results in the reflection being pitch black,
making the water look horrendous. Making the game re-render the reflection after a device lost resolves the issue.
The other issue is also related to the device lost event, but it happens when the device resets (either due to Alt + Tab or a display mode change) outside of the race.
Since reflections are rendered at the start of the race, they should be unaffected by a reset in menus and render just fine. However, they are rendered slightly miscolored:
Left - reflections rendered correctly, right - miscolored reflections after a device reset.
Because of the one-shot nature of those reflections (and, of course, making them re-render every frame “fixes” this bug), it was extremely hard to catch on a graphics capture.
However, once done, PIX provided a hint – one of the lighting render states is different between the “good” reflection render and a “bad” one:
Left - correct reflections, right - miscolored reflections.
This essentially means that the scene is rendered to the cubemap with incorrect, possibly unpredictable, lighting – but why? The game code correctly sets the emissive
source before rendering the cubemap, and yet it’s still wrong.
The answer is slightly complicated, and it boils down to cache coherency. CMR3’s rendering engine has a layer of abstraction over Direct3D 9 designed to cache
the state the game wants to put the rendering pipeline at, and ensures that any state changes call reach D3D9 only when necessary. However, sometimes the game cache
needs to be evicted or updated, as the D3D9 runtime discards its state. One such event is… the device reset (emphasis mine):
Calling IDirect3DDevice9::Reset causes all texture memory surfaces to be lost, managed textures to be flushed from video memory, and all state information to be lost.
The developers behind a PC port of CMR3 were aware of this, so the game submits all cached render states to D3D9 again after a device reset,
therefore making sure that the runtime state matches what the game expects. Except… a few device states have been missed! Those are:
D3DSAMP_BORDERCOLOR - for all 8 samplers
D3DRS_EMISSIVEMATERIALSOURCE
D3DRS_BLENDOP
While I don’t know if the other two are ever used (despite being cached), D3DRS_EMISSIVEMATERIALSOURCE is the exact render state that is incorrect when
the reflections are dark. The fact they were not updated after a device reset means that the game thought the D3D9 runtime is in a different state
than it truly is, and thus it’s not setting the render state if it thought it’s “pointless” – hence the state cache losing coherency.
Fixing the Reset function to correctly reconcile those 3 missing states fixes the issue, so now water looks the same at all times:
This might not be Far Cry, but the water still looks nice.
If you’ve played CMR3 on PlayStation 2 or watched any footage of it, you may have noticed that the game looked a little more vibrant there,
most prominently when it comes to car reflections. Albeit present on PC and Xbox, they always seemed a little dull. To verify, I ran the same car and stage on PC
and in the PCSX2 emulator, and pulled the reflection data before and after it’s been mapped on a sphere:
They have clearly been rendered differently, but the most noticeable difference is in the sky – PS2’s reflection has a normal sky,
while on PC it’s always a grey box, except for night stages.
PS2 reflections are rendered in a really simple way:
Take the entire rendered frame up to the point of drawing reflections (that’s why the car shadow is present on the reflection).
Project that frame buffer on a sphere drawn to a separate render target.
Render the lens flare, if applicable.
PC opts for a more involved solution:
Clear a separate render target to grey, unless it’s a night stage. Oddly enough, instead of using a camera clear, this is done by drawing a rectangle spanning the entire render target – no idea why.
If it’s a night stage, render the sky.
Render most of the scene again with a very low draw distance.
Project that on a sphere drawn to yet another render target.
Render the lens flare, if applicable.
At first, it might seem like the PC reflections are done better, but I believe this change was made purely for technical, not visual, reasons.
Unlike on PS2, on PC taking a frame “rendered up to a specific point” is not trivial, especially with older rendering APIs like Direct3D 9.
Most games from the era render directly to a back buffer, and using that surface as an input resource for another draw (to project it on a sphere)
is virtually impossible without copying it, which can be a costly and/or memory intensive operation.
That’s not to say that doing it the PS2 way is impossible, of course – CMR3 could have rendered to a separate render target that is simultaneously
a render target and a texture. That does the trick, but comes with a few disadvantages:
A color target + depth target the size of a screen is required, which can take a lot of precious VRAM.
It is not possible to create a resource that is simultaneously multisampled, can be rendered to, and bound as an input resource. To keep multisampling,
yet another intermediate render target would be required.
Neither of those two is an issue for modern games (I implemented this exact thing in another game just a few months ago) – but the situation in 2003,
when you only had 32-64 MB VRAM to use, was likely very different.
What about the sky on PC, however? Once again it’s hard to say, but it is possibly a performance optimization, allowing reflections to draw less.
Curiously, split-screen uses a full sky in reflections – which I found peculiar until I remembered that the Xbox version uses identical reflections
and that split-screen on consoles runs at 30 FPS. If this truly was a performance optimization, then it may not have been needed when the target frame rate is lower.
For SilentPatch, I went ahead and enabled sky rendering for reflections at all times:
PC (with SilentPatch); 256x256 reflection & sphere
Not only does this change make the car reflections more vibrant, but it also “fixes” the TV displays in cutscenes – as they reuse the reflection map,
they now display the sky correctly!
If for some reason you prefer the stock reflections, this change can be disabled from the SilentPatchCMR3.ini file – by adding these lines at the very bottom of the file:
[Advanced]ENVMAP_SKY=0
(In)famously, Direct3D has no option of altering the line thickness of draws; therefore, line draws are always 1px thick. CMR3 uses lines widely (pun
unintended) – they are used both in 2D (in menus and graphs), and in 3D (for antennas). This wasn’t an issue on consoles, as well as on PC when played
at 640x480 – but the larger the selected resolution is, the more noticeable it becomes that those lines become relatively thin and hard to read.
SilentPatch resolves this issue by implementing line thickness:
The default CMR3 menus look notoriously inconsistent. SilentPatch fixes many inconsistently formatted texts (e.g. CONTROLS: on one screen, CONTROLS : on another)
and imperfect menu elements – with “line boxes” being exceptionally imperfect:
The stock boxes look like they have a ribbon in the bottom right IMO.
Just like the previous games in the franchise, Colin McRae Rally 3 comes with a split-screen feature. The issue is, on most modern PCs by default it looks like this:
That’s not what I meant when I said that I like the Horizon games.
This issue, fixed in Colin McRae Rally 04, can also be worked around by setting the game affinity to just a single core. However, since that’s not a threading issue,
this likely only buys the user some time, and in the future, this method might stop working too.
How was it fixed in CMR04? It’s one of the only fixes I’ve admittedly not understood fully, but it seems to be related to the physics update tick ending up at a
0 ms delta value (which means 0 ms have passed between updates). CMR04 seems to correct this by replacing relatively inaccurate timeGetTime functions with a more accurate
QueryPerformanceCounter; however, this wasn’t enough to fix CMR3, so I also additionally offset the first physics update tick by one second.
This means that the game thinks the very first physics tick took one second, but in practice, this changes nothing, as that one tick is performed just after the cars
are spawned – and this happens before the screen starts to fade from white.
CMR3 comes with support for multiple displays and allows the user to specify what display to render the game to, but unless all your displays are identical,
your typical multi-monitor experience was likely to look like this:
Yes, I would like to run the game at (NULL).
The addition of a Refresh Rate option in SilentPatch only made this issue worse, so despite using a single-display system myself, I had to take a look.
Turns out the issue is simple – although the game correctly refreshes the list of available resolutions as soon as you switch the selected display adapter,
it… doesn’t update the number of available resolutions. This, depending on whether the newly selected adapter has more or fewer display modes,
could result in either being unable to select the higher resolutions or in an instant crash (as shown above). SilentPatch fixes the issue by
updating the display mode counts and makes sure that the selected resolution cannot ever go over the number of listed display modes.
The last issue I wanted to highlight never showed up in the original game, but it’s somewhat fascinating, and could serve as a cautionary tale for other developers.
Initially, after implementing the windowed mode, I’d observe an issue where the game window flashes black every few seconds.
This only happened in normal windowed mode, and not borderless, even though the two are technically nearly identical.
I initially thought it was an issue caused by NVidia Shadowplay, as the issue seems to have been caused by something sending this series
of messages to the game window:
S WM_WINDOWPOSCHANGING lpwp:0019FA8C
R WM_WINDOWPOSCHANGING
S WM_ERASEBKGND hdc:0F01208B
R WM_ERASEBKGND fErased:True
S WM_WINDOWPOSCHANGED lIpwp:0019FA84
S WM_SIZE fwSizeType:SIZE_RESTORED nWidth:1280 nHeight:720
R WM_SIZE
R WM_WINDOWPOSCHANGED
S WM_GETICON fType: True
R WM_GETICON hicon:00000000
S WM_GETICON fType: True
R WM_GETICON hicon:00000000
S WM_GETICON fType:False
R WM_GETICON hicon:00000000
S WM_WINDOWPOSCHANGING Ipwp:0019FA8C
R WM_WINDOWPOSCHANGING
S WM_ERASEBKGND hde:7D0123DE
R WM_ERASEBKGND fErased:True
S WM_WINDOWPOSCHANGED lIpwp:0019FA84
S WM_SIZE fwSizeType:SIZE_RESTORED nWidth:1280 nHeight:720
R WM_SIZE
R WM_WINDOWPOSCHANGED
S WM_WINDOWPOSCHANGING Ipwp:0019FA8C
The key to understanding is the fact those are not position changes, but style changes – and sometimes I’d also see the window border
briefly change the style to the one used by windows that are hung. Indeed, the issue was essentially revealed by this feature of Windows:
Traditionally, Windows thinks the window is hung when its window messages are not pumped often enough, typically 5 seconds.
However, at no point, the game was truly unresponsive, and so the chain of events that I think has happened there is:
The game processes gameplay logic and renders.
The game waits for a message to arrive (without pumping).
If any messages are present, process them.
Repeat from point 1.
The issue lies in point 2. – the game somehow must be waiting for new messages without pumping them.
Therefore, Windows thinks the app is hung and sends several messages to indicate that fact via a window style change.
This in turn causes the game to spot that new messages are present, and process them; however,
processing messages is an indicator of a window that’s working normally, so that backtracks the “app is hung” state!
The cycle repeats every few seconds, causing periodic flashes.
The proper fix would be to always pump messages, without waiting for them – but since I wanted to keep the fix non-invasive
and at the same time comprehensive, I opted to “poke” the game window with an empty timer message every 2 seconds to keep
it always active. Not the cleanest, but makes it impossible to overlook any places in the code to patch, which arguably is
the highest priority when retrofitting fixes like this.
That said, please don’t implement this fix in your app – fix it properly instead 👼
New options
Starting with a small one – the game is now fully portable and saves settings to a SilentPatchCMR3.ini file located in the game directory,
instead of saving to the system registry. If you wished to put CMR3 on a flash drive and carry it with you, now you can.
Graphics Options have been expanded with several new options. My patches shipped with new options for a long time,
both SilentPatch for Colin McRae Rally 2.0 and
SilentPatch for TOCA 2 Touring Cars previously included
options like FOV control and more. However, this time those options are present in the game options.
The new options are:
Tachometer (Analog/Digital) – much like in CMR2.0, the tachometer is now customizable. The digital tachometer was previously exclusive
to 2 player split-screen.
Split-screen (Horizontal/Vertical) – another option inspired by CMR2.0. Previously, the game always used a horizontal split-screen
when playing in 4:3, and a vertical one when playing in 16:9; this means that the vertical split-screen remained unused on PC.
Since the game now adjusts itself to arbitrary aspect ratios, separating this into a new option made the most sense.
Field of View control – the default field of view for all in-game cameras is 75 degrees, and now I added an option to set
your preferred FOV in the range of 30 - 150 degrees. External and internal cameras get their separate options – something not done even
in DiRT Rally 2.0.
Digital tachometerVertical split-screen30 degrees FOV120 degrees FOV
Advanced Graphics Options have received a set of new options inspired by later CMR games and modern games in general.
This isn’t DiRT Rally 2.0, but a good old CMR3.
Those are:
Display mode (Fullscreen, Windowed, Borderless) – using the stock game’s windowed mode that remained unfinished in the code,
presumably a scrapped idea and/or a debug feature.
The new options default to English if you’re using an international or a Czech version, and Polish if you’re using a Polish version.
However, the Language Pack comes with translations for all new strings added to the game. Please check
Chapter 5: Merging regional releases together for more info.
Chapter 4: The perfect remaster – adding an HD interface
A set of fixes and perfect widescreen support make for a nice patch, but it’s not enough to call this a remaster. However, this changed once Bekoha offered
to work on retouching the UI and fonts in high quality. The original assets were clearly made with a 640x480 resolution in mind; so when playing at high resolutions
the game itself looked gorgeous, but the UI was lacking.
Feels like something is missing here.
Bekoha’s HD UI addresses this by replacing most interface assets with faithful high quality recreations:
More comparison screenshots (also showcasing SP’s widescreen support) can be found on Bekoha’s website: CMR3 HD UI Screenshots
Of course, if replacing textures was as easy as just putting them in the game, I wouldn’t be writing about it here, and someone else would’ve
likely released HQ fonts/UI years ago. Instead, to get HD textures to look the way we wanted them to, we had to solve not one, but three separate issues.
Scaling issues
Theoretically, replacing textures in CMR3 is easy. Font files are loose DDS files, while the UI textures are DDS files packaged in BigFile archives that have been
well understood for nearly two decades. However, a naïve texture replacement produces results that are hardly optimal:
In case you forget who is the sponsor.
Albeit unusual for PC games, this behavior is perfectly explainable. The original UI design was pixel perfect, with no scaling involved – which
means that all UI textures displayed 1:1 to what they are in files. For obvious reasons, this does not translate well to PC where the output resolution
is configurable, but there the draws only get linearly scaled, with the setup unchanged. This means that internally, the game still issues UI draws
using the texture dimensions as a draw size, producing oversize UI elements (screenshots #1 and #3), or specifying UV coordinates
in pixels directly, producing cut off elements (screenshot #2).
The solution here is simple – since the UI has already been “finalized” with specific texture dimensions in mind, scaling can be implemented trivially
by lying to the game about the texture sizes, and always pretending the texture dimensions are the same as the original!
Because the UV data sent to the rendering API is normalized, this lie allows the game to keep the internal
setup unchanged, while the actual rendering stays unaffected and makes full use of the high fidelity resource.
Font filtering
Contrary to a popular belief, upscaling is not always the best solution for a high quality interface.
Detailed textures benefit from it the best, but for pixel art there usually is a better solution – nearest neighbor scaling:
For any textures considered pixel art, scaling them via nearest neighbor filtering (as opposed to linear filtering) retains the effect of sharp pixels
without the need to ship assets that effectively duplicate pixels multiple times:
These are the same font assets, just filtered differently.
SilentPatch opts to always use nearest filtering on a set of textures and fonts predefined by us, so they look sharper than in the stock game even without the HD UI installed.
Half pixel issues
Direct3D 9 comes with a rather annoying texturing phenomenon dubbed “half pixel offset”, where textures display slightly wrong unless the draw is offset by half a pixel.
It has finally been corrected on the API level in Direct3D 10 and newer and it has never been an issue in OpenGL, so it’s a commonly overlooked issue – and CMR3 is no different.
The issue is documented very well, you can read about it more here:
While CMR3 is subject to this issue, with linear filtered textures I couldn’t spot it at any resolution.
However, it all changes once nearest filtering is used – textures appear blurry on the edges even though it should be impossible when nearest filtering is used
(top image). Applying that specific fix to all UI elements ensures they always stay as sharp as possible (bottom image). Pay attention to the blurred edges, especially on
1, L, and R:
This close to greatness… Click to open this image at 300% scaling, as, ironically, browsers use linear scaling when zooming in.
Chapter 5: Merging regional releases together
With all fixes and high definition UI in place, it was time for the icing on the cake – producing a single ultimate package of releases combining the regional editions,
not unlike what a real remaster could potentially do. For this, I only consider known official releases, so fan translations are not considered.
The Language Pack includes all 7 official translations (counting English), and 8 co-drivers, including the two Polish co-drivers presented above.
The Polish re-release also receives support for Nicky Grist’s pace notes much like the original Polish release, although due to the high file size, Grist’s audio files
are a separate download. All regional changes made for the Polish release, such as localized cube textures and the OSD keyboard, are also present;
not only that, but the Czech localization also receives its own OSD keyboard, while the official release did not:
Since the regional releases ship their own atlases of fonts, and the Polish release goes as far as updating the codepoints from Windows-1252 (Western Europe)
to Windows-1250 (Central Europe), the initial plan was to merge them all and update the game to use UTF-8. However, we ruled against it for several reasons:
The PCF format is not complicated to reverse engineer, but making a tool that can correctly repack it from a human readable format is another matter.
Changes like this can be extraordinarily risky and could potentially break compatibility with the existing saves and track records.
Even if they didn’t break compatibility with “old” records when SilentPatch is installed, it would be highly likely that “new” records would break the stock game.
Therefore, SilentPatch adds support for “regional” fonts for each language. Both Language Pack and HD UI ship Polish fonts in fonts/fonts_P, and Czech fonts in fonts/fonts_C.
These alternate sets of fonts are used regardless of whether the Language Pack is installed or not,
so the HD UI can only ship a single set of files that works for as long as SP is installed.
Aside from including regional languages and co-drivers, the Language Pack also improves the existing translations.
Therefore, it makes sense to install the Language Pack even if you don’t plan to use Polish or Czech localizations:
Codemasters introduced a “Return to Centre” option in the official 1.1 patch and hardcoded that string.
Language Pack extracts it to the localization files, so all languages now received a translated string.
The Telemetry screen hardcodes a “NA” text in the international release; this was later moved to the localization file for the Polish release.
Language Pack unifies this, and now all languages received a translated string.
The Polish release moved more key names (such as “Left”, “Right”, “Up”, and “Down” arrow keys) to the localization file.
Language Pack unifies this, and now all languages received a translated string.
Thanks to LoStraniero91, the Italian translation has been completely revised and uses more accurate and fitting translations.
Changelog and download
You made it all the way, congratulations 😁 (or maybe you just skipped to here from a TL;DR, that’s fine too)
The full mod’s changelog is as follows; fixes marked with can be configured/toggled via the INI file.
The other new options have been added to in-game menus instead.
Essential fixes:
The game now lists all available display resolutions, lifting the limit of 128 resolutions and the 4:3 aspect ratio constraint.
The game will now try to pick the closest matching resolution instead of crashing on startup if launched with an invalid resolution specified in the config.
The game now defaults to desktop resolution on the first boot.
Several issues related to the sun rendering have been fixed - sun flickering with anti-aliasing enabled has been fixed, and a consistent hitch when the sun was about to appear on screen was resolved.
Fixed multiple distinct issues causing water reflections to appear either too dark or completely black.
Fixed car shadows appearing overly sharp, or not appearing at all when anti-aliasing is enabled.
Fixed a crash when switching between display adapters with different numbers of resolutions, and made the resolutions list automatically refresh when switching adapters, eliminating a possible crash.
The game now handles arbitrary aspect ratios correctly - with all 3D elements and the entire UI fixed for widescreen and positioning dynamically.
Fixed a possible out of bounds read when the supplied translation file did not contain all the strings the game needs (for example, when using the PL executable with EN data).
Improved the overall precision of in-game timers.
Fixed an issue where split-screen would not work correctly on modern PCs with fast enough CPUs unless the game was forced to use a single CPU core.
Miscellaneous fixes:
Environment maps on cars now always reflect the sky, like on the PS2; making reflections look more natural and correcting an issue where the big TV screens displayed a grey sky.
Line rendering now respects the display resolution, making line thickness proportional to resolution and improving their visibility.
Half pixel issues have been corrected across the UI, improving the overall clarity of the interface, and fixing numerous issues where fullscreen backgrounds would leave a single pixel-wide line (or a seam in the middle) with multisampling enabled.
Improved the visual consistency of numerous race UI elements.
Improved the visual consistency of the digital tachometer by using a scissor feature for rendering, improving its accuracy and resolving a possible flicker.
Support for texture replacements and new fonts has been improved - the game can now handle higher resolution assets without glitching.
UI elements and fonts with sharp pixels now use nearest neighbor filtering instead of linear filtering for improved clarity.
Improved the presentation of line boxes used e.g. in the onscreen keyboard and Car Setup, fixing gaps, overlapping lines, and misplaced fill.
Legend lines on the Telemetry screen now fade out together with the rest of the menu.
Fixed numerous spacing inconsistencies in menu texts.
Fixed a broken split-screen Time Trial results screen (Czech executable only).
Fixed “Player X has retired” texts going off the screen at resolutions above 640x480.
Fixed an issue where the resolution change countdown went into negatives when fading out.
Fixed an issue on wider aspect ratios where repeated menu entries would not fade correctly.
Fixed an issue only showing in the Polish release where leaving the ‘Co-driver’s voice’ screen would flicker the menu animations.
Alt + F4 now works.
Removed a debug feature where invalid codepoints flickered randomly.
The error message displayed when the game fails to load specific game files now doesn’t freeze the game and can be closed with Alt + F4.
Enhancements:
The game is now fully portable, as the settings have been redirected from the registry to the INI file.
Car shadows are now slightly sharper, matching the way they are rendered in Colin McRae Rally 2005.
Menu navigation on the gamepad has been remapped from the analog stick to the directional pad like it is in the console releases.
New Graphics options added: Field of View (separate for external and internal cameras), Digital Tachometer, Vertical Split-screen.
Added support for all official text translations used together - English, French, German, Spanish, Italian, Polish, and Czech.
Added support for all official co-drivers together - English, French, German, Spanish, Polish (Janusz Kulig), Polish (Janusz Wituch), and Czech.
Re-added support for Nicky Grist’s pace notes in the Polish re-release.
Revised some capitalization inconsistencies in all languages.
Revised Italian translation.
Included translation lines for all new menu options added by SilentPatch.
HD UI - by Bekoha:
Made with 4K resolution in mind.
Font atlases remade using original fonts.
Support for EFIGS, Polish and Czech languages.
Banners redrawn for every stage.
Majority of in-game UI elements replaced.
I’ve created a brief showcase of the patch in video form, you can watch it here:
Unlike most of my other mods, installing this one is a little more involved. Due to the presence of DRM-free executables,
I only officially support those, and instead, I provide a ready solution to upgrade the latest official DRM’d executables to the DRM-free versions.
If you don’t do this before installing SilentPatch, you will be greeted with a warning message on startup.
The mod’s download page includes detailed setup instructions to walk you through this process step by step.
The modification can be downloaded from Mods & Patches. Click here to head to the game’s page directly: Download SilentPatch for Colin McRae Rally 3 (and addons)
Please follow the installation instructions carefully and extract the components into your game directory in order.
Not sure how to proceed? Check the Setup Instructions.
Credits and acknowledgments
Bekoha for the entirety of the HD UI work and general support
Krusantusz for help with the Polish eXtra Klasyka release
Various people contributing new translation lines in German, French, Spanish, Italian, and Czech
abbydiode and Cpone for additional testing
Several ex-CMR3 developers who are aware of this project and were able to share their feedback 🙂
For those interested, the full source code of the mod has been published on GitHub, so it can be freely used as a point of reference: See source on GitHub
Finding reasons to work on more patches even before this one is finalized 🙄 ↩↩2
Sounds very similar to how the sun lens flare was broken in the PC version of GTA San Andreas, right? ↩
]]>World Racing 2: Champion Edition releases on Steam!2022-12-08T18:10:00+00:002022-12-08T18:10:00+00:00https://cookieplmonster.github.io/2022/12/08/world-racing-2-champion-edition-releaseThis page contains affiliate links, meaning I get a commission for every purchase made through them.
I am happy to report that World Racing 2: Champion Edition, a digital re-release of World Racing 2
I’ve been working on has now been released on Steam, GOG.com and ZOOM Platform!
WR2CE offers the full experience and the classic gameplay of the original 2005 game, plus:
Custom unlicensed cars created by modifying the original 2005 game’s licensed ones, fitting in an unified “Synetic lore” of N.I.C.E., World Racing, and Crash Time
Revised environment art, placing the game’s sceneries in an unified “Synetic lore” of N.I.C.E., World Racing, and Crash Time
Numerous technical improvements that ensure smooth experience on both older and modern PCs
Support for ultrawide displays and modern controllers
Raised stock game limits and a 64-bit build, allowing for more extreme modding
Expanded Photo Mode
52 achievements
Full Steam Workshop support, building upon the original game’s modding capabilities and expanding them further
Steam Remote Play Together, allowing players to play split-screen online
Steam Cloud
I’m excited to see the reception of this release – while it’s far from my first commercial project,
it’s the first time I’ve been involved in production to this extent!
We potentially have more things planned for this release, so if there is a demand – this might not be the end 😉
]]>New release of Dreamcast Restoration 2.0 for Crazy Taxi2022-03-19T18:00:00+00:002022-03-19T18:00:00+00:00https://cookieplmonster.github.io/2022/03/19/crazy-taxi-dreamcast-restoration-r2Hey there! I’ve just released a new version of a Dreamcast Restoration 2.0 mod for Crazy Taxi.
The changelog is as follows:
Restored previously cut passenger voices referring to licensed destinations.
While I initially thought they were removed from the files, turns out I was wrong and they were locked off, just like everything else around these licenses.
Fixed Z-fighting on re-enabled FILA and Pizza Hut logos. This means they will not flicker anymore.
This release in action – Alexvgz published a teaser for restored voices a while ago. Now, with Z-fighting fixed, we’re finally making this release official:
Would you look at that, license voices have been restored! It only took 3 different crazy taxi port assembly just to find the code that was keeping them mute. pic.twitter.com/94Ji5tFmzO
Additionally, just yesterday Rinnegatamante published an update for his Crazy Taxi Vita that integrates Dreamcast Restoration 2.0!
In fact, his findings made this update possible, as I was finally able to fix the Z-fighting =)
Crazy Taxi Vita can be downloaded from VitaDB and requires a (free) copy of Crazy Taxi for Android.
Download
The modification can be downloaded from Mods & Patches. Click here to head to the game’s page directly:
For those interested,
full source codes of both mods has been published on GitHub, so it can be freely used as a point of reference: See Dreamcast Restoration 2.0 on GitHub
]]>Gran Turismo 4 Loose Chase Camera2022-03-15T19:10:00+00:002022-03-15T19:10:00+00:00https://cookieplmonster.github.io/2022/03/15/gran-turismo-4-loose-chase-cameraTL;DR - if you are not interested in an overview of those cheat codes,
scroll down to the Download section for download links.
Those who played Gran Turismo 4 are probably familiar with the issue at hand, but in case you didn’t – one of the changes
introduced in Gran Turismo 4 is a new chase camera. The previous games had a chase camera that would swing gently to the sides
in corners; while Gran Turismo 4 technically does the same, the camera is much “stiffer” and stays centered even when taking
corners at a very high speed.
As you may have guessed already, many people disliked the change, and sadly we never got an in-game option to customize
the camera (it took until GT Sport for this to become an option) – until now.
Interestingly, Polyphony made that change very late in development – GT4 First Preview, one of the demos released well after GT4 Prologue
still has a GT3-like chase camera!
I never before compared an "old" Gran Turismo chase camera with the "new" one introduced in GT4, so I wasn't sure how big of a deal it is. Now comparing GT4 and GT4 First Preview (still using "old" chase camera), the difference is indeed major. Interesting! pic.twitter.com/l4GgPLel6f
In the past, there have been attempts at bringing a GT3-style camera back to GT4, but none of them replicated the behaviour exactly.
With my approach, I investigated the exact differences between GT4 First Preview and the final GT4. For what I need,
I assumed that GT4 FP’s camera is exactly how a GT3-style camera would have behaved in GT4 had it not been changed last minute:
The chase camera works as if on a spring and it has two hardcoded parameters.
“Max angle” value determines how far the camera can lean before the spring effect stops it. Final GT4 sets this value to 15.0, GT4FP sets it to 10.0.
“Damper” value determines how fast the camera self-centers. Final GT4 sets this value to 120.0, GT4FP sets it to 30.0 – making the spring effect 4 times stronger in the final game!
With a cheat code modifying just those two values, GT4 First Preview’s camera is back in the final GT4 (and Tourist Trophy)!
But what if you wanted to customize the camera further? Since the cheat code I created is intended to be as user-friendly as possible,
adjusting parameters is trivial. For example, here I made the camera even stiffer than the default (“damper” set to 360.0), thus emulating the GT5/GT6 chase camera:
Far chase camera
Aside from the camera stiffness, GT4 Prologue and GT4 First Preview have one more difference – instead of the hood/roof camera, they have a second chase camera, located farther and higher from the car:
The final GT4 does not remove this camera entirely; instead, it is available as one of the replay cameras.
With another cheat code, I managed to add this camera back to the in-race selection as a new, fourth selectable camera:
Download
All listed cheats can be downloaded from Mods & Patches. Click here to head to the game’s page directly: