2014-07-19 02:19:43 +00:00
# include "d3d8Wrapper.h"
D3D8Base : : LPDIRECT3D8 g_D3D = NULL ;
2014-08-10 21:14:29 +00:00
HMODULE realDLL ;
2014-07-19 02:19:43 +00:00
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-08-10 21:14:29 +00:00
// Get the real DLL path from the system directory
2014-07-20 02:38:57 +00:00
// 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-08-10 21:14:29 +00:00
realDLL = LoadLibrary ( dll_path ) ;
2014-07-19 02:19:43 +00:00
2014-08-10 21:14:29 +00:00
D3D8Wrapper : : D3DCREATE realDirect3DCreate8 = ( D3D8Wrapper : : D3DCREATE ) GetProcAddress ( realDLL , " Direct3DCreate8 " ) ;
2014-07-19 02:19:43 +00:00
2014-07-20 02:38:57 +00:00
// Use the real Direct3DCreate8 to make the base object
2014-08-10 21:14:29 +00:00
D3D8Base : : IDirect3D8 * realD3D = realDirect3DCreate8 ( D3D_SDK_VERSION ) ;
2014-07-19 02:19:43 +00:00
2014-07-20 02:38:57 +00:00
// Wrap the object
2014-08-10 21:14:29 +00:00
D3D8Wrapper : : IDirect3D8 * wrappedD3D = D3D8Wrapper : : IDirect3D8 : : GetDirect3D ( realD3D ) ;
2014-07-19 02:19:43 +00:00
2014-08-10 21:14:29 +00:00
return wrappedD3D ;
2014-07-19 02:19:43 +00:00
}
}
2014-07-20 02:38:57 +00:00
__declspec ( dllexport ) void __cdecl CloseDLL ( )
{
2014-08-10 21:14:29 +00:00
FreeLibrary ( realDLL ) ;
2014-07-20 02:38:57 +00:00
}
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 ;
}
// 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
2014-07-27 06:25:59 +00:00
//resolve rendertarget to a system memory texture, for locking
//TODO! UNACCEPTABLE CODE! THIS IS HORRIBLE!
//X8R8G8B8 or fail -- A8R8G8B8 will malfunction (is it because the source surface format isnt matching? I think so)
2014-07-27 01:51:11 +00:00
static D3D8Wrapper : : IDirect3DTexture8 * tex = NULL ;
2014-07-27 06:25:59 +00:00
static RECT texRect ;
if ( ! tex | | ( texRect . right ! = entire_buffer . right ) | | ( texRect . bottom ! = entire_buffer . bottom ) )
{
if ( tex )
tex - > Release ( ) ;
texRect = entire_buffer ;
2014-07-27 01:51:11 +00:00
D3D8Wrapper : : last_device - > CreateTexture ( desc . Width , desc . Height , 1 , 0 , D3D8Base : : D3DFMT_X8R8G8B8 , D3D8Base : : D3DPOOL_SYSTEMMEM , & tex ) ;
2014-07-27 06:25:59 +00:00
}
2014-07-27 01:51:11 +00:00
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.
2014-07-27 06:25:59 +00:00
//TODO - allow bizhawk to handle flipped images.... nonetheless, it might not handle images with unusual pitches, although maybe we should consider that.
//so this code will probably remain for quite some time
2014-07-26 22:50:50 +00:00
int dest_row = desc . Height - 1 ;
2014-08-17 18:53:49 +00:00
for ( UINT 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?
}
}