Soldier of Fortune
Install & patch the game
To install the required utils :
# apt-get install xxd
To install the game, mount your CD & run the installer with linux32
from the util-linux
package :
# mount /dev/cdrom /media/cdrom $ linux32 bash /media/cdrom/setup.sh
Apply the the last released patch :
$ linux32 bash sof-1.06a-cdrom-x86.run
Video crash
./sof
greets you with “Fatal signal: Segmentation Fault (SDL Parachute Deployed)”
The ref_gl.so library wants to print a list of OpenGL extensions available in your graphic driver. What's happening is that the buffer with the extensions is too large for the 8192 bytes allocated text-string use by vsprintf. The program crash after overwriting instruction memory with text data. The most simple way to fix this, is to never let vsprintf write the buffer. It's only a message console, it's never used for anything useful in the game!
You can do it graphically, using an hex editor, find “GL_EXTENSIONS: %s” and replace “%s” by 2 spaces.
Or you can do it in with xxd
:
$ cp ref_gl.so ref_gl.so.orig $ echo -n "2020" | xxd -r -p -seek 0x50245 - ref_gl.so
Audio crash
====== Soldier of Fortune Initialized ====== Fatal signal: Segmentation Fault (SDL Parachute Deployed) Segmentation fault
This one is a little bit more complicated…
sof-bin
use symbols from libX11.so.6
, itself linked to libXdmcp.so.6
. In modern Linux distribution, libXdmcp.so.6
is linked to libbsd0
. Current libbsd (version >= 0.7 to be precise) provide the symbol 'sl_add'.
But the liboasnd.so
file (provided and used by the game) also has a symbol named 'sl_add'. When liboasnd.so
calls 'his' 'sl_add', it use in fact the libbsd provided 'sl_add' function, and the game crash.
Option 1
Use a libxdmcp6 package from before the added dependency to libbsd0.
Option 2
Use elfhash to rename liboasnd.so
's sl_add symbol
$ cp liboasnd.so liboasnd.so.orig $ elfhash -f sl_add -t sl_adx liboasnd.so
Option 3
I used a Python script to rename liboasnd.so
's sl_add symbol:
# apt-get install virtualenv python3-pip $ virtualenv venv-pip $ . venv-pip/bin/activate $ pip install lief $ cp liboasnd.so liboasnd.so.orig
import lief liboasnd = lief.parse("liboasnd.so") for idx, lsym in enumerate(filter(lambda e : e.exported, liboasnd.dynamic_symbols)): if lsym.name == "sl_add": print(f"rename symbol {idx} {lsym.name} to 'sl_adx'") lsym.name = "sl_adx" liboasnd.write(liboasnd.name)
Optional: use sdl12-compat instead of bundled SDL-1.1
$ mv libSDL-1.1.so.0 libSDL-1.1.so.0.orig $ ln -s /usr/lib/i386-linux-gnu/libSDL-1.2.so.0 libSDL-1.1.so.0
Now you can start the game, but when you try to walk forward you will get extreme stuttering and a flashing ethernet icon.
This is cause by the combinaison of broken game logic & framerate over 120 (ie: you have a much more powerful computer than what was available when the game was released). The easiest way to fix this is to force VSYNC at the SDL level. This works for my hardware (it locks framerate at ~60), but I know there is already 360hz and higher monitors on the market, so it may not works for you.
$ LD_PRELOAD=libX11.so.6 SDL12COMPAT_SYNC_TO_VBLANK=1 ./sof