Path: blob/master/libmupen64plus/D3D8Interceptor/d3d8Wrapper.cpp
2 views
#include "d3d8Wrapper.h"12D3D8Base::LPDIRECT3D8 g_D3D=NULL;34HMODULE realDLL;56extern "C"7{8namespace D3D8Wrapper9{10IDirect3DDevice8 *last_device = NULL;11IDirect3DSurface8 *render_surface = NULL;12void (*rendering_callback)( int );1314D3D8Wrapper::IDirect3D8* WINAPI Direct3DCreate8(UINT Version)15{16//sometimes, Intel drivers will clear the dll path. So let's save and restore it (do their job for them)17char oldDllDirectory[MAX_PATH];18GetDllDirectory(MAX_PATH, oldDllDirectory);1920// Get the real DLL path from the system directory, needs to be specific to avoid binding to the d3d8.dll we're in now!21// Might be unsafe22CHAR dll_path[1024];23GetSystemDirectory(dll_path,1024);24strcat(dll_path,"\\d3d8.dll");2526realDLL = LoadLibrary(dll_path);2728D3D8Wrapper::D3DCREATE realDirect3DCreate8 = (D3D8Wrapper::D3DCREATE)GetProcAddress(realDLL, "Direct3DCreate8");2930// Use the real Direct3DCreate8 to make the base object31D3D8Base::IDirect3D8* realD3D = realDirect3DCreate8(D3D_SDK_VERSION);3233// Wrap the object34D3D8Wrapper::IDirect3D8* wrappedD3D = D3D8Wrapper::IDirect3D8::GetDirect3D(realD3D);3536//restore old DLL directory37SetDllDirectory(oldDllDirectory);3839return wrappedD3D;40}41}424344__declspec(dllexport) void __cdecl CloseDLL()45{46FreeLibrary(realDLL);47}4849__declspec(dllexport) void __cdecl SetRenderingCallback(void (*callback)(int))50{51D3D8Wrapper::rendering_callback = callback;52}5354__declspec(dllexport) void __cdecl ReadScreen(void *dest, int *width, int *height)55{56if (D3D8Wrapper::last_device == NULL)57{58*width = 0;59*height = 0;60return;61}6263// surface...64// make a D3DSURFACE_DESC, pass to GetDesc65D3D8Base::D3DSURFACE_DESC desc;66D3D8Wrapper::render_surface->GetDesc(&desc);6768// get out height/width69*width = desc.Width;70*height = desc.Height;7172// if dest isn't null73if (dest != NULL)74{75// make a RECT with size of buffer76RECT entire_buffer;77entire_buffer.left = 0;78entire_buffer.top = 0;79entire_buffer.right = desc.Width;80entire_buffer.bottom = desc.Height;8182//resolve rendertarget to a system memory texture, for locking83//TODO! UNACCEPTABLE CODE! THIS IS HORRIBLE!84//X8R8G8B8 or fail -- A8R8G8B8 will malfunction (is it because the source surface format isnt matching? I think so)85static D3D8Wrapper::IDirect3DTexture8* tex = NULL;86static RECT texRect;87if(!tex || (texRect.right != entire_buffer.right) || (texRect.bottom != entire_buffer.bottom))88{89if(tex)90tex->Release();91texRect = entire_buffer;92D3D8Wrapper::last_device->CreateTexture(desc.Width, desc.Height, 1, 0, D3D8Base::D3DFMT_X8R8G8B8, D3D8Base::D3DPOOL_SYSTEMMEM, &tex);93}9495D3D8Wrapper::IDirect3DSurface8* surf;96tex->GetSurfaceLevel(0,&surf);97HRESULT hr = D3D8Wrapper::last_device->CopyRects(D3D8Wrapper::render_surface,NULL,0,surf,NULL);9899// make a D3DLOCKED_RECT, pass to LockRect100D3D8Base::D3DLOCKED_RECT locked;101hr = surf->LockRect(&locked,&entire_buffer,D3DLOCK_READONLY);102103//this loop was reversed from the original.104//it should be faster anyway if anything since the reading can be prefetched forwardly.105//TODO - allow bizhawk to handle flipped images.... nonetheless, it might not handle images with unusual pitches, although maybe we should consider that.106//so this code will probably remain for quite some time107int dest_row = desc.Height - 1;108for (UINT from_row = 0; from_row < desc.Height; from_row++)109{110memcpy((char*)dest + (dest_row * desc.Width*4),(char*)locked.pBits + from_row * locked.Pitch, desc.Width*4);111dest_row--;112}113114// unlock rect115surf->UnlockRect();116surf->Release();117}118119// release the surface120//backbuffer->Release();121122// we're done, maybe?123}124}125126