2014-07-19 02:19:43 +00:00
|
|
|
#include "d3d8Wrapper.h"
|
|
|
|
|
|
|
|
D3D8Base::LPDIRECT3D8 g_D3D=NULL;
|
|
|
|
|
|
|
|
HMODULE hD3D;
|
|
|
|
|
|
|
|
ThreadSafePointerSet D3D8Wrapper::IDirect3DDevice8::m_List;
|
|
|
|
ThreadSafePointerSet D3D8Wrapper::IDirect3DBaseTexture8::m_List;
|
|
|
|
ThreadSafePointerSet D3D8Wrapper::IDirect3DVolumeTexture8::m_List;
|
|
|
|
ThreadSafePointerSet D3D8Wrapper::IDirect3DCubeTexture8::m_List;
|
|
|
|
ThreadSafePointerSet D3D8Wrapper::IDirect3DVertexBuffer8::m_List;
|
|
|
|
ThreadSafePointerSet D3D8Wrapper::IDirect3DIndexBuffer8::m_List;
|
|
|
|
ThreadSafePointerSet D3D8Wrapper::IDirect3DSurface8::m_List;
|
|
|
|
ThreadSafePointerSet D3D8Wrapper::IDirect3DVolume8::m_List;
|
|
|
|
ThreadSafePointerSet D3D8Wrapper::IDirect3DSwapChain8::m_List;
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
namespace D3D8Wrapper
|
2014-07-19 18:35:47 +00:00
|
|
|
{
|
|
|
|
IDirect3DDevice8 *last_device = NULL;
|
2014-07-23 02:44:33 +00:00
|
|
|
IDirect3DSurface8 *render_surface = NULL;
|
2014-07-19 18:35:47 +00:00
|
|
|
void (*rendering_callback)( int );
|
2014-07-19 02:19:43 +00:00
|
|
|
|
|
|
|
D3D8Wrapper::IDirect3D8* WINAPI Direct3DCreate8(UINT Version)
|
|
|
|
{
|
2014-07-20 02:38:57 +00:00
|
|
|
// Get the real DLL path
|
|
|
|
// Might be unsafe
|
|
|
|
CHAR dll_path[1024];
|
|
|
|
GetSystemDirectory(dll_path,1024);
|
|
|
|
strcat(dll_path,"\\d3d8.dll");
|
2014-07-19 02:19:43 +00:00
|
|
|
|
2014-07-20 02:38:57 +00:00
|
|
|
hD3D = LoadLibrary(dll_path);
|
2014-07-19 02:19:43 +00:00
|
|
|
|
|
|
|
D3D8Wrapper::D3DCREATE pCreate = (D3D8Wrapper::D3DCREATE)GetProcAddress(hD3D, "Direct3DCreate8");
|
|
|
|
|
2014-07-20 02:38:57 +00:00
|
|
|
// Use the real Direct3DCreate8 to make the base object
|
2014-07-19 02:19:43 +00:00
|
|
|
D3D8Base::IDirect3D8* pD3D = pCreate(D3D_SDK_VERSION);
|
|
|
|
|
2014-07-20 02:38:57 +00:00
|
|
|
// Wrap the object
|
2014-07-19 02:19:43 +00:00
|
|
|
D3D8Wrapper::IDirect3D8* fD3D = D3D8Wrapper::IDirect3D8::GetDirect3D(pD3D);
|
|
|
|
|
2014-07-20 02:38:57 +00:00
|
|
|
return fD3D;
|
2014-07-19 02:19:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-20 02:38:57 +00:00
|
|
|
__declspec(dllexport) void __cdecl CloseDLL()
|
|
|
|
{
|
|
|
|
FreeLibrary(hD3D);
|
|
|
|
}
|
2014-07-19 02:19:43 +00:00
|
|
|
|
|
|
|
__declspec(dllexport) void __cdecl SetRenderingCallback(void (*callback)(int))
|
|
|
|
{
|
2014-07-19 18:35:47 +00:00
|
|
|
D3D8Wrapper::rendering_callback = callback;
|
2014-07-19 02:19:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
__declspec(dllexport) void __cdecl ReadScreen(void *dest, int *width, int *height)
|
|
|
|
{
|
2014-07-19 18:35:47 +00:00
|
|
|
if (D3D8Wrapper::last_device == NULL)
|
2014-07-19 02:19:43 +00:00
|
|
|
{
|
|
|
|
*width = 0;
|
|
|
|
*height = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get back buffer (surface)
|
2014-07-23 02:44:33 +00:00
|
|
|
//D3D8Base::IDirect3DSurface8 *backbuffer;
|
|
|
|
//D3D8Wrapper::last_device->GetD3D8Device()->GetBackBuffer(0,D3D8Base::D3DBACKBUFFER_TYPE_MONO,&backbuffer);
|
2014-07-19 02:19:43 +00:00
|
|
|
|
|
|
|
// surface...
|
|
|
|
// make a D3DSURFACE_DESC, pass to GetDesc
|
|
|
|
D3D8Base::D3DSURFACE_DESC desc;
|
2014-07-23 02:44:33 +00:00
|
|
|
D3D8Wrapper::render_surface->GetDesc(&desc);
|
2014-07-19 02:19:43 +00:00
|
|
|
|
|
|
|
// get out height/width
|
|
|
|
*width = desc.Width;
|
|
|
|
*height = desc.Height;
|
|
|
|
|
|
|
|
// if dest isn't null
|
|
|
|
if (dest != NULL)
|
|
|
|
{
|
|
|
|
// make a RECT with size of buffer
|
|
|
|
RECT entire_buffer;
|
|
|
|
entire_buffer.left = 0;
|
|
|
|
entire_buffer.top = 0;
|
|
|
|
entire_buffer.right = desc.Width;
|
|
|
|
entire_buffer.bottom = desc.Height;
|
2014-07-27 01:51:11 +00:00
|
|
|
|
|
|
|
//X8R8G8B8 or fail -- A8R8G8B8 will malfunction (is it because the source surface format isnt matching?)
|
|
|
|
static D3D8Wrapper::IDirect3DTexture8* tex = NULL;
|
|
|
|
if(!tex)
|
|
|
|
D3D8Wrapper::last_device->CreateTexture(desc.Width, desc.Height, 1, 0, D3D8Base::D3DFMT_X8R8G8B8, D3D8Base::D3DPOOL_SYSTEMMEM, &tex);
|
|
|
|
|
|
|
|
D3D8Wrapper::IDirect3DSurface8* surf;
|
|
|
|
tex->GetSurfaceLevel(0,&surf);
|
|
|
|
HRESULT hr = D3D8Wrapper::last_device->CopyRects(D3D8Wrapper::render_surface,NULL,0,surf,NULL);
|
|
|
|
|
2014-07-19 02:19:43 +00:00
|
|
|
// make a D3DLOCKED_RECT, pass to LockRect
|
|
|
|
D3D8Base::D3DLOCKED_RECT locked;
|
2014-07-27 01:51:11 +00:00
|
|
|
hr = surf->LockRect(&locked,&entire_buffer,D3DLOCK_READONLY);
|
2014-07-26 22:50:50 +00:00
|
|
|
|
|
|
|
//this loop was reversed from the original.
|
|
|
|
//it should be faster anyway if anything since the reading can be prefetched forwardly.
|
|
|
|
int dest_row = desc.Height - 1;
|
|
|
|
for (int from_row = 0; from_row < desc.Height; from_row++)
|
2014-07-19 02:19:43 +00:00
|
|
|
{
|
2014-07-27 01:51:11 +00:00
|
|
|
memcpy((char*)dest + (dest_row * desc.Width*4),(char*)locked.pBits + from_row * locked.Pitch, desc.Width*4);
|
2014-07-26 22:50:50 +00:00
|
|
|
dest_row--;
|
2014-07-19 02:19:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// unlock rect
|
2014-07-27 01:51:11 +00:00
|
|
|
surf->UnlockRect();
|
|
|
|
surf->Release();
|
2014-07-19 02:19:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// release the surface
|
2014-07-23 02:44:33 +00:00
|
|
|
//backbuffer->Release();
|
2014-07-19 02:19:43 +00:00
|
|
|
|
|
|
|
// we're done, maybe?
|
|
|
|
}
|
|
|
|
}
|