Jan 162018
The Red Solstice logo

1.) Introduction

Yes, it’s another one of “those” posts. Reason for this is, that Humble Bundle is currently [giving away] the crowdfunded title “The Red Solstice” for free, so I picked up a copy to see whether I could get it to work on Windows XP x64 (and also 32-bit XP). Why not, right? Ah, you need Steam for this by the way.

This game is the first one I’ve seen on the Desktop which is actually using OpenGL ES instead of OpenGL or just Direct3D. Typically, that API is more widespread on mobile devices running Android or something, as it’s slimmer and brings a reduced feature set of the “real” OpenGL to the table. The bundled version is OpenGL ES 2.0, and instead of some modern GPGPU language like HLSL it uses nVidias’ old Cg library, which is luckily compatible with XP. The game developer [Ironward] seems to claim that this game, which is based on something called the “TRSEngine” needs Windows 7 or newer to run however.

2.) Required tools

To be able to reproduce the hack described in this post you will need the following tools:

3.) Fixing the platform target

The game has been compiled for a NT 6.0 or Windows Vista platform target, so launching it as-is will result in the dreaded “not a Win32 application” error:

The Red Solstice is "not a valid Win32 application" on XP

Hey, it’s not a Win32 application! Pfh, as if…

The fact that the program was built with an NT 6.0 platform target doesn’t necessarily mean that it actually needs any modern functions of Vista/7/8/10, so the first step is usually to fix the binary headers and change that platform level to something lower, usually 5.1 (XP) for 32-bit code or 5.2 (XP x64 / Server 2003) for 64-bit code. The Red Solstice is a 32-bit game, so it’s going to be 5.1. Sometimes, this can be enough.

As an example, launch CFF Explorer and open the Game.exe from the games’ installation folder, then click on Nt Headers -> Optional Header. I’ve marked the important parts in red for you:

The Red Solstice stock Game.exe

The Red Solstice stock Game.exe (click to enlarge)

To fix this, change the values from 0006 and 0000 to 0005 and 0001, this corresponds to changing the required platform from NT 6.0 to 5.1.

Game.exe with modified binary header

Game.exe with modified binary header (click to enlarge)

After the change, save and overwrite the existing file, but create a backup first, if you wish to be able to revert from the change quickly.

Fixing that one file won’t be enough though. In total, you’ll need to apply the hack seen above to the following files:

  • Game.exe
  • icudt51.dll (Unicode library)
  • icuin51.dll (Unicode library)
  • icuuc51.dll (Unicode library)
  • libEGL.dll (Platform-specific glue layer for OpenGL ES on Windows)
  • libGLESv2.dll (OpenGL ES 2.0)
  • libogg.dll (OGG vorbis audio decoder)
  • libtheoraplayer.dll (Theora audio decoder)
  • OpenAL32.dll (OpenAL audio API)
  • Qt5Core.dll (Qt5 2D GUI library)
  • Qt5Gui.dll (Qt5 2D GUI library)
  • Qt5Widgets.dll (Qt5 2D GUI library)
  • platforms\qwindows.dll (Platform-specific glue layer for Qt5 on Windows)

It’ll take about 1-2 minutes to fix all of them I guess. However, if you attempt to run the game after that, it’ll still fall on its face with a different error:

The XP kernel API doesn't provide GetTickCount64()

Ah, GetTickCount64() is actually an [old acquaintance] of mine by now…

Inspecting the Game.exe with Steve Millers’ Dependency Walker shows, that the problem is actually limited to GetTickCount64(), so it’s the one and only missing kernel API function call we’ll have to deal with:

Tracking the dependencies of Game.exe brings up a missing GetTickCount64() call in kernel32.dll

Tracking the dependencies of Game.exe brings up a missing GetTickCount64() call to kernel32.dll, but no other problems. (Click to enlarge)

Alright, let’s get to it!

4.) Fixing the GetTickCount64() call

This is a bit trickier, as we need to present a GetTickCount64() function to the game, that will do something useful. For this we’ll use Oleg Ovcharenkos’ Stellaris hack, which allows us to redirect that missing call to the legacy GetTickCount() that Windows XP does have.

Unpack the software into some directory of your choice and copy the Game.exe of “The Red Solstice” into that directory as well. Olegs’ hack isn’t prepared for this game yet, so copy one of the existing scripts such as xp_Stellaris_1.6.cmd to a new script file, e.g. xp_TheRedSolstice_1.6.cmd. Open the file in your favorite text editor, and make sure it contains exactly and only the following lines:

rundll32 zernel32.dll,PatchFile Game.exe

Save the file, and run it by double-clicking on it or by launching it directly from a command line terminal. It’ll patch the game so it calls the stub DLL zernel32.dll and some other z* libraries, which fixes some missing calls and redirect the rest to the platforms kernel API as-is. It’ll also create a backup copy of Game.exe for you. Now you have to copy the following files from the folder containing Olegs’ hack back to the actual game folder:

  • Game.exe
  • zernel32.dll
  • zs2_32.dll

That’s it!

5.) Finally: Running the game on XP

With the platform target hack done with CFF Explorer and the GetTickCount64() => GetTickCount() redirection done by Olegs’ Stellaris hack we can finally launch the game:

The Red Solstice fired up on Windows XP x64

The Red Solstice fired up on Windows XP x64 (click to enlarge)

I have to say that I haven’t tested this extensively so far, but a few brief gameplay tests have been conducted:

Gameplay test

Gameplay test (click to enlarge)

There you go, another modern game hacked to run on ancient Windows XP & XP x64! Beer Smilie

Aug 032016
xmms logo

Yeah, I’m still using the good old xmms v1 on Linux and UNIX. Now, the boxes I used to play music on were all 32-bit x86 so far. Just some old hardware. Recently I tried to play some of my [AAC-LC] files on my 64-bit Linux workstation, and to my surprise, it failed to play the file, giving me the error Pulse coding not allowed in short blocks when started from the shell (just so I can read the error output).

I thought this had to have something to do with my file and not the player, so I tried .aac files with ADTS headers instead of audio packed into an mp4/m4a container. The result was the same. Also, the encoding (SBR/VBR or even HE-AAC, which sucks for music anyway) didn’t make a difference. Then I found [this post] on the Gentoo forums, showing that the problem was really the architecture. 32-bit builds wouldn’t fail, but the source code of the [libfaad2] decoding library of xmms’ mp4 plugin wasn’t ready for 64-bit.

xmms’ xmms_mp4Plugin-0.4 comes with a pretty old libfaad2, 2.0 or something. I will show you how to upgrade that to version 2.7, which is fixed for x86_64 (Readily fixed source code is also provided at the bottom). We’ll also fix up other parts of that plugin so it can compile using more modern versions of GCC and clang, and my test platform for this would be a rather conservative CentOS 6.8 Linux. First, get the source code:

I’m assuming you already have xmms installed, otherwise obtain version 1.2.11 from [here]!

Step 1, libfaad2:

Unpack both archives from above, then enter the mp4 plugins’ source directory. You’ll find a libfaad2/ directory in there. Delete or move it and all of its contents. From the faad2 source tree, copy the directory libfaad/ from there to libfaad2/ in the plugins’ directory, replacing the deleted one. Now that’s the source, but we also need the updated headers so that the xmms plugin can link against the newer libfaad2. To do that, copy the two files include/faad.h and include/neaacdec.h from the faad2 2.7 source tree to the directory include/ in the plugin source tree. Overwrite faad.h if prompted.

Step 2, libmp4v2:

Also, the bundled libmp4v2 of the mp4 plugin is very old and broken on modern systems due to code issues. Let’s fix them, so back to the mp4 plugin source tree. We need to fix some invalid pure specifiers in the following files: libmp4v2/mp4property.h, libmp4v2/mp4property.cpp, libmp4v2/rtphint.h and libmp4v2/rtphint.cpp.

To do so, open them in a text editor and search and replace all occurences of = NULL with = 0. This will fix all assignments and comparisons that would otherwise break. When using vi or vim, you can do :%s/=\sNULL/= 0/g for this.

On top of that, we need to fix a invalid const char* to char* conversion in libmp4v2/rtphint.cpp as well. Open it, and hop to line number 325, you’ll see this:

  1. char* pSlash = strchr(pRtpMap, '/');

Replace it with this:

  1. const char* pSlash = strchr(pRtpMap, '/');

And we’re done!

Now, in the mp4 plugins’ source root directory, run $ ./bootstrap && ./configure. Hopefully, no errors will occur. If all is ok, run $ make. Given you have xmms 1.2.11 installed, it should compile and link fine now. Last step: # make install.

This has been tested with my current GCC 4.4.7 platform compiler as well as GCC 4.9.3 on CentOS 6.8 Linux. Also, it has been tested with clang 3.4.1 on FreeBSD 10.3 UNIX, also x86_64. Please note that FreeBSD 10.3 needs extensive modifications to its build tools as well, so I can’t provide fixed source for this. However, packages on FreeBSD have already been fixed in that regard, so you can just # pkg install xmms-faad2 and it’s done anyway. This is likely the case for several modern Linux distros as well.

Let’s play:

xmms playing AAC-LC Freebsd 10.3 UNIX on x86_64

Yeah, it works. In this case on FreeBSD.

And the shell would say:

2-MPEG-4 AAC Low Complexity profile
MP4 - 2 channels @ 44100 Hz

Perfect! And here is the [fixed source code] upgraded with libfaad2 2.7, so you don’t have to do anything by yourself other than $ ./bootstrap && ./configure && make and # make install! Ah, actually I’m not so sure whether xmms itself builds fine on CentOS 6.8 from source these days… Maybe I’ll check that out another day. ;)

Feb 062012

config.mak with ldflagsOn Friday I tried to compile, install and run x264 with libav support strictly with user privileges on Linux, so no root, no write permissions to /usr/lib, /usr/include, /usr/bin or whatever. I thought this was going to be tricky and I have never done that before. But if I get that access to that Itanium² machine on our university, I need to be able to do that to install x264 without any root privileges. So what you need to do is add -L and -I options to your CFLAGS and CXXFLAGS environment variables to make the GNU C and C++ compilers search for headers and libraries in specific subdirectories in your users home directory. So I created a ~/build folder, and first built libav using the configure option --prefix=~/build. The flags on my test machine were like this:

$ export CFLAGS="-march=native -O3 -ffast-math -mssse3 -pipe -L~/build/lib -I~/build/include"
$ export CXXFLAGS="-march=native -O3 -ffast-math -mssse3 -pipe -L~/build/lib -I~/build/include"

But that alone is not enough…  Continue reading »