-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a command-line (Linux) version, and Auto-resolution mode #1
base: main
Are you sure you want to change the base?
Conversation
The .NET version doesn't work properly for me under wine/mono, complaining about some GDIPlus font function not being available. Hack together a command-line program which does the same thing. The EXE_RESOURCE needs to be extracted and passed as an arguement. This can be done with wrestool on the windows/.NET PharaohResizer.exe file: wrestool PharaohResizer.exe -x --type='EXECUTABLE' --name=101 The new PharaohResizer.c program will lz4 decompress this, and patch the resolution in.
As extracting the EXE_RESOURCE is a bit of a pain, add support for using an original (albeit stripped of any DRM wrappers) version of the Pharaoh.exe from Cleopatra as a base, and apply the patches directly to that. If such an executable is not provided, the input is assumed to be the extracted EXE_RESOURCE. The various patches applied to PharaohResizer.exe's embedded version are replicated here in the DoCrudeliosPatches() function: it's an impressive bit of patching I admit to not fully understanding, so kudos! This was tested against the GOG executable -- which is the only version of Cleopatra I have -- and it produced an executable identical to the embedded one save for GOG's patched website address.
If a resolution is not specified, instead patch in some code to determine it at runtime from calls to GetSystemMetrics(). This seems to work fine on my machine, but probably needs testing on others: it could be less reliable at some strange resolutions, or on multi-monitor setups which are different to mine (i.e., wine with two 1440x900 monitors side-by-side). This mode can be activated by simply not passing a width and height into the program. (I've also added a default output filename of PharaohNew.exe, so that you only need to pass the path to Pharaoh.exe or the extracted EXE_RESOURCE to get something which works. This should even -- in theory -- allow windows users to drag-and-drop Pharaoh.exe onto this binary, were it compiled for windows, and have a PharaohNew.exe appear.)
This is really nice, thank you very much! I'll have a look at the code eventually, though I'm not sure exacly when as right now I'm drowned in work and really tired. I do like your changes though as they don't require a previously patched exe and they can be easily adapted for Windows as well. |
No worries: things are getting pretty busy here at the moment, too, so I'm definitely not in any kind of hurry to see anything. :-) I may push some more changes to this branch/PR if I do get time to do anything else — it doesn't seem like it'd be worth splitting anything into separate PRs at this point. But I can't think of anything likely to happen soon. |
I have to be honest, I totally forgot about this PR. I'll have a look at it ASAP! 👍 |
I am interested in this Linux version as I have the EXE file outputed by the resizer running on wine crashes after the Breakaway Game logo when I start the game. Moreover, I use the French version of the game and I have seen on the now closed wsgf forum that a version of the resizer for the French version of the game had been made. I am willing to help make a Linux FR version any way I can. Let me know if there is any way I can help. |
Impressive work you've done, @sulix! By the way, what is a SML file? I tried to decompress it with lz4, but I It would be nice if @crudelios commented his patches. I would be very |
@matteobin I did this years ago, but basically the sml file was my own file format, it's a simple raw compression of the exe using the library provided with this tool. When an exe is generated using the resizer, it simply decompresses the sml file and changes the bytes for the resolution. So you can use a generated exe from pharaohresizer as a base for another resolution changer. @Vartaghan The PR version of pharaoh is completely different than the English one. I did provide a modified French version, but it's an older patch with way fewer features. Considering updating the patch to be on par with the English version requires an awful amount of hacking, I don't think it's worth doing it. |
Yeah: "extracting" the patches involved doing a diff of a patched and unpatched executable, then sanity checking the changes against a disassembly. Alas, I never got around to working out the details of them any further than the comments in that function. If I recall, the game had two ways of dealing with the resolution: some parts used a "resolution id" (1 == 640×480, 2 == 800×600, 3 == 1024×768), and then there were actual width and height variables. (In fact, there were a few copies of each of these). Most of my personal reverse-engineering of Pharaoh was from the CD version, without the Cleopatra expansion, though, so I don't actually have a good label for what @crudelios's patches actually did. I imagine they mostly replaced code which looked up the resolution ID, and placed things in hardcoded locations with code which calculated a position based on the width and height. Similarly, I don't actually have a French executable around (and, alas, probably wouldn't have the time to patch it properly even if I did), but I'd expect it'd involve:
As you can tell, it's a fair bit of machine-code patching. And you're still left with issues like crashes on multiprocessor systems (upgrade the Miles DLLs and/or pin the process to one core), and Linux stack incompatibilities (though wine works around this). |
@sulix That's exactly what I did. The game checked for static resolution values and did everything statically, while I made everything dynamic. As you guessed, that's a lot of new code. I did think about commenting my changes but never got around to it, and now, 7 years later, I don't really remember what I did lol. Curiously, I found a bug with the empire map where the bottomost 16 or so pixels of the map wouldn't register mouse inputs. This is nearly irrelevant on the default resolutions, but the amount of unregistered pixels increases with the resolution. So at things like 1920x1080, the bottom third of the empire map was unclickable until I fixed the issue. |
I couldn't get PharaohResizer.exe running easily on a stock wine install under Linux, so have done this quick-and-dirty command-line Linux version. It works either with an extracted version of the
EXE_RESOURCE
from the windowsPharaohResizer.exe
, which it'll decompress and patch the resolution in, or can patch a DRM-unencumbered version of the original CleopatraPharaoh.exe
(such as the version sold from GOG) from scratch.It builds as a simple command-line program on Linux (and should be trivially compilable on basically anything else with LZ4 available), with the following command line options:
It also adds an "Auto-resolution" mode where — if no resolution is specified when patching — some code is patched in to use the current desktop resolution. This is not very well tested, but works okay as a fallback on my machine.
I know you probably don't want to be stuck maintaining something hacky like this, so feel free to ignore it if you'd prefer, but I thought I'd throw it out here in case you or anyone else happen to be interested! Either way, thanks a lot for PharaohResizer: it's a phenomenal piece of patching!