It might be that the background are layered out using 3D calls. This is what is done in very many new 2D games at least. The problem with using 2D calls and then 3D calls is that it plays a little havoc on the system bus and so on. Direct3D might be emulating DirectDraw in 3D mode, this is really what I fear, however they might still have picked Direct3D for rendering the backgrounds because it gives automatic hardware scaling! Think bilinear filtering...
So, at least if I had written this, I'd do stuff like this (this is psuedo-code!):
SetRes(640, 480);
SetViewport(0, 0, 640, 480, D3D_ORTHOGONAL);
//Draw my 2D stuff using quads at a very far distance
//Things do not get smaller if they are far away in this mode
SetViewPort(-1, -1, 1, 1, D3D_FRUSTUM);
//Draw my 3D stuff, thinks will now become
//smaller the further away they are
This means that the only part that *might* need to be changed is the constants passed in to SetRes. The game will still set up a 640x480 viewport and work with that while drawing the background (not that it is guaranteed that the game uses that exact mode).
Still the problem is with hacking into Direct3D with it's hundreds of calls. I think the solution is to write low-level COM code, the kind of code we would have written from C or assembler to use Direct3D. What we do is:
Build our own low-level DllGetComObject or whatever those were called (the four global functions present in all COM dlls). Those low level functions...
- calls the original DirectX code to get a pointer
- copies the destination into it's own buffer using a simple memcpy
- changes the necessarry stuff, this will be done by casting the copied buffer into an array of functions and change the stuff at a fixed address
This way there's only work to be done per call being replaced, and the size of the lib doesn't really matter. The clue is that COM interfaces really are only a v-table (table of function pointers).
As always, I have not got the time for actually doing this. Sorry.