[Howto] Doom3 und OSS

B

beko

Guest
Moin,
das ist nun mein dritter Versuch diese paar Zeilen zusammen zu tippseln.
Wehe der Kram verreckt wieder mitten drin ;)

Eckdaten:
Linux: 2.4.27
Nvidia: 1.0-6111
Alsa*: 1.0.6a

*mit OSS-Emulation

Problem 1:
WARNING: failed to open sound device '/dev/dsp': Device or resource busy

Lösung 1:
Ein Gerät blockiert noch die Soundkarte. Mit großer Wahrscheinlichkeit ist
der Übeltäter ein Sounddaemon wie artsd oder esd. Wer diesen nicht
abschalten möchte hat die Möglichkeit das Startscript doom3/doom3-demo ein
wenig zu erweitern:

Originalzeile: exec ./doom.x86 "$@"
Möglichkeit 1: artsdsp -m ./doom.x86 "$@"
Möglichkeit 2: esddsp ./doom.x86 "$@"
Möglichkeit 2: <insert your soundserver here>

Da ich zwar KDE nutze, aber den artsd doch etwas zuviel des Guten finde,
verzichte ich auf diese Lösungen und arbeite mit OSS.

Problem 2:
WARNING: mmap 57344 bytes on device /dev/dsp failed: Input/output error

Lösung 2:
Wie bei ID-Games üblich hilft folgender alter Trick (siehe et, quake usw):

echo "doom.x86 0 0 direct" > /proc/asound/card0/pcm0p/oss

Problem 3:
WARNING: ioctl SNDCTL_DSP_SPEED failed to get the requested frequency 44100,
got 48000

Lösung 3:
Scheinbar ist meine gute alte OnBoard Soundkarte nicht in der Lage die
Abspielfrequenz zu ändern. Eine neue und bessere Soundkarte könnte das
Problem lösen, doch bin ich nicht bereit wegen einem einzigen Spiel eine
neue Soundkarte zu kaufen wenn doch sonst alles wunderbar mit der
bisherigen zurecht kommt. Hier hilft folgender Hack, den ich auf
http://www.linuxgames.com/news/feedback.php?identiferID=6962&action=flatview
von Anonymous gefunden habe:
I see I'm not the only one to get this error:

WARNING: ioctl SNDCTL_DSP_SPEED failed to get the requested frequency
44100, got 44101

I don't have a sound server, and use pure OSS (no alsa emulation).
Apparently it is caused by low-quality sound chipset, or bad drivers, that
are not able to provide the requested frequency (due to limitations or
round-off errors), and return the closest frequency they can handle. It
should not be really an error, but Doom3 decides that for 1Hz of
difference, it won't play sound :/

I propose a... radical fix: patch the doom3 binary so that it doesn't
compare the returned value with the expected one, and act as if it was OK.

I don't assume any problem this could cause to your system !!

You will need a hexadecimal editor for that; I used "hexcurse" (text-mode).
- You should know where you installed doom3, and go to this directory.
- DO A BACKUP of the original "doom.x86" binary in a safe place elsewhere.
- You may need to be root to modify the file. In this case you should better
do a copy of the file as a normal user, edit it as described with this
user, and overwrite it back as root when you are done.Less chance to do
errors as root...
- open the file with "hexcurse doom.x86"
- Go to the byte to modify by typing "Ctrl-G" and entering the address ; for
doom3, it is address 001BED1B ; for doom3-demo, it is 001BE3FB.
- Modifiy the "74" under the cursor to "EB".
- Save (Ctrl-S) and quit (Ctrl-Q)
The md5sum of the modified binary is now:
a4b9c37eef2ad5142b9c88f0447bb52a for the complete version
3cb21789bd262ef6f4b451cce8559239 for the demo version.
If not, you made an error; restore the backup file and start again.

Now doom3 should ignore any difference in the frequency settings. It worked
OK for me because I have only a 1Hz difference; if you have more, I don't
know how it will behave...

For those interested/who want to be sure I didn't just install a virus in
their binary :) here is the explanation:

I used "objdump -d doom.x86 > doom_disassembled.txt" to get the disassembled
(machine instructions) version of the program. the SNDCTL_DSP_SPEED ioctl
has for value 0xc0045002. There is only 1 occurence of this value in the
code. Reading the disassembled output around leads to:


8206ce5: bf 02 50 04 c0 _______ mov $0xc0045002,%edi <--
SNDCTL_DSP_SPEED ioctl code
[... some more parameter passing ...]
8206d05: e8 1a 42 e4 ff _______ call 0x804af24 <-- call the ioctl
function
8206d0a: 40 ________________ inc %eax
8206d0b: 0f 84 7e 02 00 00 ____ je 0x8206f8f <-- test if return value is
-1 (error)
8206d11: 8b 4e 10 _______________ mov 0x10(%esi),%ecx
8206d14: 3b 8c 24 a4 00 00 00 _____ cmp 0xa4(%esp),%ecx <-- compare a
passed parameter to a returned value (the 44100 Hz)
8206d1b: 74 24 __________________ je 0x8206d41 <-- if equal, continue
code somewhere
[... else fall through the warning code and sound disabling ...]


My patch replace the test by an unconditionnal jump:

8206d1b: eb 24 _____ jmp 0x8206d41


which never cares about the comparison.

(Disclaimer: this "reverse-engineering" was done purely for interoperability
purpose, so should be legal (at least here in Europe) )

Eine Alternative zu hexcurse ist übrigens hexedit, was ich bevorzuge. Wer
nicht bereit ist diesen doch etwas radikalen Schritt zu riskieren kann sich
mit artsdsp (siehe Lösung 1) behelfen:

-m, --mmap emulate memory mapping (i.e. for quake)

So, ich hoffe ich spare einigen Leuten das gegoogle ;)
 
Oben