VOGONS


First post, by UCyborg

User metadata
Rank Member
Rank
Member

I've recently assembled a brand new patch for classic Max Payne games, solving one of the biggest technical issues with those games, in some cases preventing them from starting-up on modern systems without hacky workarounds like starting the game with affinity set to single core or worse, running them in compatibility modes. I'll probably upload the patch to PC Gaming Wiki as well. Straight from the ReadMe:

This patch is intended to solve issues related to game engine initializing Direct3D inside DllMain, which most notably causes the game to hang during startup with certain combinations of graphics hardware and drivers. Additionally, it is impossible to run the game through dgVoodoo Direct3D 8 to 11 wrapper, because Direct3D 11 runtime refuses to initialize from DllMain to prevent lockups.

The patch will solve above mentioned issues and possibly other problems that might be related to Direct3D initialization inside DllMain by delaying actual initialization to the point when execution flow returns from LoadLibrary API, therefore preventing any sort of lockup that would occur otherwise.

No compatibility modes should be applied to game executables, as they usually create more problems than they solve. Starting the game with affinity set to single core also isn't required anymore and will only serve to slow the game down a little.

Files in this archive are intended to use with latest version of games, which are:

Max Payne v1.05
Max Payne 2 v1.01

If you have Steam version of games, you should already have latest versions, otherwise, they must be updated with appropriate official patches before applying this patch.

To install, simply extract contents of each game's folder into your own, overwriting original files.

Last edited by UCyborg on 2017-01-23, 09:48. Edited 1 time in total.
Arthur Schopenhauer wrote:

A man can be himself only so long as he is alone; and if he does not love solitude, he will not love freedom; for it is only when he is alone that he is really free.

Reply 2 of 19, by lowenz

User metadata
Rank Oldbie
Rank
Oldbie

Can you make the same patch for 3DMark 2001 SE? (3DMark 2000 can already run with dgVoodoo 2).

Reply 3 of 19, by UCyborg

User metadata
Rank Member
Rank
Member
lowenz wrote:

Can you make the same patch for 3DMark 2001 SE? (3DMark 2000 can already run with dgVoodoo 2).

Will get to it. You just reminded me that I've read some time ago that older 3D Mark programs are based on MAX-FX engine. Just downloaded it and I see that it uses same DLLs as games, though checksums don't match with either fully patched games, so I suppose I gotta do it all over again, since due to the nature of working with disassembled code, you can't just do a copy-paste, even though the patches are identical for both games with exception of minor low-level differences.

Arthur Schopenhauer wrote:

A man can be himself only so long as he is alone; and if he does not love solitude, he will not love freedom; for it is only when he is alone that he is really free.

Reply 4 of 19, by lowenz

User metadata
Rank Oldbie
Rank
Oldbie

Obviously if you got the time! Thanks! (So we can test it with the pure D3D8.dll with the affinity trick, the Crosire D3D9 wrapper and dgVoodoo2 for D3D11).

These are the results with an OC'ed 1050 Ti

Pure D3D8:
D3_D8_1050.png

Crosire D3D8to9:
D3_D9_1050.png

It is really interesting, 'cause the wrapper overhead is largely exceeded by the D3D9 advantage givern by today GPUs drivers.

Reply 5 of 19, by UCyborg

User metadata
Rank Member
Rank
Member

3D Mark 2001 SE patch done: 3D Mark 99 Max & 2001 SE Startup Hang Patch

You actually don't need to change affinity with stock d3d8.dll thanks to this patch. On my weak laptop with AMD Radeon R2, I've noticed, without any FPS counters, that the game is a little smoother when run on all cores. It kinda makes sense since game's main thread isn't the only one that is part of the game's process so it helps if OS can schedule threads on any CPU it desires instead of everything being constricted to 1 core. And even before this patch, one could set affinity back to all cores when the game started up, but I don't think anyone ever thought of that.

Arthur Schopenhauer wrote:

A man can be himself only so long as he is alone; and if he does not love solitude, he will not love freedom; for it is only when he is alone that he is really free.

Reply 6 of 19, by DCX6723

User metadata
Rank Newbie
Rank
Newbie

Good job and thank you!

The 2 was huge payne on my computer, making the game randomly working when upgrading Windows.

Reply 7 of 19, by Lelasin

User metadata
Rank Newbie
Rank
Newbie

Good job!!!
Is it difficult to make such patches on their own? Can you advise any tutorials?

Reply 8 of 19, by UCyborg

User metadata
Rank Member
Rank
Member

You're all very welcome! There aren't any specific tutorials. You just somehow put the pieces together. Patching games that don't come with source code is a very specific kind of programming, or more like re-programming and needs the one to get familiar with x86 assembly language and studying disassembled code using tools like OllyDbg. You do find miscellaneous tutorials about certain tasks, but you're mostly on your own I think. I remember watching long time ago the tutorial that demonstrated how to make Notepad show a message box before it starts. The ones for demonstrating how to bypass copy protection in certain programs seem common, but I never found anything that demonstrated how some bugs were found and fixed in certain application/game. And the fact that every problem is unique complicates matters, plus the source code for most games is not available. When it's available, many improvements are possible, look at modern source ports of classic Doom and Quake games.

Generally, what little I've learned about programming, it all seems like some sort of complex puzzle. For example, you have a library with functionality that manipulate images, another for playing sound files and one that contains drawing routines and by combining functionality in all of them, you can make a game. It's really hard to explain and I'm not really good at these things, haven't really put anything particularly useful together from scratch. Improving other people's work is easier. I don't really understand how some people can just sit behind the computer screen and just write and write code, I usually struggle with simple things and like I said, every problem you're trying to solve programmatically is unique. Programming is essentially manipulating data that make the hardware produce the desired result. It probably takes a lot of practice, trial and error before you become proficient at it.

With this particular patch, it came down to understanding basic x86 assembly language, how Portable Executable format works (it's a container for Windows executable files and DLLs) and a couple of details from documentation on MSDN. So I thought, since I knew Max Payne did something in one of the DLLs' DllMain function, which is not supposed to be used for anything or just for really simple initialization, what if I could delay its execution by the time it would be safe to execute its functionality. So I put a variable in its DllMain where I store if the function was already called. If not, it means Windows called it as part of the game request to load its rendering library. When this happens, I bail out, since I know nothing complex (in this case, calls to Direct3D initialization routines) is supposed to be executed until the game's request to load said library is completed (otherwise you can get a deadlock), at which point, its initialization routine in DllMain can be executed without bad consequences. So by this point, I call it again on my own and this time, the check whether the routine was already called once passes and initialization completes instead of not doing anything like the first time. And no bizarre workarounds required.

This is really very special kind of problem and the only reason it came to it is the fact that developers chose to ignore documentation here: https://msdn.microsoft.com/en-us/librar ... s.85).aspx When you choose to ignore the guidelines, unexpected things can happen and since it works on one computer but not other, some people put the blame on the operating system or graphics drivers. Soulbringer had the same problem before I patched it and I've read that someone discovered the "fix" which includes putting older version of one of graphics driver DLLs in its game folder. Then another person tries it and wonders why the game randomly crashes with strange error. And for the third person, the game doesn't work at all.

Arthur Schopenhauer wrote:

A man can be himself only so long as he is alone; and if he does not love solitude, he will not love freedom; for it is only when he is alone that he is really free.

Reply 9 of 19, by gunshit

User metadata
Rank Newbie
Rank
Newbie

Thanks a lot for the patch 😄

Could you please share the source code so we can see the trick working?

Regards

Reply 10 of 19, by UCyborg

User metadata
Rank Member
Rank
Member

There is no source code, I modified the binaries with OllyDbg and Relocation Section Editor.

Arthur Schopenhauer wrote:

A man can be himself only so long as he is alone; and if he does not love solitude, he will not love freedom; for it is only when he is alone that he is really free.

Reply 11 of 19, by gunshit

User metadata
Rank Newbie
Rank
Newbie

I run Max Payne 2 (Steam version) with no issues for now.

Thanks for your effort and the explanation

Regards

Reply 12 of 19, by Splinter

User metadata
Rank Member
Rank
Member

Excellent patch, so thanks for the hard work. Solved my issue on windows 10 and original CDs.

http://www.compufixshop.com
Main rig Ryzen 2600X Strix RX580 32GB RAM
Secondary rig FX8350 GTX960 16GB RAM

Reply 13 of 19, by Splinter

User metadata
Rank Member
Rank
Member

Oddly enough, Max Payne 2 has stopped starting now with a message saying that Mp2 needs a Microsoft DirectX 9.0 compatible display adaptor.
I have the game on two machines with identical installations - patched to v1.01, widescreen fix and then this startup fix from the OP. No other changes have been made in the intervening months, apart from Windows updates, which I'm beginning to suspect to be the cause.
I even did an uninstall/reinstall of the game on one machine, but still receive the same DirectX message.
I'll try another clean game install and see what happens.

http://www.compufixshop.com
Main rig Ryzen 2600X Strix RX580 32GB RAM
Secondary rig FX8350 GTX960 16GB RAM

Reply 14 of 19, by Srandista

User metadata
Rank Oldbie
Rank
Oldbie

Are you playing on that FX CPU or some different one? Also, do you already update to Win 10 1909 (if you're using Win 10 at all)?

Socket 775 - ASRock 4CoreDual-VSTA, Pentium E6500K, 4GB RAM, Radeon 9800XT, ESS Solo-1, Win 98/XP
Socket A - Chaintech CT-7AIA, AMD Athlon XP 2400+, 1GB RAM, Radeon 9600XT, ESS ES1869F, Win 98

Reply 15 of 19, by Splinter

User metadata
Rank Member
Rank
Member

I'll have to update my sig:
Main rig Ryzen 2600X RX580
Secondary FX8350 GTX960
Both are running Windows 10 ver 1903 build 18362.476
What's odd is that I haven't played the game on either rig for a few months.
I did notice that when I go to uninstall the game (for a clean reinstall) the game version is showing 1.0.98, even though I extracted the 1.01 patch to the game directory since the patch is not self-running.
Correction: I found the executable patch 1.01.

http://www.compufixshop.com
Main rig Ryzen 2600X Strix RX580 32GB RAM
Secondary rig FX8350 GTX960 16GB RAM

Reply 16 of 19, by Srandista

User metadata
Rank Oldbie
Rank
Oldbie

Try reinstall GPU drivers.

Socket 775 - ASRock 4CoreDual-VSTA, Pentium E6500K, 4GB RAM, Radeon 9800XT, ESS Solo-1, Win 98/XP
Socket A - Chaintech CT-7AIA, AMD Athlon XP 2400+, 1GB RAM, Radeon 9600XT, ESS ES1869F, Win 98

Reply 17 of 19, by Splinter

User metadata
Rank Member
Rank
Member

Hi there and sorry for the late reply. Yes, my GPU drivers are up to date as of today's writing.
In fact, I reinstalled the game, patched it to 1.01 then added this hang patch, but I still get the same DX9 compatible display adaptor message.
This is most unusual.

Edit
Steam has both games on sale at the moment, so I grabbed them for less than $1, applied the startup hang patch to both games and MP 1 worked fine but I had to set MP2 compatibility to Win98 and now it runs.

http://www.compufixshop.com
Main rig Ryzen 2600X Strix RX580 32GB RAM
Secondary rig FX8350 GTX960 16GB RAM

Reply 18 of 19, by rolloLG

User metadata
Rank Member
Rank
Member

Is it possible to add a 60 fps cap for Max Payne 1 & 2 together with Widescreen fixes?
Workaround for Max Payne 1: https://steamcommunity.com/sharedfiles/filede … /?id=1934864423
but it doesn't work with Max Payne 2 which always v-syncs to actual screen refresh, while I'd like to cap it to 60fps....

Last edited by rolloLG on 2022-02-18, 11:24. Edited 2 times in total.


ROG-mini-22x13.png SCAR 18 G834JY: i9-13980HX, 32GB DDR5@5600, 4090 laptop 256 bit 16GB, 2560x1600 16:10 G-Sync, NVMe 6GB/s, 8BitDo Arcade Stick, EasySMX X10 controller, ROG Strix Carry Mouse.

Reply 19 of 19, by rolloLG

User metadata
Rank Member
Rank
Member

All of a sudden (it worked fine for months!) Windows 10 (19043.1526) + NVidia 511.65 refuse to launch the new exe for Max Payne 1 with a privilege error:
image.png
(Denied access - Accede with admin privileges and try again)

Old exe (unfixed) works fine but requires the usual workarounds.


ROG-mini-22x13.png SCAR 18 G834JY: i9-13980HX, 32GB DDR5@5600, 4090 laptop 256 bit 16GB, 2560x1600 16:10 G-Sync, NVMe 6GB/s, 8BitDo Arcade Stick, EasySMX X10 controller, ROG Strix Carry Mouse.