Xbox LIVE Indie Games
Sort Discussions: Previous Discussion Next Discussion
Page 1 of 1 (6 posts)

DirectX 7

Last post 3/24/2017 12:35 PM by gho. 5 replies.
  • 9/28/2007 9:48 AM

    DirectX 7

    Ok, this might seem like a strange question, but I can't find any info about it through google or others. So I thought I'll post it here, doesn't hurt to try now does it :-).

    I'll start with a bit of background so you guys know what I'm doing:

    About 1,5 year ago I bought Doom 3 for PC (I know D3 engine is OpenGL), really loved the game, got to know about modding and started to look into that. Now basically I made some changes to Doom 3 just to have me some fun, nothing I really wanted to release or something, just added some extra weapons, powerups, modified some skins and the likes. Nothing to fancy, but I enjoyed it a lot.

    Since then I try and find out what the modding capabilities are for games I buy and start experimenting with those as well.

    But I'm going a bit further now. I've looked for some modding tools for older games that I own, but halas some don't really support modding. And well, I searched on until I found a possible solution. I came across a wallhack for Doom 3 and although I'm not interested in cheating (I might not be the best player, far from it, but hey I enjoy myself so why cheat), I still was interested in how they did it (add blending to the walls). So here I found a possible solution to do some graphics modifications (although quite limited).

    I made a wrapper for d3d9.dll, which is quite stable now and allows me to search through all different textures currently used in the scene and make some adjustments (blending, replacing by other texture and stuff).

    But going through my older games it ofcourse didn't take long to encounter a game that uses DirectX 7.

    Now here's the catch. I know quite a bit about Direct3D 9 by reading books about it and such, but DirectX 7 was totally new to me, but I thought, hey what the hell, lets just try it out. You guys probably know all of this, but I'm just explaining what I discovered:

    With Direct3D9 the application communicates directly with d3d9.dll, while with DirectX 7 the communication happens with ddraw.dll first and you acquire a IDirect3D7 interface calling QueryInterface on a DirectDraw interface. (I had to look this up, since I didn't know).

    Ok, so I started out by making my own d3dim700.dll. Dumpbin allows me to see the exported functions, so that's one step in the right direction. However, nowhere on the web are any prototypes to be found for all these functions, so that led me to examining some of the assembly code.

    Now I think I got most of it: number of arguments, size of the arguments and return values. It's still a pain to get it right. Basically I can wrap those exported functions without any problem (although a lot of the parameters are LPVOID, since I don't know what type they're really refering to).

    Then comes the call to Direct3DCreate. I assumed it was similar to Direct3DCreate9 at first, but that soon seemed to be wrong. What I have right now is this:

    HRESULT WINAPI Direct3DCreate(UINT SDKVersion, IUnknown **d3dApi, IUnknown *parent);

    As you can see I threat the second parameter as if we request a IUknown pointer. Since I know it's a COM-interface that's being returned, I just don't know what type.

    And I continued on wrapping a basic IUknown interface which can then be queried for a wrapped IDirect3D7 interface.

    All goes well until a call to CreateDevice (from the IDirect3D7 interface), which ends up calling FlushD3DDevices (one of the exported functions I don't know the parameter's type of) where it crashes.

    Canceling some of my wrappers out and examining the assembly code while tracing, I figured out that the FlushD3DDevices function derives the obtained IDirect3D7 interface pointer from the parameter (becomes the value of EAX). While wrapped it seems to do exactly the same, except that on the assembly line where EAX gets the value of the IDirect3D7 interface pointer it gets the value 0xFDFDFDFD. Also each time this function is called it has another value for it's parameter, but it always ends out in EAX getting the value of the IDirect3D7 interface pointer.

    I did some further experimenting and the same stuff applies to CreateTexture and other exported functions.

    So now to the question:

    It might be classified, if it is I'm in bad luck.
    - What are the prototypes of these exported functions, since that might clarify a lot for me. I'm suspecting the parameters are DirectDraw objects of some sort, but I can't be sure.
    - More importantly what is the type of the second parameter in Direct3DCreate. Since I suspect this is the cause of it. I just created a wrapper for the IUnknown interface, but nothing else.
    - Third, but not least. I doubt this is the case but, I have the feeling that ddraw.dll accesses public members of some objects in d3dim700.dll directly. I say "I doubt this is the case", since all ddraw.dll receives are pointers to the interfaces, but still I want to be sure, since if it does access public members directly, then well it's seems all the more difficult to create a stable proxy-dll.

    As explained above, all of this is just for personal use, as a hobby of mine, looking at games from another perspective and gaining some knowledge on how they work in the black box.

    Ah yes, before I forget. I ain't planning on writing a wrapper for ddraw (yet) and most likely I never will, since well my interest is in the 3D graphics. Also I don't think it will provide me with a solution to my problem, since well that's related to how ddraw works, not how its API looks.

  • 9/28/2007 12:35 PM In reply to

    Re: DirectX 7

    Answer
    Reply Quote

    To make a long story short. Direct3D 7 works very different from Direct3D 8 and 9.

    Most of the functions that are exported from the different dlls were never called directly from the application. Therefore they were never documented at all. The public interface for Direct3D7 (which was still coupled with DirectDraw) can still be found in the headers that are part of the SDK.

  • 9/29/2007 8:10 AM In reply to

    Re: DirectX 7

    I was making a bigger problem than there really was. The answer is really in my own question already, more specifically the last sentence.

    The problem occurs because I'm making a proxy for d3dim700.dll, but the application only imports ddraw.dll, which then imports d3dim700.dll in turn.

    Now for the creation process it goes like this:

    App -> ddraw.dll -> d3dim700.dll : App call queryinterface on IDirectDraw7 interface to get a IDirect3D7 interface.

    With proxy:

    App -> ddraw.dll -> d3dim700.dll <proxy> -> d3dim700.dll

    This I got working by proxying d3dim700.dll.

    But afterwards when the App wants to create a direct3d device it goes like this:

    App -> d3dim700.dll (through the IDirect3D7 interface) -> ddraw.dll -> d3dim700.dll (FlushD3DDevices)

    With proxy:

    App -> d3dim700.dll <proxy wrapped IDirect3D7 interface> -> d3dim700.dll -> ddraw.dll -> d3dim700.dll <proxy with wrapped FlushD3DDevices, but no knowledge of the parameter> -> d3dim700.dll <crashes because of incorrect parameter>

    So I was actually wrapping a dll that ddraw.dll communicates with, but the dll itself requires ddraw.dll itself. So the parameters can be anything, since it's not important for the App, but only the internal workings of directdraw and direct3d.

    Wrapping ddraw.dll and adding wrappers for the interfaces of direct3d 7 within the same proxy would always have the same callstack (or dll-stack):

    App -> ddraw.dll <proxy> -> ddraw.dll

    App -> ddraw.dll <proxy with wrapped Direct3D interface> -> d3dim700.dll

    So that within the real ddraw.dll & d3dim700.dll the functionality stays exactly the same as with no wrapper...

    The solution was there all along, I just kept looking over it cause I was too focused on d3dim700.dll...

  • 5/13/2008 12:09 PM In reply to

    Re: DirectX 7

    Do you have these proxy dll's and source code posted anywhere?  I've been looking for this to enable some older games to work correctly.
  • 2/10/2011 10:03 PM In reply to

    Re: DirectX 7

    If anyone's still interested, I've uploaded a basic wrapper here: https://github.com/Hereifixedit/Direct3D7Wrapper
  • 3/24/2017 12:35 PM In reply to

    Re: DirectX 7

    Hi.
    I'm GHO, currently author of the sourceforge open-source release of DxWnd.
    I'm very interested in your work about dx7, I may have some information and I seek collaboration for integration of more and more hacks within DxWnd in order to make it a powerful tool for oldies compatibility.
    In particular, DxWnd has a skeleton for ddraw / d3dim / d3dim700 wrapping and hacking: a good starting point to inject any sort of compatibility or enhancement shims.
    Also, DxWnd has a useful operation logging and some basic functionalities for texture dumping & hacking.
    Please, pay us a visit to https://sourceforge.net/p/dxwnd/discussion/general
    p.s. the second argument of Direct3DCreateDevice is the pointer to the renderer GUID.
Page 1 of 1 (6 posts) Previous Discussion Next Discussion