how-to/tut (if any1 is interested)
Grab the the
ddhack logger fix a minor issue with in the Blt logging code ( make sure LPDDBLTFX isn't NULL )
add return address logging to all relevant functions
compile ddraw.dll and drop it into your game folder
start the game, let the movies run, then immediately end the game
take a look in the log file
you'll see startup followed by the movie code then a little bit of the menu then cleanup
the movie code should be easy to spot as it will be done every frame so it will repeat like 1,000 times in a row
DDraw allows us to stretch images using the Blt call
---
I took a look at Throne of Bhaal unfortunately they are doing things the way you would expect them to
(3d acceleration off which might matter)Lock the back buffer
--draw the movie frame by hand onto the back buffer--
Unlock the back buffer
then Flip the back buffer to the front
this time there is no convenient Blt call that is only used for the movies
the flip call is used for in-game as well
( Windowed mode uses Blt but it is just replacing the Flip )For some reason trying to Blt the back buffer to itself doesn't turn out well.
so currently [using ddhack logger as a platform]
I just hook the movie's Lock call and pass in a (new) offscreen surface to be Locked instead of the back buffer
the movie's Unlock call is hooked so as to unlock that offscreen surface instead of the back buffer then
we (stretch) Blt that offscreen surface to fill the back buffer
I'm thinking this will be a pain to turn into a polished mod though
extern "C" void * _ReturnAddress(void);
#pragma intrinsic(_ReturnAddress)
LPDIRECTDRAWSURFACE dds_movie = NULL;
LPDIRECTDRAW2 dd; //grabbed from the myIDDraw2 constructor
HRESULT __stdcall myIDDrawSurface1::Unlock(LPVOID a)
{
if( (_ReturnAddress() == (VOID*)0x004610FB) )
{
HRESULT hr = dds_movie->Unlock(NULL);
RECT rc = { 400,210,1040,660 }; // I'm running at 1440x900 and the movie is centered
m_pIDDrawSurface->Blt(NULL,dds_movie,&rc,DDBLT_WAIT, NULL);
return hr;
}
return m_pIDDrawSurface->Unlock(a);
}
HRESULT __stdcall myIDDrawSurface1::Lock(LPRECT a,LPDDSURFACEDESC b,DWORD c,HANDLE d)
{
if( _ReturnAddress() == (VOID*)0x00461004 )
{
if(dds_movie == NULL){
DDSURFACEDESC ddsd;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = 1440; // <----- blah
ddsd.dwHeight = 900; // <----- blah
dd->CreateSurface(&ddsd, &dds_movie, NULL);
}
return dds_movie->Lock(a,b,c,d);
}
return m_pIDDrawSurface->Lock(a,b,c,d);
}