[Bug 39272] Homeworld Remastered crashes on unimplemented function msvcp110.dll._FExp

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Oct 4 13:15:30 CDT 2015


https://bugs.winehq.org/show_bug.cgi?id=39272

Andrew D'Addesio <andrew at fatbag.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrew at fatbag.net

--- Comment #2 from Andrew D'Addesio <andrew at fatbag.net> ---
I installed Windows 98SE on my spare PC (with a Radeon Xpress 200 chipset) and
ran the tool for three versions of DirectX:
* The stock DirectX: 6.1a, 4.06.03.0518, 1999-04-23
* DirectX 7.0, 4.07.00.0716, 1999-09-09
* DirectX 8.1, 4.08.01.0881, 2001-10-30

For each version of DirectX, I ran the tool with and without the
"EnumReference" and "EnumNullDevice" registry settings.

The results are:
* (IDirect3D 1&2 only) "Ramp Emulation"
* (All interfaces) "RGB Emulation"
* (All interfaces) "Direct3D HAL" (requires driver support)
* (IDirect3D 2 only) "MMX Emulation"
* (All interfaces) "Reference Rasterizer" (DX 6-8 only and requires
"EnumReference" with nonzero value, briefly mentioned in KB249579)
* (All interfaces) "Null device" (DX 6-8 only and requires "EnumNullDevice"
with nonzero value, mentioned in DX 6&7 SDKs)
* (IDirect3D 7 only) "Direct3D T&L HAL" (DX 7+ and requires driver support)

It appears that DirectX 9 and onwards no longer recognize the "EnumReference"
and "EnumNullDevice" settings as I wasn't able to get these devices to show up
in Windows XP SP3 (32-bit) on the same machine.

So we would like to add support for these games:
* Resident Evil
* Carmageddon 2 demo
* The Sims Online

without breaking these games:
* Moto Racer 2
* Aliens versus Predator
* GTA 2
* Rollcage
* Donald Duck: Goin' Quackers

The current comments in d3d3_EnumDevices present these issues:
a. Motoracer 2 depends on the device names being in writable memory.
b. AvP / Motoracer 2 (both Direct3D1 games) break if the reference rasterizer
is enumerated.
c. GTA 2 (presumably Direct3D3) depends on the HEL device being the first
enumerated device and the HAL device being the second enumerated device.
d. Rollcage (Direct3D2) tells which is the HAL device and which is the HEL
device solely by looking at hal_desc and hel_desc. When it receives a device,
it knows that it's looking at the correct device description (hal_desc on the
HAL device or hel_desc on the HEL device) if and only if the "Power-of-2
textures only" limitation is set. Once it's looking at the correct description,
it discards all devices which have the "perspective correction" flag
(presumably) set.
e. Donald Duck: Goin' Quackers identifies the devices by the names "Direct3D
HAL" and (presumably) "Direct3D HEL".

So, I downloaded the Moto Racer 2 Demo:
http://download.cnet.com/Moto-Racer-2-updated-demo/3000-2115_4-10025083.html

I verified that the game installs and runs in Wine 1.7.51-git on Linux (Fedora
22).

### Issue a

I have personally verified issue a: If you replace the instances of
"device_name" with string literals, the game demo segfaults immediately upon
start (eip=00424875). I undid my change and the game resumed working.

### Issue b

I then replaced "if (ddraw->d3dversion != 1)" with "if (1)" in order to
enumerate the HEL device and changed all of the TRACE messages to FIXMEs so
that they would appear in the terminal. Even with this change, the game still
works for me; here is the output:

> fixme:ddraw:d3d1_EnumDevices iface 0x133da4, callback 0x424814, context (nil).
> fixme:ddraw:d3d3_EnumDevices iface 0x133d9c, callback 0x424814, context (nil).
> fixme:ddraw:d3d3_EnumDevices Enumerating WineD3D D3DDevice interface.
> fixme:ddraw:d3d3_EnumDevices Enumerating HAL Direct3D device.
> fixme:ddraw:d3d3_EnumDevices End of enumeration.

Changing "Direct3D HEL" to "RGB Emulation" has no effect; in fact, renaming
both devices to "foo"/"bar" has no effect. So, I thought, "maybe it breaks on
one of the other HEL IIDs."

Currently, ddraw.c says this:

>    /* Do I have to enumerate the reference id? Note from old d3d7:
>     * "It seems that enumerating the reference IID on Direct3D 1 games
>     * (AvP / Motoracer2) breaks them". So do not enumerate this iid in V1

It turns out that the mentioned comment was created way back in May 2003:

https://www.winehq.org/pipermail/wine-patches/2003-May/006228.html
http://cvs.winehq.org/cvsweb/wine/dlls/ddraw/d3ddevice/Attic/mesa.c?rev=1.96&content-type=text/x-cvsweb-markup

> +    if (version > 1) {
> +        /* It seems that enumerating the reference IID on Direct3D 1 games (AvP / Motoracer2) breaks them */
> +        TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice));
> +        d1 = dref;
> +        d2 = dref;
> +        ret_value = cb((LPIID) &IID_IDirect3DRefDevice, "WINE Reference Direct3DX using OpenGL", device_name, &d1, &d2, context);
> +        if (ret_value != D3DENUMRET_OK)
> +            return ret_value;
> +    }

If the D3D version is not 1, then enumerate IID_IDirect3DRefDevice.

Yet, the present code does this:

>    /* Do I have to enumerate the reference id? Note from old d3d7:
>     * "It seems that enumerating the reference IID on Direct3D 1 games
>     * (AvP / Motoracer2) breaks them". So do not enumerate this iid in V1
>     * ... */
>    if (ddraw->d3dversion != 1)
>    {
>        /* ... */
>        hr = callback((GUID *)&IID_IDirect3DRGBDevice, reference_description,
>                device_name, &hal_desc, &hel_desc, context);

If the D3D version is not 1, then enumerate IID_IDirect3DRGBDevice.

So I replaced IID_IDirect3DRGBDevice with IID_IDirect3DRefDevice, but oddly the
game still works. Really, I can't get this game to *not* work.

I haven't tested Aliens versus Predator; it may or may not break on
IID_IDirect3DRefDevice; but (at least until I test) I have no reason to suspect
it would break on IID_IDirect3DRGBDevice.

### Issue c

I don't have GTA 2 but it's possible that it uses Direct3D3, so that the first
device is the RGB device and the second device is the HAL device. In that case,
issue c is consistent with the Windows behavior.

### Issue d

I installed Rollcage (first unpatched from the CD and, later, the 1.0b patch).
This was the most interesting game to test.

The following comment is no longer accurate:

>     * Other games (Rollcage) tell emulation and hal device apart by certain
>     * flags. Rollcage expects D3DPTEXTURECAPS_POW2 to be set (yeah, it is a
>     * limitation flag), and it refuses all devices that have the perspective
>     * flag set. This way it refuses the emulation device, and HAL devices
>     * never have POW2 unset in d3d7 on windows. */

There is a mistake in the comment: it refuses all devices that have the
perspective flag unset* (not set). When I ORed the flag into hal_desc and
hel_desc:

> hal_desc.dpcLineCaps.dwTextureCaps |= D3DPTEXTURECAPS_PERSPECTIVE;
> hal_desc.dpcTriCaps.dwTextureCaps |= D3DPTEXTURECAPS_PERSPECTIVE;
> hel_desc.dpcLineCaps.dwTextureCaps |= D3DPTEXTURECAPS_PERSPECTIVE;
> hel_desc.dpcTriCaps.dwTextureCaps |= D3DPTEXTURECAPS_PERSPECTIVE;

the game still worked; when I masked it out instead:

> hal_desc.dpcLineCaps.dwTextureCaps &= ~D3DPTEXTURECAPS_PERSPECTIVE;
> hal_desc.dpcTriCaps.dwTextureCaps &= ~D3DPTEXTURECAPS_PERSPECTIVE;
> hel_desc.dpcLineCaps.dwTextureCaps &= ~D3DPTEXTURECAPS_PERSPECTIVE;
> hel_desc.dpcTriCaps.dwTextureCaps &= ~D3DPTEXTURECAPS_PERSPECTIVE;

the game stopped working (it immediately exits after the intro movie). In fact,
the original patch to fix EnumDevices mentions this:

http://marc.info/?l=wine-patches&m=117870468623214&w=2

> The  other flag is D3DPTEXTURECAPS_PERSPECTIVE which is not set on rgb
> emulation(!= refrast). Rollcage uses this flag to tell rgb emulation
> from hal.

Thus, it refuses all devices which have D3DPTEXTURECAPS_PERSPECTIVE unset.

Additionally, this comment is no longer accurate:
> HAL devices never have POW2 unset in d3d7 on windows.

On my Windows 7 install, the HAL device's hal_desc (D3D1-3) or desc (D3D7)
always has D3DPTEXTURECAPS_POW2 and D3DPTEXTURECAPS_NONPOW2CONDITIONAL both
unset (which means that "unconditional support is provided for 2D textures with
dimensions that are not powers of two" according to MSDN's D3DCAPS9 article).

But it looks like that doesn't matter; I masked out these flags in hal_desc and
hel_desc and the game still worked. (The game also works if you OR in one of
the flags and mask out the other, or OR in both flags.)

Using a debugger, I found that the game does the following in its callback
function (0041D280 in the unpatched version, 0041d250 in version 1.0b) for
IDirect3D3::EnumDevices:
> * Let ptr = hal_desc.
> * If ptr->dcmColorModel == 0, then change ptr to hel_desc.
> * If ptr->dwDeviceRenderBitDepth does not contain DDBD(selected_bit_depth), return DDENUMRET_OK (request the next device).
> * If ptr->dcmColorModel is odd (this corresponds to D3DCOLOR_MONO) and ptr->dpcTriCaps.dwShadeCaps does not contain D3DPSHADECAPS_COLORGOURAUDMONO, return DDENUMRET_OK.
> * If ptr->dcmColorModel is even (this corresponds to D3DCOLOR_RGB) and ptr->dpcTriCaps.dwShadeCaps does not contain D3DPSHADECAPS_COLORGOURAUDRGB, return DDENUMRET_OK.
> * If ptr->dpcTriCaps.dwTextureCaps does not contain D3DPTEXTURECAPS_PERSPECTIVE, return DDENUMRET_OK.
> * If we have made it to this point, this is a good device.

Upon this quick examination there is no reference to the POW2 flags that I can
see, and for me the game still works if the flags are masked out, so I believe
we can stop adding the POW2 flags in EnumDevices.

### Issue e

I was unable to get a device named "Direct3D HEL" in DirectX 6.1a, 7.0, 8.1, or
later versions, thus I believe we should change "Direct3D HEL" to "RGB
Emulation".

---

In short, we want:
* d3d1: ramp rgb (hal )? (ref )? (null )?
* d3d2: ramp rgb (hal )? mmx (ref )? (null )?
* d3d3: rgb (hal )? (ref )? (null )?
* d3d7: rgb (hal )? (ref )? (null )? (tnlhal )?

with the correct names ("Ramp Emulation", "RGB Emulation", and so on), and we
want the non-matching description of each device (hel_desc on the HAL device or
hal_desc on the other devices) to be empty (or almost empty for the HAL
device's hel_desc).

I have submitted a patchset so that Wine conforms to this behavior:
https://www.winehq.org/pipermail/wine-patches/2015-October/142721.html

The patchset fixes Resident Evil 1 and at least knocks off one of the bugs in
The Sims Online trial. Carmageddon 2 demo is actually affected by an issue in
FindDevice (FindDevice should accept dwSizes 0xac, 0xcc, and 0xfc in
D3DDEVICEDESC); this is also fixed in the patchset.

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list