├── .gitignore ├── D2GI ├── src │ ├── d2gi │ │ ├── d2gi_blitter_ps.hlsl │ │ ├── d2gi_common.cpp │ │ ├── d2gi_common.h │ │ ├── d2gi_ib_container.h │ │ ├── d2gi_vb_container.h │ │ ├── d2gi_zbuf_surf.h │ │ ├── d2gi_zbuf_surf.cpp │ │ ├── d2gi_blitter_vs.hlsl │ │ ├── d2gi_resource.h │ │ ├── d2gi_sysmem_surf.h │ │ ├── d2gi_container.h │ │ ├── d2gi_direct3d.h │ │ ├── d2gi_surface.cpp │ │ ├── d2gi_resource.cpp │ │ ├── d2gi_blitter.h │ │ ├── d2gi_palette.h │ │ ├── d2gi_config.h │ │ ├── d2gi_hooks.h │ │ ├── d2gi_prim_single_surf.h │ │ ├── d2gi_prim_flip_surf.h │ │ ├── d2gi_strided_renderer.h │ │ ├── d2gi_surface.h │ │ ├── d2gi_palette.cpp │ │ ├── d2gi_sysmem_surf.cpp │ │ ├── d2gi_backbuf_surf.h │ │ ├── d2gi_mipmap_surf.h │ │ ├── d2gi_vb_container.cpp │ │ ├── d2gi_ib_container.cpp │ │ ├── d2gi_direct3d.cpp │ │ ├── d2gi_enums.h │ │ ├── d2gi_texture.h │ │ ├── d2gi_ddraw.h │ │ ├── d2gi_device.h │ │ ├── d2gi_container.cpp │ │ ├── d2gi_buffer_container.cpp │ │ ├── d2gi_config.cpp │ │ ├── d2gi_prim_single_surf.cpp │ │ ├── d2gi_buffer_container.h │ │ ├── d2gi_prim_flip_surf.cpp │ │ ├── d2gi_blitter_ps.h │ │ ├── d2gi_blitter_vs.h │ │ ├── d2gi_hooks.cpp │ │ ├── d2gi_mipmap_surf.cpp │ │ ├── d2gi_device.cpp │ │ ├── d2gi_backbuf_surf.cpp │ │ ├── d2gi.h │ │ ├── d2gi_strided_renderer.cpp │ │ ├── d2gi_texture.cpp │ │ ├── d2gi_ddraw.cpp │ │ ├── d2gi_blitter.cpp │ │ ├── d2gi_enums.cpp │ │ └── d2gi.cpp │ ├── common │ │ ├── m3x4.h │ │ ├── utils.h │ │ ├── dir.h │ │ ├── logger.h │ │ ├── frect.h │ │ ├── common.h │ │ ├── dir.cpp │ │ ├── utils.cpp │ │ ├── logger.cpp │ │ ├── d3d9.h │ │ └── d3d7.h │ ├── ddraw │ │ ├── dd_palette.cpp │ │ ├── dd_palette.h │ │ ├── dd_ddraw.h │ │ ├── dd_surface.h │ │ ├── dd_ddraw.cpp │ │ └── dd_surface.cpp │ ├── d3d │ │ ├── d3d_direct3d.h │ │ ├── d3d_direct3d.cpp │ │ ├── d3d_device.h │ │ └── d3d_device.cpp │ └── main.cpp ├── d2gi.def ├── defs.props ├── D2GI.vcxproj.user ├── D2GI.vcxproj.filters └── D2GI.vcxproj ├── D2GI.sln ├── README-EN.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | Debug/ 3 | Release/ 4 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_blitter_ps.hlsl: -------------------------------------------------------------------------------- 1 | 2 | sampler g_txSourceTexture : register(s0); 3 | 4 | 5 | float4 g_vBorder:register(c0); 6 | 7 | 8 | float4 main(float2 vTC : TEXCOORD0) : COLOR0 9 | { 10 | vTC = clamp(vTC, g_vBorder.xy, g_vBorder.zw); 11 | return tex2D(g_txSourceTexture, vTC); 12 | } 13 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_common.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "d2gi_common.h" 3 | #include "d2gi.h" 4 | 5 | 6 | D3D9::IDirect3D9* D2GIBase::GetD3D9() 7 | { 8 | return m_pD2GI->GetD3D9(); 9 | } 10 | 11 | 12 | D3D9::IDirect3DDevice9* D2GIBase::GetD3D9Device() 13 | { 14 | return m_pD2GI->GetD3D9Device(); 15 | } 16 | -------------------------------------------------------------------------------- /D2GI/src/common/m3x4.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | 6 | struct MAT3X4 7 | { 8 | union 9 | { 10 | struct 11 | { 12 | FLOAT _11, _12, _13; 13 | FLOAT _21, _22, _23; 14 | FLOAT _31, _32, _33; 15 | FLOAT _41, _42, _43; 16 | }; 17 | FLOAT m[4][3]; 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /D2GI/src/common/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d7.h" 4 | #include "d3d9.h" 5 | 6 | 7 | UINT CalcFVFStride(DWORD); 8 | UINT CalcPrimitiveCount(D3D7::D3DPRIMITIVETYPE, DWORD dwVertexOrIndexCount); 9 | UINT CalcFVFTextureCount(DWORD); 10 | VOID CalcMipMapLevelSize(DWORD, DWORD, UINT, DWORD*, DWORD*); 11 | -------------------------------------------------------------------------------- /D2GI/src/common/dir.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include "common.h" 5 | 6 | 7 | class Directory 8 | { 9 | static TCHAR s_szSysDir[MAX_PATH]; 10 | static TCHAR s_szEXEPath[MAX_PATH], s_szEXEDir[MAX_PATH]; 11 | public: 12 | static TCHAR* GetEXEPath(); 13 | static TCHAR* GetEXEDirectory(); 14 | static TCHAR* GetSysDirectory(); 15 | }; 16 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/d3d9.h" 4 | 5 | class D2GI; 6 | 7 | class D2GIBase 8 | { 9 | protected: 10 | D2GI* m_pD2GI; 11 | public: 12 | D2GIBase(D2GI* pD2GI) : m_pD2GI(pD2GI) {} 13 | 14 | D2GI* GetD2GI() { return m_pD2GI; } 15 | D3D9::IDirect3D9* GetD3D9(); 16 | D3D9::IDirect3DDevice9* GetD3D9Device(); 17 | }; 18 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_ib_container.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d2gi_buffer_container.h" 4 | 5 | 6 | class D2GIIndexBufferContainer : public D2GIBufferContainer 7 | { 8 | protected: 9 | virtual INDEX_STREAMING_BUFFER* AllocNewBuffer(UINT); 10 | public: 11 | D2GIIndexBufferContainer(D2GI*); 12 | ~D2GIIndexBufferContainer(); 13 | 14 | UINT SetAsSource(); 15 | }; 16 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_vb_container.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d2gi_buffer_container.h" 4 | 5 | 6 | class D2GIVertexBufferContainer : public D2GIBufferContainer 7 | { 8 | protected: 9 | virtual VERTEX_STREAMING_BUFFER* AllocNewBuffer(UINT); 10 | public: 11 | D2GIVertexBufferContainer(D2GI*); 12 | ~D2GIVertexBufferContainer(); 13 | 14 | VOID SetAsSource(UINT); 15 | }; 16 | -------------------------------------------------------------------------------- /D2GI/src/common/logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include "common.h" 5 | 6 | 7 | class Logger 8 | { 9 | static TCHAR s_szLogPath[MAX_PATH]; 10 | static HWND s_hWnd; 11 | 12 | static VOID WriteLog(TCHAR*); 13 | public: 14 | static VOID SetHWND(HWND hWnd) { s_hWnd = hWnd; }; 15 | static VOID Error(TCHAR*, ...); 16 | static VOID Warning(TCHAR*, ...); 17 | static VOID Log(TCHAR*, ...); 18 | }; 19 | -------------------------------------------------------------------------------- /D2GI/d2gi.def: -------------------------------------------------------------------------------- 1 | LIBRARY "ddraw" 2 | EXPORTS DirectDrawCreate = DirectDrawCreate @8 3 | EXPORTS DirectDrawCreateClipper = DirectDrawCreateClipper @9 4 | EXPORTS DirectDrawCreateEx = DirectDrawCreateEx @10 5 | EXPORTS DirectDrawEnumerateA = DirectDrawEnumerateA @11 6 | EXPORTS DirectDrawEnumerateExA = DirectDrawEnumerateExA @12 7 | EXPORTS DirectDrawEnumerateExW = DirectDrawEnumerateExW @13 8 | EXPORTS DirectDrawEnumerateW = DirectDrawEnumerateW @14 9 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_zbuf_surf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d2gi_surface.h" 4 | 5 | 6 | class D2GIZBufferSurface : public D2GISurface 7 | { 8 | public: 9 | D2GIZBufferSurface(D2GI*, DWORD dwW, DWORD dwH, D2GIPIXELFORMAT); 10 | virtual ~D2GIZBufferSurface(); 11 | 12 | virtual SURFACETYPE GetType() { return ST_ZBUFFER; } 13 | virtual VOID ReleaseResource() {}; 14 | virtual VOID LoadResource() {} 15 | 16 | STDMETHOD(IsLost)(); 17 | }; 18 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_zbuf_surf.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "d2gi_zbuf_surf.h" 3 | #include "d2gi.h" 4 | 5 | 6 | D2GIZBufferSurface::D2GIZBufferSurface(D2GI* pD2GI, 7 | DWORD dwWidth, DWORD dwHeight, D2GIPIXELFORMAT eFormat) 8 | : D2GISurface(pD2GI, dwWidth, dwHeight, eFormat) 9 | { 10 | 11 | } 12 | 13 | 14 | D2GIZBufferSurface::~D2GIZBufferSurface() 15 | { 16 | 17 | } 18 | 19 | 20 | HRESULT D2GIZBufferSurface::IsLost() 21 | { 22 | return DD_OK; 23 | } 24 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_blitter_vs.hlsl: -------------------------------------------------------------------------------- 1 | 2 | float4 g_vRect: register(c0); 3 | float4 g_vTexRect: register(c1); 4 | 5 | 6 | struct VS_OUT 7 | { 8 | float4 vPos: POSITION; 9 | float2 vTexCoord: TEXCOORD0; 10 | }; 11 | 12 | 13 | VS_OUT main(float4 vPos: POSITION, float2 vTC: TEXCOORD0) 14 | { 15 | VS_OUT sOut; 16 | 17 | sOut.vPos = float4(vPos.xy * g_vRect.xy + g_vRect.zw, 0.0, 1.0f); 18 | sOut.vTexCoord = (vTC * g_vTexRect.xy) + g_vTexRect.zw; 19 | 20 | return sOut; 21 | } 22 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_resource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d2gi_common.h" 4 | 5 | 6 | class D2GIResourceContainer; 7 | 8 | 9 | class D2GIResource : public D2GIBase 10 | { 11 | protected: 12 | D2GIResourceContainer* m_pContainer; 13 | public: 14 | D2GIResource(D2GI*); 15 | ~D2GIResource(); 16 | 17 | VOID AttachToContainer(D2GIResourceContainer*); 18 | VOID DetachFromContainer(); 19 | virtual VOID ReleaseResource() = 0; 20 | virtual VOID LoadResource() = 0; 21 | }; 22 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_sysmem_surf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d2gi_texture.h" 4 | 5 | 6 | class D2GISystemMemorySurface : public D2GITexture 7 | { 8 | public: 9 | D2GISystemMemorySurface(D2GI*, DWORD dwW, DWORD dwH, D2GIPIXELFORMAT eFormat); 10 | virtual ~D2GISystemMemorySurface(); 11 | 12 | virtual SURFACETYPE GetType() { return ST_SYSMEM; } 13 | 14 | STDMETHOD(Lock)(LPRECT, D3D7::LPDDSURFACEDESC2, DWORD, HANDLE); 15 | STDMETHOD(GetCaps)(D3D7::LPDDSCAPS2); 16 | }; 17 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_container.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "d2gi_common.h" 6 | 7 | 8 | class D2GIResource; 9 | 10 | 11 | class D2GIResourceContainer : public std::vector, public D2GIBase 12 | { 13 | CRITICAL_SECTION m_sCriticalSection; 14 | public: 15 | D2GIResourceContainer(D2GI*); 16 | ~D2GIResourceContainer(); 17 | 18 | VOID Add(D2GIResource*); 19 | VOID Remove(D2GIResource*); 20 | VOID ReleaseResources(); 21 | VOID LoadResources(); 22 | }; 23 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_direct3d.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../d3d/d3d_direct3d.h" 4 | 5 | #include "d2gi_common.h" 6 | 7 | 8 | class D2GIDirect3D : public D3DProxy, public D2GIBase 9 | { 10 | public: 11 | D2GIDirect3D(D2GI*); 12 | virtual ~D2GIDirect3D(); 13 | 14 | STDMETHOD(CreateDevice)(REFCLSID, D3D7::LPDIRECTDRAWSURFACE7, D3D7::LPDIRECT3DDEVICE7*); 15 | STDMETHOD(EnumDevices)(D3D7::LPD3DENUMDEVICESCALLBACK7, LPVOID); 16 | STDMETHOD(EnumZBufferFormats)(REFCLSID, D3D7::LPD3DENUMPIXELFORMATSCALLBACK, LPVOID); 17 | }; -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_surface.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "../common/common.h" 4 | 5 | #include "d2gi_surface.h" 6 | 7 | 8 | using namespace D3D7; 9 | 10 | 11 | D2GISurface::D2GISurface(D2GI* pD2GI, DWORD dwWidth, DWORD dwHeight, D2GIPIXELFORMAT eFormat) 12 | : D2GIResource(pD2GI) 13 | { 14 | m_dwWidth = dwWidth; 15 | m_dwHeight = dwHeight; 16 | m_eD2GIPixelFormat = eFormat; 17 | m_sDD7PixelFormat = g_asD2GIPF_To_DD7PF[eFormat]; 18 | m_dwBPP = m_sDD7PixelFormat.dwRGBBitCount; 19 | } 20 | 21 | 22 | D2GISurface::~D2GISurface() 23 | { 24 | } 25 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_resource.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "d2gi_resource.h" 3 | #include "d2gi_container.h" 4 | 5 | 6 | D2GIResource::D2GIResource(D2GI* pD2GI) 7 | : D2GIBase(pD2GI), m_pContainer(NULL) 8 | { 9 | } 10 | 11 | 12 | D2GIResource::~D2GIResource() 13 | { 14 | if(m_pContainer != NULL) 15 | m_pContainer->Remove(this); 16 | } 17 | 18 | 19 | VOID D2GIResource::AttachToContainer(D2GIResourceContainer* pContainer) 20 | { 21 | m_pContainer = pContainer; 22 | } 23 | 24 | 25 | VOID D2GIResource::DetachFromContainer() 26 | { 27 | m_pContainer = NULL; 28 | } 29 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_blitter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d2gi_common.h" 4 | 5 | 6 | struct FLOATRECT; 7 | 8 | 9 | class D2GIBlitter : public D2GIBase 10 | { 11 | D3D9::IDirect3DVertexDeclaration9* m_pVDecl; 12 | D3D9::IDirect3DVertexBuffer9* m_pVB; 13 | D3D9::IDirect3DVertexShader9* m_pVS; 14 | D3D9::IDirect3DPixelShader9* m_pPS; 15 | public: 16 | D2GIBlitter(D2GI*); 17 | ~D2GIBlitter(); 18 | 19 | VOID ReleaseResource(); 20 | VOID LoadResource(); 21 | ; 22 | VOID Blit(D3D9::IDirect3DSurface9*, FRECT*, D3D9::IDirect3DTexture9*, FRECT*, BOOL bEmulateCK); 23 | }; 24 | -------------------------------------------------------------------------------- /D2GI/src/common/frect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | 6 | struct FRECT 7 | { 8 | FLOAT fLeft, fTop, fRight, fBottom; 9 | 10 | FRECT(){} 11 | FRECT(FLOAT l, FLOAT t, FLOAT r, FLOAT b) 12 | { 13 | fLeft = l; fTop = t; fRight = r; fBottom = b; 14 | } 15 | FRECT(CONST RECT& rt) 16 | { 17 | fLeft = (FLOAT)rt.left; fTop = (FLOAT)rt.top; fRight = (FLOAT)rt.right; fBottom = (FLOAT)rt.bottom; 18 | } 19 | 20 | FLOAT GetWidth() { return fRight - fLeft; }; 21 | FLOAT GetHeight() { return fBottom - fTop; }; 22 | FLOAT GetXCenter() { return 0.5f * (fLeft + fRight); } 23 | FLOAT GetYCenter() { return 0.5f * (fTop + fBottom); } 24 | }; 25 | -------------------------------------------------------------------------------- /D2GI/defs.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GOG 8.1 SEMod 1.2 6 | E:\Program Files (x86)\Hard Truck 2\Hard Truck 2 $(D2VERSION)\ 7 | $(D2DIR)King.exe 8 | 9 | 10 | 11 | D2GI_VERSION=TEXT("0.1");%(PreprocessorDefinitions) 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /D2GI/src/ddraw/dd_palette.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "dd_palette.h" 3 | 4 | 5 | PaletteProxy::PaletteProxy() : Unknown() 6 | { 7 | 8 | } 9 | 10 | 11 | PaletteProxy::~PaletteProxy() 12 | { 13 | 14 | } 15 | 16 | 17 | HRESULT PaletteProxy::GetCaps(LPDWORD) 18 | { 19 | return DDERR_GENERIC; 20 | } 21 | 22 | 23 | HRESULT PaletteProxy::GetEntries(DWORD, DWORD, DWORD, LPPALETTEENTRY) 24 | { 25 | return DDERR_GENERIC; 26 | } 27 | 28 | 29 | HRESULT PaletteProxy::Initialize(D3D7::LPDIRECTDRAW, DWORD, LPPALETTEENTRY) 30 | { 31 | return DDERR_GENERIC; 32 | } 33 | 34 | 35 | HRESULT PaletteProxy::SetEntries(DWORD, DWORD dwIdx, DWORD dwCount, LPPALETTEENTRY pEntries) 36 | { 37 | return DDERR_GENERIC; 38 | } 39 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_palette.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../ddraw/dd_palette.h" 4 | 5 | #include "d2gi_common.h" 6 | #include "d2gi_resource.h" 7 | 8 | 9 | class D2GIPalette : public PaletteProxy, public D2GIResource 10 | { 11 | PALETTEENTRY m_asEntries[256]; 12 | UINT16 m_auEntries16[256]; 13 | 14 | VOID UpdateEntries16(DWORD dwIdx, DWORD dwCount); 15 | public: 16 | D2GIPalette(D2GI*, PALETTEENTRY*); 17 | virtual ~D2GIPalette(); 18 | 19 | virtual VOID ReleaseResource() {}; 20 | virtual VOID LoadResource() {}; 21 | 22 | STDMETHOD(SetEntries)(DWORD, DWORD, DWORD, LPPALETTEENTRY); 23 | 24 | PALETTEENTRY* GetEntries() { return m_asEntries; } 25 | UINT16* GetEntries16() { return m_auEntries16; } 26 | }; 27 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include "d2gi_common.h" 5 | 6 | 7 | enum WINDOWMODE 8 | { 9 | WMODE_WINDOWED, 10 | WMODE_BORDERLESS, 11 | WMODE_FULLSCREEN, 12 | }; 13 | 14 | 15 | class D2GIConfig 16 | { 17 | static WINDOWMODE s_eWindowMode; 18 | static DWORD s_dwVideoWidth, s_dwVideoHeight; 19 | static BOOL s_bEnableHooks; 20 | static BOOL s_bEnableVSync; 21 | public: 22 | static VOID ReadFromFile(); 23 | 24 | static WINDOWMODE GetWindowMode() { return s_eWindowMode; }; 25 | static DWORD GetVideoWidth(); 26 | static DWORD GetVideoHeight(); 27 | static BOOL HooksEnabled() { return s_bEnableHooks; }; 28 | static BOOL VSyncEnabled() { return s_bEnableVSync; } 29 | }; 30 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_hooks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/common.h" 4 | #include "../common/m3x4.h" 5 | 6 | #include "d2gi_common.h" 7 | 8 | 9 | class D2GIHookInjector 10 | { 11 | enum D2VERSION 12 | { 13 | D2V_UNKNOWN = -1, 14 | D2V_8_1, 15 | D2V_8_1B, 16 | }; 17 | 18 | static D2VERSION s_eCurrentD2Version; 19 | 20 | static D2GI* ObtainD2GI(); 21 | static INT __stdcall SetupTransforms(VOID* pThis, MAT3X4* pmView, MAT3X4* pmProj); 22 | static INT CallOriginalSetupTransforms(VOID* pThis, MAT3X4* pmView, MAT3X4* pmProj); 23 | 24 | static D2VERSION DetectD2Version(); 25 | static BOOL PatchCallOperation(DWORD dwOperationAddress, DWORD dwNewCallAddress); 26 | public: 27 | static VOID InjectHooks(); 28 | }; 29 | -------------------------------------------------------------------------------- /D2GI/src/ddraw/dd_palette.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/common.h" 4 | #include "../common/d3d7.h" 5 | 6 | 7 | class PaletteProxy : public D3D7::IDirectDrawPalette, public Unknown 8 | { 9 | public: 10 | PaletteProxy(); 11 | virtual ~PaletteProxy(); 12 | 13 | STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj) { return Unknown::QueryInterface(riid, ppvObj); }; 14 | STDMETHOD_(ULONG, AddRef) () { return Unknown::AddRef(); }; 15 | STDMETHOD_(ULONG, Release) () { return Unknown::Release(); }; 16 | 17 | STDMETHOD(GetCaps)(LPDWORD); 18 | STDMETHOD(GetEntries)(DWORD, DWORD, DWORD, LPPALETTEENTRY); 19 | STDMETHOD(Initialize)(D3D7::LPDIRECTDRAW, DWORD, LPPALETTEENTRY); 20 | STDMETHOD(SetEntries)(DWORD, DWORD, DWORD, LPPALETTEENTRY); 21 | }; 22 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_prim_single_surf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d2gi_surface.h" 4 | #include "d2gi_palette.h" 5 | 6 | 7 | class D2GIPrimarySingleSurface : public D2GISurface 8 | { 9 | D2GIPalette* m_pPalette; 10 | public: 11 | D2GIPrimarySingleSurface(D2GI*, DWORD dwWidth, DWORD dwHeight, D2GIPIXELFORMAT eFormat); 12 | virtual ~D2GIPrimarySingleSurface(); 13 | 14 | virtual SURFACETYPE GetType() { return ST_PRIMARY_SINGLE; } 15 | virtual VOID ReleaseResource() {}; 16 | virtual VOID LoadResource() {}; 17 | 18 | STDMETHOD(GetSurfaceDesc)(D3D7::LPDDSURFACEDESC2); 19 | STDMETHOD(SetPalette)(D3D7::LPDIRECTDRAWPALETTE); 20 | STDMETHOD(IsLost)(); 21 | STDMETHOD(Blt)(LPRECT, D3D7::LPDIRECTDRAWSURFACE7, LPRECT, DWORD, D3D7::LPDDBLTFX); 22 | 23 | D2GIPalette* GetPalette() { return m_pPalette; } 24 | }; 25 | -------------------------------------------------------------------------------- /D2GI/D2GI.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(D2EXE) 5 | $(D2DIR) 6 | WindowsLocalDebugger 7 | false 8 | 9 | 10 | $(D2EXE) 11 | $(D2DIR) 12 | WindowsLocalDebugger 13 | true 14 | 15 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_prim_flip_surf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d2gi_surface.h" 4 | 5 | 6 | class D2GIBackBufferSurface; 7 | 8 | 9 | class D2GIPrimaryFlippableSurface : public D2GISurface 10 | { 11 | D2GIBackBufferSurface* m_pBackBuffer; 12 | public: 13 | D2GIPrimaryFlippableSurface(D2GI*, DWORD dwW, DWORD dwH, D2GIPIXELFORMAT); 14 | virtual ~D2GIPrimaryFlippableSurface(); 15 | 16 | virtual SURFACETYPE GetType() { return ST_PRIMARY_FLIPPABLE; } 17 | virtual VOID ReleaseResource(); 18 | virtual VOID LoadResource(); 19 | 20 | STDMETHOD(GetAttachedSurface)(D3D7::LPDDSCAPS2, D3D7::LPDIRECTDRAWSURFACE7 FAR*); 21 | STDMETHOD(GetSurfaceDesc)(D3D7::LPDDSURFACEDESC2); 22 | STDMETHOD(IsLost)(); 23 | STDMETHOD(Flip)(D3D7::LPDIRECTDRAWSURFACE7, DWORD); 24 | STDMETHOD(GetFlipStatus)(DWORD); 25 | 26 | D2GIBackBufferSurface* GetBackBufferSurface() { return m_pBackBuffer; } 27 | }; 28 | -------------------------------------------------------------------------------- /D2GI/src/common/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | #ifndef D2GI_VERSION 9 | #define D2GI_VERSION TEXT("UNDEFINED") 10 | #endif 11 | 12 | 13 | #ifdef UNICODE 14 | #define ASCII_STR TEXT("%S") 15 | #else 16 | #define ASCII_STR TEXT("%s") 17 | #endif 18 | 19 | 20 | #define RELEASE(x) {if((x) != NULL) {(x)->Release(); (x) = NULL;} } 21 | #define DEL(x) {if((x) != NULL) {delete (x); (x) = NULL;}} 22 | 23 | 24 | class Unknown : public IUnknown 25 | { 26 | protected: 27 | UINT m_uRefCount; 28 | public: 29 | Unknown() : m_uRefCount(1) {} 30 | virtual ~Unknown() {} 31 | 32 | STDMETHOD_(ULONG, AddRef)() { return ++m_uRefCount; } 33 | STDMETHOD_(ULONG, Release)() { ULONG uRes = --m_uRefCount; if (uRes == 0) delete this; return uRes; } 34 | STDMETHOD(QueryInterface)(REFIID, LPVOID FAR*) { return S_FALSE; } 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /D2GI/src/common/dir.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "dir.h" 3 | 4 | 5 | TCHAR Directory::s_szSysDir[MAX_PATH] = { '\0' }; 6 | TCHAR Directory::s_szEXEDir[MAX_PATH] = { '\0' }; 7 | TCHAR Directory::s_szEXEPath[MAX_PATH] = { '\0' }; 8 | 9 | 10 | TCHAR* Directory::GetEXEDirectory() 11 | { 12 | if (*s_szEXEDir == '\0') 13 | { 14 | TCHAR* c; 15 | 16 | GetModuleFileName(NULL, s_szEXEDir, MAX_PATH); 17 | c = s_szEXEDir + _tcslen(s_szEXEDir); 18 | while (*c != '\\' && c >= s_szEXEDir) 19 | *(c--) = '\0'; 20 | } 21 | 22 | return s_szEXEDir; 23 | } 24 | 25 | 26 | TCHAR* Directory::GetEXEPath() 27 | { 28 | if (*s_szEXEPath == '\0') 29 | GetModuleFileName(NULL, s_szEXEPath, MAX_PATH); 30 | 31 | return s_szEXEPath; 32 | } 33 | 34 | 35 | TCHAR* Directory::GetSysDirectory() 36 | { 37 | if (*s_szSysDir == '\0') 38 | GetSystemDirectory(s_szSysDir, MAX_PATH); 39 | 40 | return s_szSysDir; 41 | } 42 | -------------------------------------------------------------------------------- /D2GI/src/d3d/d3d_direct3d.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/common.h" 4 | #include "../common/d3d7.h" 5 | 6 | 7 | class D3DProxy : public D3D7::IDirect3D7, public Unknown 8 | { 9 | public: 10 | D3DProxy(); 11 | virtual ~D3DProxy(); 12 | 13 | STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppvObj) { return Unknown::QueryInterface(riid, ppvObj); }; 14 | STDMETHOD_(ULONG, AddRef)() { return Unknown::AddRef(); }; 15 | STDMETHOD_(ULONG, Release)() { return Unknown::Release(); }; 16 | 17 | STDMETHOD(EnumDevices)(D3D7::LPD3DENUMDEVICESCALLBACK7, LPVOID) ; 18 | STDMETHOD(CreateDevice)( REFCLSID, D3D7::LPDIRECTDRAWSURFACE7, D3D7::LPDIRECT3DDEVICE7*) ; 19 | STDMETHOD(CreateVertexBuffer)(D3D7::LPD3DVERTEXBUFFERDESC, D3D7::LPDIRECT3DVERTEXBUFFER7*, DWORD) ; 20 | STDMETHOD(EnumZBufferFormats)( REFCLSID, D3D7::LPD3DENUMPIXELFORMATSCALLBACK, LPVOID) ; 21 | STDMETHOD(EvictManagedTextures)() ; 22 | }; 23 | -------------------------------------------------------------------------------- /D2GI/src/d3d/d3d_direct3d.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/common.h" 3 | 4 | #include "d3d_direct3d.h" 5 | 6 | 7 | using namespace D3D7; 8 | 9 | 10 | D3DProxy::D3DProxy() : Unknown() 11 | { 12 | 13 | } 14 | 15 | 16 | D3DProxy::~D3DProxy() 17 | { 18 | 19 | } 20 | 21 | 22 | HRESULT D3DProxy::EnumDevices(LPD3DENUMDEVICESCALLBACK7 lpCallback, LPVOID lpArg) 23 | { 24 | return DDERR_GENERIC; 25 | } 26 | 27 | 28 | HRESULT D3DProxy::CreateDevice(REFCLSID iid, LPDIRECTDRAWSURFACE7 lpSurf, LPDIRECT3DDEVICE7* lpDev) 29 | { 30 | return DDERR_GENERIC; 31 | } 32 | 33 | 34 | HRESULT D3DProxy::CreateVertexBuffer(LPD3DVERTEXBUFFERDESC lpDesc, LPDIRECT3DVERTEXBUFFER7* lpVB, DWORD dwFlags) 35 | { 36 | return DDERR_GENERIC; 37 | } 38 | 39 | 40 | HRESULT D3DProxy::EnumZBufferFormats(REFCLSID iid, LPD3DENUMPIXELFORMATSCALLBACK lpCallback, LPVOID lpArg) 41 | { 42 | return DDERR_GENERIC; 43 | } 44 | 45 | 46 | HRESULT D3DProxy::EvictManagedTextures() 47 | { 48 | return DDERR_GENERIC; 49 | } 50 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_strided_renderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/common.h" 4 | #include "../common/d3d7.h" 5 | 6 | #include "d2gi_common.h" 7 | 8 | 9 | class D2GIVertexBufferContainer; 10 | class D2GIIndexBufferContainer; 11 | 12 | 13 | class D2GIStridedPrimitiveRenderer : public D2GIBase 14 | { 15 | D2GIVertexBufferContainer* m_pVBContainer; 16 | D2GIIndexBufferContainer* m_pIBContainer; 17 | 18 | VOID SetupVertexStream(DWORD dwFVF, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA pData, DWORD dwCount); 19 | public: 20 | D2GIStridedPrimitiveRenderer(D2GI*); 21 | ~D2GIStridedPrimitiveRenderer(); 22 | 23 | VOID ReleaseResource(); 24 | VOID LoadResource(); 25 | VOID OnPresentationFinished(); 26 | 27 | 28 | VOID DrawIndexedPrimitiveStrided(D3D7::D3DPRIMITIVETYPE, DWORD, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, LPWORD, DWORD, DWORD); 29 | VOID DrawPrimitiveStrided(D3D7::D3DPRIMITIVETYPE pt, DWORD dwFVF, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA pData, DWORD dwCount, DWORD dwFlags); 30 | }; 31 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_surface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../ddraw/dd_surface.h" 4 | 5 | #include "d2gi_common.h" 6 | #include "d2gi_resource.h" 7 | #include "d2gi_enums.h" 8 | 9 | 10 | enum SURFACETYPE 11 | { 12 | ST_PRIMARY_FLIPPABLE, 13 | ST_BACKBUFFER, 14 | ST_PRIMARY_SINGLE, 15 | ST_ZBUFFER, 16 | ST_TEXTURE, 17 | ST_SYSMEM, 18 | ST_MIPMAP, 19 | }; 20 | 21 | 22 | class D2GISurface : public SurfaceProxy, public D2GIResource 23 | { 24 | protected: 25 | DWORD m_dwWidth, m_dwHeight, m_dwBPP; 26 | D3D7::DDPIXELFORMAT m_sDD7PixelFormat; 27 | D2GIPIXELFORMAT m_eD2GIPixelFormat; 28 | public: 29 | D2GISurface(D2GI*, DWORD dwW, DWORD dwH, D2GIPIXELFORMAT); 30 | virtual ~D2GISurface(); 31 | 32 | virtual SURFACETYPE GetType() = 0; 33 | 34 | DWORD GetWidth() { return m_dwWidth; } 35 | DWORD GetHeight() { return m_dwHeight; } 36 | DWORD GetBPP() { return m_dwBPP; } 37 | D3D7::DDPIXELFORMAT* GetDD7PixelFormat() { return &m_sDD7PixelFormat; } 38 | D2GIPIXELFORMAT GetD2GIPixelFormat() { return m_eD2GIPixelFormat; } 39 | }; 40 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_palette.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "d2gi_palette.h" 3 | 4 | 5 | D2GIPalette::D2GIPalette(D2GI* pD2GI, PALETTEENTRY* pEntries) 6 | : PaletteProxy(), D2GIResource(pD2GI) 7 | { 8 | CopyMemory(m_asEntries, pEntries, sizeof(m_asEntries)); 9 | UpdateEntries16(0, 256); 10 | } 11 | 12 | 13 | D2GIPalette::~D2GIPalette() 14 | { 15 | } 16 | 17 | 18 | HRESULT D2GIPalette::SetEntries(DWORD, DWORD dwIdx, DWORD dwCount, LPPALETTEENTRY pEntries) 19 | { 20 | CopyMemory(m_asEntries + dwIdx, pEntries, sizeof(PALETTEENTRY) * dwCount); 21 | UpdateEntries16(dwIdx, dwCount); 22 | 23 | return DD_OK; 24 | } 25 | 26 | 27 | VOID D2GIPalette::UpdateEntries16(DWORD dwIdx, DWORD dwCount) 28 | { 29 | DWORD i; 30 | 31 | for (i = dwIdx; i < dwIdx + dwCount; i++) 32 | { 33 | BYTE bR = (BYTE)((INT)m_asEntries[i].peRed * 31 / 255); 34 | BYTE bG = (BYTE)((INT)m_asEntries[i].peGreen * 63 / 255); 35 | BYTE bB = (BYTE)((INT)m_asEntries[i].peBlue * 31 / 255); 36 | 37 | m_auEntries16[i] = (UINT16)((bR << 11) | (bG << 5) | (bB)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_sysmem_surf.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/logger.h" 3 | 4 | #include "d2gi.h" 5 | #include "d2gi_sysmem_surf.h" 6 | #include "d2gi_enums.h" 7 | #include "d2gi_palette.h" 8 | 9 | 10 | D2GISystemMemorySurface::D2GISystemMemorySurface(D2GI* pD2GI, 11 | DWORD dwWidth, DWORD dwHeight, D2GIPIXELFORMAT eFormat) 12 | : D2GITexture(pD2GI, dwWidth, dwHeight, eFormat, 1) 13 | { 14 | } 15 | 16 | 17 | D2GISystemMemorySurface::~D2GISystemMemorySurface() 18 | { 19 | } 20 | 21 | 22 | HRESULT D2GISystemMemorySurface::Lock(LPRECT pRect, D3D7::LPDDSURFACEDESC2 pDesc, DWORD dwFlags, HANDLE h) 23 | { 24 | HRESULT hRes = D2GITexture::Lock(pRect, pDesc, dwFlags, h); 25 | 26 | if (SUCCEEDED(hRes)) 27 | { 28 | pDesc->dwFlags ^= DDSD_MIPMAPCOUNT; 29 | pDesc->ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY; 30 | } 31 | 32 | return hRes; 33 | } 34 | 35 | 36 | HRESULT D2GISystemMemorySurface::GetCaps(D3D7::LPDDSCAPS2 pCaps) 37 | { 38 | ZeroMemory(pCaps, sizeof(D3D7::DDSCAPS2)); 39 | pCaps->dwCaps = DDSCAPS_SYSTEMMEMORY; 40 | 41 | return DD_OK; 42 | } 43 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_backbuf_surf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d2gi_surface.h" 4 | 5 | 6 | class D2GIBackBufferSurface : public D2GISurface 7 | { 8 | D3D9::IDirect3DTexture9* m_pStreamingTexture; 9 | D3D9::IDirect3DSurface9* m_pStreamingSurface; 10 | D3D9::IDirect3DSurface9* m_pReadingSurface; 11 | D3D9::IDirect3DSurface9* m_pOffSurface; 12 | BOOL m_bLastLockReadOnly; 13 | 14 | public: 15 | D2GIBackBufferSurface(D2GI*, DWORD dwW, DWORD dwH, D2GIPIXELFORMAT); 16 | virtual ~D2GIBackBufferSurface(); 17 | 18 | virtual SURFACETYPE GetType() { return ST_BACKBUFFER; } 19 | virtual VOID ReleaseResource(); 20 | virtual VOID LoadResource(); 21 | 22 | STDMETHOD(Lock)(LPRECT, D3D7::LPDDSURFACEDESC2, DWORD, HANDLE); 23 | STDMETHOD(Unlock)(LPRECT); 24 | STDMETHOD(IsLost)(); 25 | STDMETHOD(AddAttachedSurface)(D3D7::LPDIRECTDRAWSURFACE7); 26 | STDMETHOD(Blt)(LPRECT, D3D7::LPDIRECTDRAWSURFACE7, LPRECT, DWORD, D3D7::LPDDBLTFX); 27 | 28 | D3D9::IDirect3DSurface9* GetD3D9StreamingSurface() { return m_pStreamingSurface; } 29 | D3D9::IDirect3DSurface9* GetD3D9ReadingSurface() { return m_pReadingSurface; } 30 | }; 31 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_mipmap_surf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d2gi_surface.h" 4 | 5 | 6 | class D2GITexture; 7 | class D2GIPalette; 8 | 9 | 10 | class D2GIMipMapSurface : public D2GISurface 11 | { 12 | D2GITexture* m_pParent; 13 | D2GIMipMapSurface* m_pNextLevel; 14 | UINT m_uLevelID; 15 | 16 | D3D9::IDirect3DSurface9* m_pSurface; 17 | VOID* m_pData; 18 | UINT m_uDataSize, m_uDataPitch; 19 | 20 | public: 21 | D2GIMipMapSurface(D2GITexture*, UINT, D2GIMipMapSurface*, DWORD dwW, DWORD dwH, D2GIPIXELFORMAT); 22 | virtual ~D2GIMipMapSurface(); 23 | 24 | virtual SURFACETYPE GetType() { return ST_MIPMAP; } 25 | virtual VOID ReleaseResource() {}; 26 | virtual VOID LoadResource() {}; 27 | 28 | VOID SetD3D9Surface(D3D9::IDirect3DSurface9*); 29 | D3D9::IDirect3DSurface9* GetD3D9Surface() { return m_pSurface; } 30 | 31 | STDMETHOD(Lock)(LPRECT, D3D7::LPDDSURFACEDESC2, DWORD, HANDLE); 32 | STDMETHOD(Unlock)(LPRECT); 33 | STDMETHOD(GetAttachedSurface)(D3D7::LPDDSCAPS2, D3D7::LPDIRECTDRAWSURFACE7 FAR*); 34 | VOID UpdateSurface(); 35 | VOID UpdateWithPalette(D2GIPalette*); 36 | VOID* GetData() { return m_pData; } 37 | UINT GetDataPitch() { return m_uDataPitch; } 38 | }; 39 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_vb_container.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/logger.h" 3 | 4 | #include "d2gi_vb_container.h" 5 | 6 | 7 | #define DEFAULT_VB_SIZE (32 * 256 * 256) 8 | 9 | 10 | D2GIVertexBufferContainer::D2GIVertexBufferContainer(D2GI* pD2GI) 11 | : D2GIBufferContainer(pD2GI) 12 | { 13 | 14 | } 15 | 16 | 17 | D2GIVertexBufferContainer::~D2GIVertexBufferContainer() 18 | { 19 | 20 | } 21 | 22 | 23 | VERTEX_STREAMING_BUFFER* D2GIVertexBufferContainer::AllocNewBuffer(UINT uRequiredSize) 24 | { 25 | UINT uSelectedSize = max(uRequiredSize, DEFAULT_VB_SIZE); 26 | D3D9::IDirect3DDevice9* pDev = GetD3D9Device(); 27 | D3D9::IDirect3DVertexBuffer9* pVB; 28 | 29 | if (FAILED(pDev->CreateVertexBuffer(uSelectedSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 30 | 0, D3D9::D3DPOOL_DEFAULT, &pVB, NULL))) 31 | Logger::Error(TEXT("Failed to alloc new vertex buffer for streaming")); 32 | 33 | push_back(VERTEX_STREAMING_BUFFER(pVB, uSelectedSize)); 34 | pVB->Release(); 35 | 36 | return data() + size() - 1; 37 | } 38 | 39 | 40 | VOID D2GIVertexBufferContainer::SetAsSource(UINT uStride) 41 | { 42 | GetD3D9Device()->SetStreamSource(0, m_pLastLockBuffer->pBuffer, m_uLastLockOffset, uStride); 43 | } 44 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_ib_container.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/logger.h" 3 | 4 | #include "d2gi_ib_container.h" 5 | 6 | 7 | #define DEFAULT_IB_SIZE (2 * 256 * 256) 8 | 9 | 10 | D2GIIndexBufferContainer::D2GIIndexBufferContainer(D2GI* pD2GI) 11 | : D2GIBufferContainer(pD2GI) 12 | { 13 | 14 | } 15 | 16 | 17 | D2GIIndexBufferContainer::~D2GIIndexBufferContainer() 18 | { 19 | 20 | } 21 | 22 | 23 | INDEX_STREAMING_BUFFER* D2GIIndexBufferContainer::AllocNewBuffer(UINT uRequiredSize) 24 | { 25 | UINT uSelectedSize = max(uRequiredSize, DEFAULT_IB_SIZE); 26 | D3D9::IDirect3DDevice9* pDev = GetD3D9Device(); 27 | D3D9::IDirect3DIndexBuffer9* pIB; 28 | 29 | if (FAILED(pDev->CreateIndexBuffer(uSelectedSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 30 | D3D9::D3DFMT_INDEX16, D3D9::D3DPOOL_DEFAULT, &pIB, NULL))) 31 | Logger::Error(TEXT("Failed to alloc new index buffer for streaming")); 32 | 33 | push_back(INDEX_STREAMING_BUFFER(pIB, uSelectedSize)); 34 | pIB->Release(); 35 | 36 | return data() + size() - 1; 37 | } 38 | 39 | 40 | UINT D2GIIndexBufferContainer::SetAsSource() 41 | { 42 | GetD3D9Device()->SetIndices(m_pLastLockBuffer->pBuffer); 43 | 44 | return m_uLastLockOffset / sizeof(UINT16); 45 | } 46 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_direct3d.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/common.h" 3 | 4 | #include "d2gi_direct3d.h" 5 | #include "d2gi_surface.h" 6 | #include "d2gi_device.h" 7 | #include "d2gi_enums.h" 8 | 9 | using namespace D3D7; 10 | 11 | 12 | D2GIDirect3D::D2GIDirect3D(D2GI* pD2GI) : D3DProxy(), D2GIBase(pD2GI) 13 | { 14 | 15 | } 16 | 17 | 18 | D2GIDirect3D::~D2GIDirect3D() 19 | { 20 | 21 | } 22 | 23 | 24 | HRESULT D2GIDirect3D::CreateDevice(REFCLSID iid, LPDIRECTDRAWSURFACE7 lpSurf, LPDIRECT3DDEVICE7* lpDev) 25 | { 26 | *lpDev = (IDirect3DDevice7*)new D2GIDevice(m_pD2GI); 27 | 28 | return DD_OK; 29 | } 30 | 31 | 32 | HRESULT D2GIDirect3D::EnumDevices(LPD3DENUMDEVICESCALLBACK7 pCallback, LPVOID pArg) 33 | { 34 | INT i; 35 | 36 | for (i = 0; i < (INT)g_uDeviceCount; i++) 37 | { 38 | if (!pCallback(g_lpszDeviceDescs[i], g_lpszDeviceNames[i], g_asDeviceDescs + i, pArg)) 39 | break; 40 | } 41 | 42 | return D3D_OK; 43 | } 44 | 45 | 46 | HRESULT D2GIDirect3D::EnumZBufferFormats(REFCLSID, D3D7::LPD3DENUMPIXELFORMATSCALLBACK pCallback, LPVOID lpArg) 47 | { 48 | INT i; 49 | 50 | for (i = 0; i < (INT)g_uZBufferFormatsCount; i++) 51 | { 52 | if (!pCallback(g_asZBufferFormats + i, lpArg)) 53 | break; 54 | } 55 | 56 | return DD_OK; 57 | } 58 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_enums.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/d3d7.h" 4 | 5 | #include "d2gi_common.h" 6 | 7 | 8 | enum D2GIPIXELFORMAT 9 | { 10 | D2GIPF_UNKNOWN = -1, 11 | D2GIPF_8_PAL, 12 | D2GIPF_16_565, 13 | D2GIPF_16_1555, 14 | D2GIPF_16_4444, 15 | D2GIPF_16_V8U8, 16 | D2GIPF_16_DEPTH, 17 | D2GIPF_16_555, 18 | }; 19 | 20 | 21 | extern D3D7::DDSURFACEDESC2 g_asStdDisplayModes[]; 22 | extern UINT g_uStdDisplayModesCount; 23 | 24 | extern D3D7::DDCAPS g_sHALCaps; 25 | extern D3D7::DDCAPS g_sHELCaps; 26 | 27 | extern D3D7::D3DDEVICEDESC7 g_asDeviceDescs[]; 28 | extern CHAR* g_lpszDeviceDescs[]; 29 | extern CHAR* g_lpszDeviceNames[]; 30 | extern UINT g_uDeviceCount; 31 | 32 | extern D3D7::DDPIXELFORMAT g_asTextureFormats[]; 33 | extern UINT g_uTextureFormatsCount; 34 | 35 | extern D3D7::DDPIXELFORMAT g_pf16_565; 36 | extern D3D7::DDPIXELFORMAT g_pf16_1555; 37 | extern D3D7::DDPIXELFORMAT g_pf16_4444; 38 | extern D3D7::DDPIXELFORMAT g_pf8_Pal; 39 | extern D3D7::DDPIXELFORMAT g_pf16_v8u8; 40 | 41 | extern D3D7::DDPIXELFORMAT g_asZBufferFormats[]; 42 | extern UINT g_uZBufferFormatsCount; 43 | 44 | extern D3D7::DDPIXELFORMAT g_asD2GIPF_To_DD7PF[]; 45 | extern D3D9::D3DFORMAT g_asD2GIPF_To_D3D9PF[]; 46 | 47 | D2GIPIXELFORMAT DD7PF_To_D2GIPF(D3D7::DDPIXELFORMAT*); 48 | BOOL IsStdDisplayMode(DWORD dwWidth, DWORD dwHeight); 49 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_texture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d2gi_surface.h" 4 | #include "d2gi_mipmap_surf.h" 5 | 6 | 7 | class D2GIPalette; 8 | 9 | 10 | class D2GITexture : public D2GISurface 11 | { 12 | protected: 13 | DWORD m_dwMipMapCount; 14 | D2GIMipMapSurface** m_lpMipMapLevels; 15 | 16 | D3D9::IDirect3DTexture9* m_pTexture; 17 | 18 | D3D7::DDCOLORKEY m_sColorKey; 19 | BOOL m_bColorKeySet; 20 | public: 21 | D2GITexture(D2GI*, DWORD dwW, DWORD dwH, D2GIPIXELFORMAT, DWORD dwMipMapCount); 22 | virtual ~D2GITexture(); 23 | 24 | virtual SURFACETYPE GetType() { return ST_TEXTURE; } 25 | virtual VOID LoadResource(); 26 | virtual VOID ReleaseResource(); 27 | 28 | STDMETHOD(SetColorKey)(DWORD, D3D7::LPDDCOLORKEY); 29 | STDMETHOD(IsLost)(); 30 | STDMETHOD(Lock)(LPRECT, D3D7::LPDDSURFACEDESC2, DWORD, HANDLE); 31 | STDMETHOD(Unlock)(LPRECT); 32 | STDMETHOD(Blt)(LPRECT, D3D7::LPDIRECTDRAWSURFACE7, LPRECT, DWORD, D3D7::LPDDBLTFX); 33 | STDMETHOD(GetAttachedSurface)(D3D7::LPDDSCAPS2, D3D7::LPDIRECTDRAWSURFACE7 FAR*); 34 | STDMETHOD(GetSurfaceDesc)(D3D7::LPDDSURFACEDESC2); 35 | 36 | D3D9::IDirect3DSurface9* GetD3D9Surface(); 37 | D3D9::IDirect3DTexture9* GetD3D9Texture() { return m_pTexture; } 38 | DWORD GetMipMapCount() { return m_dwMipMapCount; } 39 | DWORD GetOriginalColorKeyValue(); 40 | BOOL HasColorKeyConversion(); 41 | VOID UpdateWithPalette(D2GIPalette*); 42 | BOOL CopyFrom(D2GITexture*); 43 | }; 44 | -------------------------------------------------------------------------------- /D2GI.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29215.179 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D2GI", "D2GI\D2GI.vcxproj", "{D32A70F2-AADF-4E5B-B11B-D78C75EC98B4}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {D32A70F2-AADF-4E5B-B11B-D78C75EC98B4}.Debug|x64.ActiveCfg = Debug|x64 17 | {D32A70F2-AADF-4E5B-B11B-D78C75EC98B4}.Debug|x64.Build.0 = Debug|x64 18 | {D32A70F2-AADF-4E5B-B11B-D78C75EC98B4}.Debug|x86.ActiveCfg = Debug|Win32 19 | {D32A70F2-AADF-4E5B-B11B-D78C75EC98B4}.Debug|x86.Build.0 = Debug|Win32 20 | {D32A70F2-AADF-4E5B-B11B-D78C75EC98B4}.Release|x64.ActiveCfg = Release|x64 21 | {D32A70F2-AADF-4E5B-B11B-D78C75EC98B4}.Release|x64.Build.0 = Release|x64 22 | {D32A70F2-AADF-4E5B-B11B-D78C75EC98B4}.Release|x86.ActiveCfg = Release|Win32 23 | {D32A70F2-AADF-4E5B-B11B-D78C75EC98B4}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {822F066E-2D3C-4C8B-92CB-114545EF751A} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_ddraw.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../ddraw/dd_ddraw.h" 4 | 5 | #include "d2gi_common.h" 6 | #include "d2gi_container.h" 7 | #include "d2gi_prim_flip_surf.h" 8 | #include "d2gi_prim_single_surf.h" 9 | 10 | 11 | class D2GIDirectDraw : public DDrawProxy, public D2GIBase 12 | { 13 | D2GIResourceContainer* m_pResourceContainer; 14 | D2GIPrimaryFlippableSurface* m_pPrimaryFlippableSurf; 15 | D2GIPrimarySingleSurface* m_pPrimarySingleSurf; 16 | public: 17 | D2GIDirectDraw(D2GI*); 18 | virtual ~D2GIDirectDraw(); 19 | 20 | STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj); 21 | STDMETHOD(CreateSurface)(D3D7::LPDDSURFACEDESC2, D3D7::LPDIRECTDRAWSURFACE7 FAR*, IUnknown FAR*); 22 | STDMETHOD(SetCooperativeLevel)(HWND, DWORD); 23 | STDMETHOD(SetDisplayMode)(DWORD, DWORD, DWORD, DWORD, DWORD); 24 | STDMETHOD(EnumDisplayModes)(DWORD, D3D7::LPDDSURFACEDESC2, LPVOID, D3D7::LPDDENUMMODESCALLBACK2); 25 | STDMETHOD(GetCaps)(D3D7::LPDDCAPS, D3D7::LPDDCAPS); 26 | STDMETHOD(GetDeviceIdentifier)(D3D7::LPDDDEVICEIDENTIFIER2, DWORD); 27 | STDMETHOD(GetAvailableVidMem)(D3D7::LPDDSCAPS2, LPDWORD, LPDWORD); 28 | STDMETHOD(RestoreDisplayMode)(); 29 | STDMETHOD(CreatePalette)(DWORD, LPPALETTEENTRY, D3D7::LPDIRECTDRAWPALETTE FAR*, IUnknown FAR*); 30 | 31 | VOID ReleaseResources(); 32 | VOID LoadResources(); 33 | D2GIPrimaryFlippableSurface* GetPrimaryFlippableSurface() { return m_pPrimaryFlippableSurf; } 34 | D2GIPrimarySingleSurface* GetPrimarySingleSurface() { return m_pPrimarySingleSurf; } 35 | }; 36 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_device.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../d3d/d3d_device.h" 4 | 5 | #include "d2gi_common.h" 6 | 7 | 8 | class D2GIDevice : public DeviceProxy, public D2GIBase 9 | { 10 | public: 11 | D2GIDevice(D2GI*); 12 | virtual ~D2GIDevice(); 13 | 14 | STDMETHOD(EnumTextureFormats)(D3D7::LPD3DENUMPIXELFORMATSCALLBACK, LPVOID); 15 | STDMETHOD(SetTexture)(DWORD, D3D7::LPDIRECTDRAWSURFACE7); 16 | STDMETHOD(SetViewport)(D3D7::LPD3DVIEWPORT7); 17 | STDMETHOD(Clear)(DWORD, D3D7::LPD3DRECT, DWORD, D3D7::D3DCOLOR, D3D7::D3DVALUE, DWORD); 18 | STDMETHOD(LightEnable)(DWORD, BOOL); 19 | STDMETHOD(BeginScene)(); 20 | STDMETHOD(EndScene)(); 21 | STDMETHOD(SetRenderState)(D3D7::D3DRENDERSTATETYPE, DWORD); 22 | STDMETHOD(SetTextureStageState)(DWORD, D3D7::D3DTEXTURESTAGESTATETYPE, DWORD); 23 | STDMETHOD(ValidateDevice)(LPDWORD); 24 | STDMETHOD(SetTransform)(D3D7::D3DTRANSFORMSTATETYPE, D3D7::LPD3DMATRIX); 25 | STDMETHOD(SetLight)(DWORD, D3D7::LPD3DLIGHT7); 26 | STDMETHOD(SetMaterial)(D3D7::LPD3DMATERIAL7); 27 | STDMETHOD(SetClipStatus)(D3D7::LPD3DCLIPSTATUS); 28 | STDMETHOD(DrawIndexedPrimitiveStrided)(D3D7::D3DPRIMITIVETYPE, DWORD, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, LPWORD, DWORD, DWORD); 29 | STDMETHOD(DrawPrimitiveStrided)(D3D7::D3DPRIMITIVETYPE, DWORD, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, DWORD); 30 | STDMETHOD(DrawPrimitive)(D3D7::D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, DWORD); 31 | STDMETHOD(DrawIndexedPrimitive)(D3D7::D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, LPWORD, DWORD, DWORD); 32 | STDMETHOD(GetRenderState)(D3D7::D3DRENDERSTATETYPE, LPDWORD); 33 | }; 34 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_container.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "d2gi_container.h" 3 | #include "d2gi_resource.h" 4 | 5 | 6 | 7 | D2GIResourceContainer::D2GIResourceContainer(D2GI* pD2GI) : D2GIBase(pD2GI) 8 | { 9 | InitializeCriticalSection(&m_sCriticalSection); 10 | } 11 | 12 | 13 | D2GIResourceContainer::~D2GIResourceContainer() 14 | { 15 | EnterCriticalSection(&m_sCriticalSection); 16 | for (D2GIResource* pRes : *this) 17 | pRes->DetachFromContainer(); 18 | LeaveCriticalSection(&m_sCriticalSection); 19 | 20 | DeleteCriticalSection(&m_sCriticalSection); 21 | } 22 | 23 | 24 | VOID D2GIResourceContainer::Add(D2GIResource* pRes) 25 | { 26 | EnterCriticalSection(&m_sCriticalSection); 27 | pRes->AttachToContainer(this); 28 | push_back(pRes); 29 | LeaveCriticalSection(&m_sCriticalSection); 30 | } 31 | 32 | 33 | VOID D2GIResourceContainer::Remove(D2GIResource* pRes) 34 | { 35 | INT i; 36 | 37 | EnterCriticalSection(&m_sCriticalSection); 38 | 39 | for (i = 0; i < (INT)size(); i++) 40 | { 41 | if ((*this)[i] == pRes) 42 | { 43 | pRes->DetachFromContainer(); 44 | erase(begin() + i); 45 | break; 46 | } 47 | } 48 | 49 | 50 | LeaveCriticalSection(&m_sCriticalSection); 51 | } 52 | 53 | 54 | VOID D2GIResourceContainer::ReleaseResources() 55 | { 56 | INT i; 57 | 58 | EnterCriticalSection(&m_sCriticalSection); 59 | for (i = 0; i < (INT)size(); i++) 60 | (*this)[i]->ReleaseResource(); 61 | LeaveCriticalSection(&m_sCriticalSection); 62 | } 63 | 64 | 65 | VOID D2GIResourceContainer::LoadResources() 66 | { 67 | INT i; 68 | 69 | EnterCriticalSection(&m_sCriticalSection); 70 | for (i = 0; i < (INT)size(); i++) 71 | (*this)[i]->LoadResource(); 72 | LeaveCriticalSection(&m_sCriticalSection); 73 | } 74 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_buffer_container.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "d2gi_buffer_container.h" 3 | 4 | 5 | template class D2GIBufferContainer; 6 | template class D2GIBufferContainer; 7 | 8 | 9 | template 10 | D2GIBufferContainer::D2GIBufferContainer(D2GI* pD2GI) 11 | : D2GIBase(pD2GI) 12 | { 13 | } 14 | 15 | 16 | template 17 | D2GIBufferContainer::~D2GIBufferContainer() 18 | { 19 | ReleaseResource(); 20 | } 21 | 22 | 23 | template 24 | VOID D2GIBufferContainer::ReleaseResource() 25 | { 26 | clear(); 27 | } 28 | 29 | 30 | template 31 | VOID D2GIBufferContainer::LoadResource() 32 | { 33 | 34 | } 35 | 36 | 37 | template 38 | VOID D2GIBufferContainer::Clear() 39 | { 40 | for (iterator it = begin(); it < end(); it++) 41 | it->Clear(); 42 | } 43 | 44 | 45 | template 46 | VOID* D2GIBufferContainer::LockStreamingSpace(UINT uSize) 47 | { 48 | UINT i; 49 | StreamingBufferType* pBuffer; 50 | 51 | for (i = 0, pBuffer = NULL; i < size(); i++) 52 | { 53 | StreamingBufferType* pCurrent = data() + i; 54 | 55 | if (pCurrent->uCurrentlyFreeSize >= uSize) 56 | { 57 | pBuffer = pCurrent; 58 | break; 59 | } 60 | } 61 | 62 | if (pBuffer == NULL) 63 | pBuffer = AllocNewBuffer(uSize); 64 | 65 | VOID* pLockData; 66 | 67 | m_pLastLockBuffer = pBuffer; 68 | m_uLastLockSize = uSize; 69 | pLockData = pBuffer->Lock(uSize, &m_uLastLockOffset); 70 | 71 | return pLockData; 72 | } 73 | 74 | 75 | template 76 | VOID D2GIBufferContainer::UnlockStreamingSpace() 77 | { 78 | m_pLastLockBuffer->Unlock(); 79 | } 80 | -------------------------------------------------------------------------------- /D2GI/src/common/utils.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "common.h" 3 | #include "utils.h" 4 | 5 | using namespace D3D7; 6 | 7 | 8 | UINT CalcFVFStride(DWORD dwFVF) 9 | { 10 | UINT uVertexStride = 0; 11 | 12 | if (dwFVF & ~(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 | 13 | D3DFVF_DIFFUSE | D3DFVF_TEX2 | D3DFVF_SPECULAR | D3DFVF_RESERVED1 | D3DFVF_XYZRHW)) 14 | return 0; 15 | 16 | if (dwFVF & D3DFVF_XYZ) 17 | uVertexStride += sizeof(FLOAT) * 3; 18 | 19 | if (dwFVF & D3DFVF_XYZRHW) 20 | uVertexStride += sizeof(FLOAT) * 4; 21 | 22 | if (dwFVF & D3DFVF_NORMAL) 23 | uVertexStride += sizeof(FLOAT) * 3; 24 | 25 | if (dwFVF & D3DFVF_RESERVED1) 26 | uVertexStride += sizeof(DWORD); 27 | 28 | if (dwFVF & D3DFVF_DIFFUSE) 29 | uVertexStride += sizeof(DWORD); 30 | 31 | if (dwFVF & D3DFVF_SPECULAR) 32 | uVertexStride += sizeof(DWORD); 33 | 34 | uVertexStride += CalcFVFTextureCount(dwFVF) * sizeof(FLOAT) * 2; 35 | 36 | return uVertexStride; 37 | } 38 | 39 | 40 | UINT CalcPrimitiveCount(D3D7::D3DPRIMITIVETYPE pt, DWORD dwVertexOrIndexCount) 41 | { 42 | switch (pt) 43 | { 44 | case D3D7::D3DPT_TRIANGLELIST: 45 | return dwVertexOrIndexCount / 3; 46 | case D3D7::D3DPT_TRIANGLEFAN: 47 | case D3D7::D3DPT_TRIANGLESTRIP: 48 | return dwVertexOrIndexCount - 2; 49 | case D3D7::D3DPT_POINTLIST: 50 | return dwVertexOrIndexCount; 51 | case D3D7::D3DPT_LINELIST: 52 | return dwVertexOrIndexCount / 2; 53 | case D3D7::D3DPT_LINESTRIP: 54 | return dwVertexOrIndexCount - 1; 55 | } 56 | 57 | return 0; 58 | } 59 | 60 | 61 | UINT CalcFVFTextureCount(DWORD dwFVF) 62 | { 63 | return (dwFVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; 64 | } 65 | 66 | 67 | VOID CalcMipMapLevelSize(DWORD dwTextureW, DWORD dwTextureH, UINT uLevel, DWORD* pMipMapW, DWORD* pMipMapH) 68 | { 69 | UINT uPow = 1 << uLevel; 70 | 71 | *pMipMapW = max(dwTextureW / uPow, 1); 72 | *pMipMapH = max(dwTextureH / uPow, 1); 73 | } 74 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_config.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/dir.h" 3 | #include "../common/logger.h" 4 | 5 | #include "d2gi_config.h" 6 | 7 | 8 | WINDOWMODE D2GIConfig::s_eWindowMode = WMODE_BORDERLESS; 9 | DWORD D2GIConfig::s_dwVideoWidth = 0, D2GIConfig::s_dwVideoHeight = 0; 10 | BOOL D2GIConfig::s_bEnableHooks = TRUE; 11 | BOOL D2GIConfig::s_bEnableVSync = FALSE; 12 | 13 | DWORD D2GIConfig::GetVideoWidth() 14 | { 15 | if (s_dwVideoWidth == 0) 16 | return GetSystemMetrics(SM_CXSCREEN); 17 | 18 | return s_dwVideoWidth; 19 | } 20 | 21 | 22 | DWORD D2GIConfig::GetVideoHeight() 23 | { 24 | if (s_dwVideoHeight == 0) 25 | return GetSystemMetrics(SM_CYSCREEN); 26 | 27 | return s_dwVideoHeight; 28 | } 29 | 30 | 31 | VOID D2GIConfig::ReadFromFile() 32 | { 33 | TCHAR szWinMode[256]; 34 | TCHAR szConfigFile[MAX_PATH]; 35 | 36 | _tcscpy(szConfigFile, Directory::GetEXEDirectory()); 37 | _tcscat(szConfigFile, TEXT("d2gi.ini")); 38 | 39 | GetPrivateProfileString(TEXT("VIDEO"), TEXT("WindowMode"), 40 | TEXT("borderless"), szWinMode, ARRAYSIZE(szWinMode), szConfigFile); 41 | 42 | if (_tcsicmp(szWinMode, TEXT("fullscreen")) == 0) 43 | s_eWindowMode = WMODE_FULLSCREEN; 44 | else if (_tcsicmp(szWinMode, TEXT("windowed")) == 0) 45 | s_eWindowMode = WMODE_WINDOWED; 46 | else if (_tcsicmp(szWinMode, TEXT("borderless")) == 0) 47 | s_eWindowMode = WMODE_BORDERLESS; 48 | else 49 | { 50 | Logger::Warning(TEXT("Unknown window mode \"%s\", setting it to borderless"), szWinMode); 51 | s_eWindowMode = WMODE_BORDERLESS; 52 | } 53 | 54 | s_dwVideoWidth = GetPrivateProfileInt(TEXT("VIDEO"), TEXT("Width"), 0, szConfigFile); 55 | s_dwVideoHeight = GetPrivateProfileInt(TEXT("VIDEO"), TEXT("Height"), 0, szConfigFile); 56 | s_bEnableVSync = !!GetPrivateProfileInt(TEXT("VIDEO"), TEXT("EnableVSync"), FALSE, szConfigFile); 57 | s_bEnableHooks = !!GetPrivateProfileInt(TEXT("HOOKS"), TEXT("EnableHooks"), TRUE, szConfigFile); 58 | } 59 | -------------------------------------------------------------------------------- /D2GI/src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "common/logger.h" 3 | 4 | #include "d2gi/d2gi.h" 5 | #include "d2gi/d2gi_config.h" 6 | #include "d2gi/d2gi_hooks.h" 7 | 8 | 9 | #define EXPORT extern "C" 10 | 11 | 12 | EXPORT HRESULT WINAPI D3D7::DirectDrawCreateEx(GUID* pGUID, LPVOID* lpDD, REFIID iid, IUnknown* pUnknown) 13 | { 14 | D2GI* pD2GI = new D2GI(); 15 | 16 | *lpDD = (D3D7::IDirectDraw7*)pD2GI->GetDirectDrawProxy(); 17 | 18 | return DD_OK; 19 | } 20 | 21 | 22 | EXPORT HRESULT WINAPI D3D7::DirectDrawEnumerateA(D3D7::LPDDENUMCALLBACKA pCallback, LPVOID pContext) 23 | { 24 | pCallback(NULL, "Primary Video Driver", "display", pContext); 25 | 26 | return DD_OK; 27 | } 28 | 29 | 30 | EXPORT HRESULT WINAPI D3D7::DirectDrawCreate(GUID FAR* lpGUID, D3D7::LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter) 31 | { 32 | return DDERR_GENERIC; 33 | } 34 | 35 | 36 | EXPORT HRESULT WINAPI D3D7::DirectDrawCreateClipper(DWORD dwFlags, D3D7::LPDIRECTDRAWCLIPPER FAR* lplpDDClipper, IUnknown FAR* pUnkOuter) 37 | { 38 | return DDERR_GENERIC; 39 | } 40 | 41 | 42 | EXPORT HRESULT WINAPI D3D7::DirectDrawEnumerateExA(D3D7::LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags) 43 | { 44 | return DDERR_GENERIC; 45 | } 46 | 47 | 48 | EXPORT HRESULT WINAPI D3D7::DirectDrawEnumerateExW(D3D7::LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags) 49 | { 50 | return DDERR_GENERIC; 51 | } 52 | 53 | 54 | EXPORT HRESULT WINAPI D3D7::DirectDrawEnumerateW(D3D7::LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) 55 | { 56 | return DDERR_GENERIC; 57 | } 58 | 59 | 60 | BOOL WINAPI DllMain(HINSTANCE, DWORD dwReason, LPVOID) 61 | { 62 | if (dwReason == DLL_PROCESS_ATTACH) 63 | { 64 | Logger::Log(TEXT("D2GI %s module loaded"), D2GI_VERSION); 65 | D2GIConfig::ReadFromFile(); 66 | D2GIHookInjector::InjectHooks(); 67 | } 68 | else if (dwReason == DLL_PROCESS_DETACH) 69 | Logger::Log(TEXT("D2GI module unloaded\n")); 70 | 71 | return TRUE; 72 | } 73 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_prim_single_surf.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "d2gi.h" 3 | #include "d2gi_prim_single_surf.h" 4 | #include "d2gi_enums.h" 5 | 6 | 7 | D2GIPrimarySingleSurface::D2GIPrimarySingleSurface(D2GI* pD2GI, 8 | DWORD dwWidth, DWORD dwHeight, D2GIPIXELFORMAT eFormat) 9 | : D2GISurface(pD2GI, dwWidth, dwHeight, eFormat) 10 | { 11 | m_pPalette = NULL; 12 | } 13 | 14 | 15 | D2GIPrimarySingleSurface::~D2GIPrimarySingleSurface() 16 | { 17 | RELEASE(m_pPalette); 18 | } 19 | 20 | 21 | HRESULT D2GIPrimarySingleSurface::GetSurfaceDesc(D3D7::LPDDSURFACEDESC2 pDesc) 22 | { 23 | 24 | ZeroMemory(pDesc, sizeof(D3D7::DDSURFACEDESC2)); 25 | pDesc->dwSize = sizeof(D3D7::DDSURFACEDESC2); 26 | pDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PITCH | DDSD_PIXELFORMAT; 27 | pDesc->dwWidth = m_dwWidth; 28 | pDesc->dwHeight = m_dwHeight; 29 | pDesc->lPitch = pDesc->dwWidth * m_dwBPP / 8; 30 | pDesc->ddsCaps.dwCaps = DDSCAPS_FRONTBUFFER | DDSCAPS_PRIMARYSURFACE | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE | DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE; 31 | pDesc->ddpfPixelFormat = m_sDD7PixelFormat; 32 | 33 | return DD_OK; 34 | } 35 | 36 | 37 | HRESULT D2GIPrimarySingleSurface::SetPalette(D3D7::LPDIRECTDRAWPALETTE pPal) 38 | { 39 | D2GIPalette* pD2GIPalette = (D2GIPalette*)pPal; 40 | 41 | if (m_pPalette == pPal) 42 | return DD_OK; 43 | 44 | RELEASE(m_pPalette); 45 | m_pPalette = pD2GIPalette; 46 | m_pPalette->AddRef(); 47 | 48 | return DD_OK; 49 | } 50 | 51 | 52 | 53 | HRESULT D2GIPrimarySingleSurface::IsLost() 54 | { 55 | return DD_OK; 56 | } 57 | 58 | 59 | HRESULT D2GIPrimarySingleSurface::Blt(LPRECT pDestRT, D3D7::LPDIRECTDRAWSURFACE7 pSrc, LPRECT pSrcRT, DWORD dwFlags, D3D7::LPDDBLTFX lpFX) 60 | { 61 | D2GISurface* pSurf = (D2GISurface*)pSrc; 62 | 63 | if (pSrc == NULL || pSurf->GetType() != ST_SYSMEM) 64 | return DDERR_GENERIC; 65 | 66 | m_pD2GI->OnSysMemSurfaceBltOnPrimarySingle((D2GISystemMemorySurface*)pSurf, pSrcRT, this, pDestRT); 67 | 68 | return DD_OK; 69 | } 70 | -------------------------------------------------------------------------------- /D2GI/src/common/logger.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "logger.h" 3 | #include "dir.h" 4 | 5 | 6 | TCHAR Logger::s_szLogPath[MAX_PATH] = {'\0'}; 7 | HWND Logger::s_hWnd = NULL; 8 | 9 | 10 | VOID Logger::WriteLog(TCHAR* pszMessage) 11 | { 12 | TCHAR szFormattedMessage[1024]; 13 | SYSTEMTIME stTime; 14 | DWORD dwPID, dwTID; 15 | FILE* pFile; 16 | 17 | if (*s_szLogPath == '\0') 18 | { 19 | _tcscpy(s_szLogPath, Directory::GetEXEDirectory()); 20 | _tcscat(s_szLogPath, TEXT("d2gi.log")); 21 | } 22 | 23 | GetSystemTime(&stTime); 24 | dwPID = GetCurrentProcessId(); 25 | dwTID = GetCurrentThreadId(); 26 | 27 | _stprintf(szFormattedMessage, TEXT("[%i-%02i-%02i %02i:%02i:%02i:%03i %i:%i] %s\n"), 28 | stTime.wYear, stTime.wMonth, stTime.wDay, stTime.wHour, 29 | stTime.wMinute, stTime.wSecond, stTime.wMilliseconds, dwPID, dwTID, pszMessage); 30 | 31 | #ifdef _DEBUG 32 | OutputDebugString(szFormattedMessage); 33 | #endif 34 | 35 | pFile = _tfopen(s_szLogPath, TEXT("a")); 36 | _ftprintf(pFile, TEXT("%s"), szFormattedMessage); 37 | fclose(pFile); 38 | } 39 | 40 | 41 | VOID Logger::Error(TCHAR* pszFmt, ...) 42 | { 43 | TCHAR szMessage[1024]; 44 | TCHAR* pszMsgWithoutPrefix; 45 | va_list args; 46 | 47 | va_start(args, pszFmt); 48 | _tcscpy(szMessage, TEXT("***FATAL ERROR***\n")); 49 | pszMsgWithoutPrefix = szMessage + _tcslen(szMessage); 50 | _vstprintf(pszMsgWithoutPrefix, pszFmt, args); 51 | va_end(args); 52 | 53 | WriteLog(szMessage); 54 | MessageBox(s_hWnd, pszMsgWithoutPrefix, TEXT("D2GI Fatal Error"), MB_OK | MB_ICONERROR); 55 | ExitProcess(-1); 56 | } 57 | 58 | 59 | VOID Logger::Warning(TCHAR* pszFmt, ...) 60 | { 61 | TCHAR szMessage[1024]; 62 | va_list args; 63 | 64 | va_start(args, pszFmt); 65 | _tcscpy(szMessage, TEXT("!!!WARNING!!! ")); 66 | _vstprintf(szMessage + _tcslen(szMessage), pszFmt, args); 67 | va_end(args); 68 | 69 | WriteLog(szMessage); 70 | } 71 | 72 | 73 | VOID Logger::Log(TCHAR* pszFmt, ...) 74 | { 75 | 76 | TCHAR szMessage[1024]; 77 | va_list args; 78 | 79 | va_start(args, pszFmt); 80 | _vstprintf(szMessage, pszFmt, args); 81 | va_end(args); 82 | 83 | WriteLog(szMessage); 84 | } 85 | -------------------------------------------------------------------------------- /D2GI/src/ddraw/dd_ddraw.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/common.h" 4 | #include "../common/d3d7.h" 5 | 6 | 7 | class DDrawProxy : public D3D7::IDirectDraw7, public Unknown 8 | { 9 | public: 10 | DDrawProxy(); 11 | virtual ~DDrawProxy(); 12 | 13 | STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj) { return Unknown::QueryInterface(riid, ppvObj); }; 14 | STDMETHOD_(ULONG, AddRef) () { return Unknown::AddRef(); }; 15 | STDMETHOD_(ULONG, Release) () { return Unknown::Release(); }; 16 | 17 | STDMETHOD(Compact)(); 18 | STDMETHOD(CreateClipper)(DWORD, D3D7::LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR*) ; 19 | STDMETHOD(CreatePalette)( DWORD, LPPALETTEENTRY, D3D7::LPDIRECTDRAWPALETTE FAR*, IUnknown FAR*) ; 20 | STDMETHOD(CreateSurface)(D3D7::LPDDSURFACEDESC2, D3D7::LPDIRECTDRAWSURFACE7 FAR*, IUnknown FAR*) ; 21 | STDMETHOD(DuplicateSurface)(D3D7::LPDIRECTDRAWSURFACE7, D3D7::LPDIRECTDRAWSURFACE7 FAR*) ; 22 | STDMETHOD(EnumDisplayModes)( DWORD, D3D7::LPDDSURFACEDESC2, LPVOID, D3D7::LPDDENUMMODESCALLBACK2) ; 23 | STDMETHOD(EnumSurfaces)( DWORD, D3D7::LPDDSURFACEDESC2, LPVOID, D3D7::LPDDENUMSURFACESCALLBACK7) ; 24 | STDMETHOD(FlipToGDISurface)() ; 25 | STDMETHOD(GetCaps)(D3D7::LPDDCAPS, D3D7::LPDDCAPS) ; 26 | STDMETHOD(GetDisplayMode)(D3D7::LPDDSURFACEDESC2) ; 27 | STDMETHOD(GetFourCCCodes)( LPDWORD, LPDWORD) ; 28 | STDMETHOD(GetGDISurface)(D3D7::LPDIRECTDRAWSURFACE7 FAR*) ; 29 | STDMETHOD(GetMonitorFrequency)( LPDWORD) ; 30 | STDMETHOD(GetScanLine)( LPDWORD) ; 31 | STDMETHOD(GetVerticalBlankStatus)( LPBOOL) ; 32 | STDMETHOD(Initialize)( GUID FAR*) ; 33 | STDMETHOD(RestoreDisplayMode)() ; 34 | STDMETHOD(SetCooperativeLevel)( HWND, DWORD) ; 35 | STDMETHOD(SetDisplayMode)( DWORD, DWORD, DWORD, DWORD, DWORD) ; 36 | STDMETHOD(WaitForVerticalBlank)( DWORD, HANDLE) ; 37 | STDMETHOD(GetAvailableVidMem)(D3D7::LPDDSCAPS2, LPDWORD, LPDWORD) ; 38 | STDMETHOD(GetSurfaceFromDC) ( HDC, D3D7::LPDIRECTDRAWSURFACE7*) ; 39 | STDMETHOD(RestoreAllSurfaces)() ; 40 | STDMETHOD(TestCooperativeLevel)() ; 41 | STDMETHOD(GetDeviceIdentifier)(D3D7::LPDDDEVICEIDENTIFIER2, DWORD) ; 42 | STDMETHOD(StartModeTest)( LPSIZE, DWORD, DWORD) ; 43 | STDMETHOD(EvaluateMode)( DWORD, DWORD*) ; 44 | }; 45 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_buffer_container.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../common/common.h" 6 | 7 | #include "d2gi_common.h" 8 | 9 | 10 | template 11 | struct STREAMING_BUFFER 12 | { 13 | UINT uTotalSize, uCurrentlyFreeSize; 14 | BufferType* pBuffer; 15 | 16 | STREAMING_BUFFER(BufferType* pBuffer, UINT uSize) 17 | { 18 | uTotalSize = uSize; uCurrentlyFreeSize = uSize; this->pBuffer = pBuffer; 19 | pBuffer->AddRef(); 20 | }; 21 | 22 | STREAMING_BUFFER(CONST STREAMING_BUFFER& other) 23 | { 24 | uTotalSize = other.uTotalSize; uCurrentlyFreeSize = other.uCurrentlyFreeSize; pBuffer = other.pBuffer; 25 | pBuffer->AddRef(); 26 | } 27 | 28 | STREAMING_BUFFER& operator = (CONST STREAMING_BUFFER& other) 29 | { 30 | if (&other == this) return; 31 | uTotalSize = other.uTotalSize; uCurrentlyFreeSize = other.uCurrentlyFreeSize; pBuffer = other.pBuffer; 32 | pBuffer->AddRef(); 33 | } 34 | 35 | ~STREAMING_BUFFER() { RELEASE(pBuffer); } 36 | 37 | VOID Clear() { uCurrentlyFreeSize = uTotalSize; } 38 | 39 | VOID* Lock(UINT uSize, UINT* pOffset) 40 | { 41 | if (uSize > uCurrentlyFreeSize) 42 | return NULL; 43 | 44 | VOID* pData; 45 | 46 | *pOffset = uTotalSize - uCurrentlyFreeSize; 47 | pBuffer->Lock(*pOffset, uSize, &pData, 48 | uCurrentlyFreeSize == uTotalSize ? D3DLOCK_DISCARD : D3DLOCK_NOOVERWRITE); 49 | 50 | uCurrentlyFreeSize -= uSize; 51 | 52 | return pData; 53 | } 54 | 55 | VOID Unlock() { pBuffer->Unlock(); } 56 | }; 57 | 58 | 59 | typedef STREAMING_BUFFER VERTEX_STREAMING_BUFFER; 60 | typedef STREAMING_BUFFER INDEX_STREAMING_BUFFER; 61 | 62 | 63 | template 64 | class D2GIBufferContainer : protected std::vector, public D2GIBase 65 | { 66 | protected: 67 | StreamingBufferType* m_pLastLockBuffer; 68 | UINT m_uLastLockOffset, m_uLastLockSize; 69 | 70 | virtual StreamingBufferType* AllocNewBuffer(UINT) = 0; 71 | public: 72 | D2GIBufferContainer(D2GI*); 73 | ~D2GIBufferContainer(); 74 | 75 | VOID ReleaseResource(); 76 | VOID LoadResource(); 77 | VOID Clear(); 78 | 79 | VOID* LockStreamingSpace(UINT); 80 | VOID UnlockStreamingSpace(); 81 | }; 82 | -------------------------------------------------------------------------------- /README-EN.md: -------------------------------------------------------------------------------- 1 | # D2GI - D2 Graphic Improvements 2 | 3 | [Читать на русском](README.md) 4 | 5 | *D2GI* - is a graphical modification which adapts the game "King of the Road" (Hard Truck 2, Rig'n'Roll) for modern PC. This is a *Direct3D*-wrapper, transferring the functionality of the legacy *DirectDraw7* + *Direct3D7* bundle to the *Direct3D9*, which works correctly on all modern Windows versions. Developed to replace existing GOG and dgVoodoo wrappers, since these are not wonderful: GOG wrapper rendered graphics incorrectly, while dgVoodoo wrapper is full of friezes and crashes. 6 | 7 | ### Features 8 | 9 | * Fixes incorrect graphics output (["Rainbow" bug](https://www.pcgamingwiki.com/wiki/Rainbow_color_problems_in_older_games), bug with an object's transparency etc.) 10 | * You can specify any resolution with any aspect ratio (4:3, 16:9 etc.) 11 | * 3 modes: windowed, borderless, fullscreen 12 | * 32-bit color rendering 13 | * Compatibility with vanilla 8.1 game version 14 | * Compatibility with [SEMod 1.2](https://vk.com/rnr_mods?w=page-157113673_53889819) 15 | * Works stable, without freezes or crashes (~~as for me~~) 16 | * High FPS on low-end hardware 17 | 18 | ### Requirements 19 | 20 | * Game version 8.1 or higher 21 | * Windows XP or higher 22 | 23 | ### Download 24 | 25 | [Download](https://github.com/REDPOWAR/D2GI/releases) 26 | 27 | ### Installation 28 | 29 | You need to unzip the files into a folder with the game. 30 | 31 | ### Settings 32 | 33 | The `d2gi.ini` file has the following settings. 34 | `VIDEO` section: 35 | * `Width` - Screen width like `1920` (`0` - auto) 36 | * `Height` - Screen height like `1080` (`0` - auto) 37 | * `WindowMode` - Window mode. Possible values: `windowed`, `borderless`, `fullscreen`. 38 | * `EnableVSync` - Turn vertical sync on or off (`1` and `0` accordingly) 39 | 40 | `HOOKS` section: 41 | * `EnableHooks` - enable game functions hooking (matrix projection correction with any aspect ratio) 42 | 43 | ### Demo 44 | 45 | Vanilla 8.1 version benchmark on Intel HD Graphics 4000: 46 | [![video](http://img.youtube.com/vi/cP87WtU5F9I/0.jpg)](https://www.youtube.com/watch?v=cP87WtU5F9I) 47 | 48 | SEMod 1.2 benchmark on Intel HD Graphics 4000: 49 | [![video](http://img.youtube.com/vi/IbHq2INIn5c/0.jpg)](https://www.youtube.com/watch?v=IbHq2INIn5c) 50 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_prim_flip_surf.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/logger.h" 3 | 4 | #include "d2gi.h" 5 | #include "d2gi_prim_flip_surf.h" 6 | #include "d2gi_backbuf_surf.h" 7 | 8 | 9 | D2GIPrimaryFlippableSurface::D2GIPrimaryFlippableSurface(D2GI* pD2GI, 10 | DWORD dwWidth, DWORD dwHeight, D2GIPIXELFORMAT eFormat) 11 | : D2GISurface(pD2GI, dwWidth, dwHeight, eFormat) 12 | { 13 | m_pBackBuffer = new D2GIBackBufferSurface(m_pD2GI, dwWidth, dwHeight, eFormat); 14 | } 15 | 16 | 17 | D2GIPrimaryFlippableSurface::~D2GIPrimaryFlippableSurface() 18 | { 19 | DEL(m_pBackBuffer); 20 | } 21 | 22 | 23 | VOID D2GIPrimaryFlippableSurface::ReleaseResource() 24 | { 25 | m_pBackBuffer->ReleaseResource(); 26 | } 27 | 28 | 29 | VOID D2GIPrimaryFlippableSurface::LoadResource() 30 | { 31 | m_pBackBuffer->LoadResource(); 32 | } 33 | 34 | 35 | HRESULT D2GIPrimaryFlippableSurface::GetAttachedSurface(D3D7::LPDDSCAPS2 pCaps, D3D7::LPDIRECTDRAWSURFACE7 FAR* lpSurf) 36 | { 37 | if (pCaps->dwCaps & DDSCAPS_BACKBUFFER) 38 | { 39 | m_pBackBuffer->AddRef(); 40 | *lpSurf = (D3D7::IDirectDrawSurface7*)m_pBackBuffer; 41 | return DD_OK; 42 | } 43 | 44 | Logger::Warning(TEXT("Requested unknown attached surface to primary flippable surface")); 45 | return DDERR_GENERIC; 46 | } 47 | 48 | 49 | HRESULT D2GIPrimaryFlippableSurface::GetSurfaceDesc(D3D7::LPDDSURFACEDESC2 pDesc) 50 | { 51 | ZeroMemory(pDesc, sizeof(D3D7::DDSURFACEDESC2)); 52 | pDesc->dwSize = sizeof(D3D7::DDSURFACEDESC2); 53 | pDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_BACKBUFFERCOUNT; 54 | pDesc->dwBackBufferCount = 1; 55 | pDesc->dwWidth = m_dwWidth; 56 | pDesc->dwHeight = m_dwHeight; 57 | pDesc->lPitch = pDesc->dwWidth * m_dwBPP / 8; 58 | pDesc->ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER | DDSCAPS_PRIMARYSURFACE | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE | DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE; 59 | pDesc->ddpfPixelFormat = m_sDD7PixelFormat; 60 | 61 | return DD_OK; 62 | } 63 | 64 | 65 | HRESULT D2GIPrimaryFlippableSurface::IsLost() 66 | { 67 | return DD_OK; 68 | } 69 | 70 | 71 | HRESULT D2GIPrimaryFlippableSurface::Flip(D3D7::LPDIRECTDRAWSURFACE7 pSurf, DWORD dwFlags) 72 | { 73 | m_pD2GI->OnFlip(); 74 | return DD_OK; 75 | } 76 | 77 | 78 | HRESULT D2GIPrimaryFlippableSurface::GetFlipStatus(DWORD) 79 | { 80 | return DD_OK; 81 | } 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # D2GI - D2 Graphic Improvements 2 | 3 | [Read on English](README-EN.md) 4 | 5 | *D2GI* - графическая модификация, которая адаптирует игру "Дальнобойщики 2" для современных ПК. Это *Direct3D*-враппер, переносящий функциональность связки древних *DirectDraw7* + *Direct3D7* на плечи *Direct3D9*, который работает корректно на всех современных Windows. Разработан для замены существующих враппера от GOG и враппера dgVoodoo, поскольку их работа оставляла желать лучшего: враппер от GOG некорректно отрисовывает графику, а враппер dgVoodoo отличился фризами и вылетами. 6 | 7 | ### Возможности 8 | 9 | * Исправляет некорректный вывод графики (["Радужный" баг](https://www.pcgamingwiki.com/wiki/Rainbow_color_problems_in_older_games), баг с прозрачностями объектов и т.п.) 10 | * Можно задавать произвольное разрешение с произвольным соотношением сторон (4:3, 16:9 и т.п.) 11 | * Три режима: оконный, окно без рамки, полноэкранный 12 | * Рендеринг в 32-битном цветовом режиме 13 | * Совместимость с чистой игрой версии 8.1 14 | * Совместимость с модом [SEMod 1.2](https://vk.com/rnr_mods?w=page-157113673_53889819) 15 | * Работает стабильно, без фризов и вылетов ~~(у меня)~~ 16 | * Высокий показатель FPS на слабом железе 17 | 18 | ### Требования 19 | 20 | * Версия игры 8.1 21 | * Windows XP и выше 22 | 23 | ### Скачать 24 | 25 | [Скачать](https://github.com/REDPOWAR/D2GI/releases) 26 | 27 | ### Установка 28 | 29 | Нужно распаковать файлы в папку с игрой. 30 | 31 | ### Настройка 32 | 33 | В файле `d2gi.ini` есть следующие настройки. 34 | Секция `VIDEO`: 35 | * `Width` - ширина изображения (`0` - автоматически) 36 | * `Height` - высота изображения (`0` - автоматически) 37 | * `WindowMode` - режим окна. `windowed` - оконный, `borderless` - окно без рамки, `fullscreen` - полноэкранный 38 | * `EnableVSync` - включить или выключить вертикальную синхронизацию 39 | 40 | Секция `HOOKS`: 41 | * `EnableHooks` - включить перехват функций игры (нужно для коррекции матрицы проекции при произвольном соотношении сторон) 42 | 43 | ### Демо 44 | 45 | Бенчмарк чистой версии 8.1 на Intel HD Graphics 4000: 46 | [![video](http://img.youtube.com/vi/cP87WtU5F9I/0.jpg)](https://www.youtube.com/watch?v=cP87WtU5F9I) 47 | 48 | Бенчмарк SEMod 1.2 на Intel HD Graphics 4000: 49 | [![video](http://img.youtube.com/vi/IbHq2INIn5c/0.jpg)](https://www.youtube.com/watch?v=IbHq2INIn5c) 50 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_blitter_ps.h: -------------------------------------------------------------------------------- 1 | #if 0 2 | // 3 | // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 4 | // 5 | // fxc /T ps_3_0 /Vn g_pBlitterPS /Fh 6 | // E:\Users\Admin\Documents\Visual_Studio_2008\Projects\D2GI\D2GI\src\d2gi\d2gi_blitter_ps.h 7 | // E:\Users\Admin\Documents\Visual_Studio_2008\Projects\D2GI\D2GI\src\d2gi\d2gi_blitter_ps.hlsl 8 | // 9 | // 10 | // Parameters: 11 | // 12 | // sampler2D g_txSourceTexture; 13 | // float4 g_vBorder; 14 | // 15 | // 16 | // Registers: 17 | // 18 | // Name Reg Size 19 | // ----------------- ----- ---- 20 | // g_vBorder c0 1 21 | // g_txSourceTexture s0 1 22 | // 23 | 24 | ps_3_0 25 | dcl_texcoord v0.xy 26 | dcl_2d s0 27 | max r0.xy, v0, c0 28 | min r1.xy, c0.zwzw, r0 29 | texld oC0, r1, s0 30 | 31 | // approximately 3 instruction slots used (1 texture, 2 arithmetic) 32 | #endif 33 | 34 | const BYTE g_pBlitterPS[] = 35 | { 36 | 0, 3, 255, 255, 254, 255, 37 | 48, 0, 67, 84, 65, 66, 38 | 28, 0, 0, 0, 139, 0, 39 | 0, 0, 0, 3, 255, 255, 40 | 2, 0, 0, 0, 28, 0, 41 | 0, 0, 0, 1, 0, 0, 42 | 132, 0, 0, 0, 68, 0, 43 | 0, 0, 3, 0, 0, 0, 44 | 1, 0, 2, 0, 88, 0, 45 | 0, 0, 0, 0, 0, 0, 46 | 104, 0, 0, 0, 2, 0, 47 | 0, 0, 1, 0, 2, 0, 48 | 116, 0, 0, 0, 0, 0, 49 | 0, 0, 103, 95, 116, 120, 50 | 83, 111, 117, 114, 99, 101, 51 | 84, 101, 120, 116, 117, 114, 52 | 101, 0, 171, 171, 4, 0, 53 | 12, 0, 1, 0, 1, 0, 54 | 1, 0, 0, 0, 0, 0, 55 | 0, 0, 103, 95, 118, 66, 56 | 111, 114, 100, 101, 114, 0, 57 | 171, 171, 1, 0, 3, 0, 58 | 1, 0, 4, 0, 1, 0, 59 | 0, 0, 0, 0, 0, 0, 60 | 112, 115, 95, 51, 95, 48, 61 | 0, 77, 105, 99, 114, 111, 62 | 115, 111, 102, 116, 32, 40, 63 | 82, 41, 32, 72, 76, 83, 64 | 76, 32, 83, 104, 97, 100, 65 | 101, 114, 32, 67, 111, 109, 66 | 112, 105, 108, 101, 114, 32, 67 | 57, 46, 50, 57, 46, 57, 68 | 53, 50, 46, 51, 49, 49, 69 | 49, 0, 31, 0, 0, 2, 70 | 5, 0, 0, 128, 0, 0, 71 | 3, 144, 31, 0, 0, 2, 72 | 0, 0, 0, 144, 0, 8, 73 | 15, 160, 11, 0, 0, 3, 74 | 0, 0, 3, 128, 0, 0, 75 | 228, 144, 0, 0, 228, 160, 76 | 10, 0, 0, 3, 1, 0, 77 | 3, 128, 0, 0, 238, 160, 78 | 0, 0, 228, 128, 66, 0, 79 | 0, 3, 0, 8, 15, 128, 80 | 1, 0, 228, 128, 0, 8, 81 | 228, 160, 255, 255, 0, 0 82 | }; 83 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_blitter_vs.h: -------------------------------------------------------------------------------- 1 | #if 0 2 | // 3 | // Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111 4 | // 5 | // fxc /T vs_3_0 /Vn g_pBlitterVS /Fh 6 | // E:\Users\Admin\Documents\Visual_Studio_2008\Projects\D2GI\D2GI\src\d2gi\d2gi_blitter_vs.h 7 | // E:\Users\Admin\Documents\Visual_Studio_2008\Projects\D2GI\D2GI\src\d2gi\d2gi_blitter_vs.hlsl 8 | // 9 | // 10 | // Parameters: 11 | // 12 | // float4 g_vRect; 13 | // float4 g_vTexRect; 14 | // 15 | // 16 | // Registers: 17 | // 18 | // Name Reg Size 19 | // ------------ ----- ---- 20 | // g_vRect c0 1 21 | // g_vTexRect c1 1 22 | // 23 | 24 | vs_3_0 25 | def c2, 0, 1, 0, 0 26 | dcl_position v0 27 | dcl_texcoord v1 28 | dcl_position o0 29 | dcl_texcoord o1.xy 30 | mad o0.xy, v0, c0, c0.zwzw 31 | mad o1.xy, v1, c1, c1.zwzw 32 | mov o0.zw, c2.xyxy 33 | 34 | // approximately 3 instruction slots used 35 | #endif 36 | 37 | const BYTE g_pBlitterVS[] = 38 | { 39 | 0, 3, 254, 255, 254, 255, 40 | 41, 0, 67, 84, 65, 66, 41 | 28, 0, 0, 0, 110, 0, 42 | 0, 0, 0, 3, 254, 255, 43 | 2, 0, 0, 0, 28, 0, 44 | 0, 0, 0, 1, 0, 0, 45 | 103, 0, 0, 0, 68, 0, 46 | 0, 0, 2, 0, 0, 0, 47 | 1, 0, 2, 0, 76, 0, 48 | 0, 0, 0, 0, 0, 0, 49 | 92, 0, 0, 0, 2, 0, 50 | 1, 0, 1, 0, 6, 0, 51 | 76, 0, 0, 0, 0, 0, 52 | 0, 0, 103, 95, 118, 82, 53 | 101, 99, 116, 0, 1, 0, 54 | 3, 0, 1, 0, 4, 0, 55 | 1, 0, 0, 0, 0, 0, 56 | 0, 0, 103, 95, 118, 84, 57 | 101, 120, 82, 101, 99, 116, 58 | 0, 118, 115, 95, 51, 95, 59 | 48, 0, 77, 105, 99, 114, 60 | 111, 115, 111, 102, 116, 32, 61 | 40, 82, 41, 32, 72, 76, 62 | 83, 76, 32, 83, 104, 97, 63 | 100, 101, 114, 32, 67, 111, 64 | 109, 112, 105, 108, 101, 114, 65 | 32, 57, 46, 50, 57, 46, 66 | 57, 53, 50, 46, 51, 49, 67 | 49, 49, 0, 171, 81, 0, 68 | 0, 5, 2, 0, 15, 160, 69 | 0, 0, 0, 0, 0, 0, 70 | 128, 63, 0, 0, 0, 0, 71 | 0, 0, 0, 0, 31, 0, 72 | 0, 2, 0, 0, 0, 128, 73 | 0, 0, 15, 144, 31, 0, 74 | 0, 2, 5, 0, 0, 128, 75 | 1, 0, 15, 144, 31, 0, 76 | 0, 2, 0, 0, 0, 128, 77 | 0, 0, 15, 224, 31, 0, 78 | 0, 2, 5, 0, 0, 128, 79 | 1, 0, 3, 224, 4, 0, 80 | 0, 4, 0, 0, 3, 224, 81 | 0, 0, 228, 144, 0, 0, 82 | 228, 160, 0, 0, 238, 160, 83 | 4, 0, 0, 4, 1, 0, 84 | 3, 224, 1, 0, 228, 144, 85 | 1, 0, 228, 160, 1, 0, 86 | 238, 160, 1, 0, 0, 2, 87 | 0, 0, 12, 224, 2, 0, 88 | 68, 160, 255, 255, 0, 0 89 | }; 90 | -------------------------------------------------------------------------------- /D2GI/src/common/d3d9.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace D3D9 7 | { 8 | #undef DIRECT3D_VERSION 9 | #define DIRECT3D_VERSION 0x0900 10 | #undef D3DCOLOR_DEFINED 11 | #undef D3DCOLORVALUE_DEFINED 12 | #undef D3DVECTOR_DEFINED 13 | #undef D3DRECT_DEFINED 14 | #undef D3DMATRIX_DEFINED 15 | 16 | #undef D3DFVF_POSITION_MASK 17 | #undef D3DFVF_RESERVED2 18 | #undef D3DERR_WRONGTEXTUREFORMAT 19 | #undef D3DERR_UNSUPPORTEDCOLOROPERATION 20 | #undef D3DERR_UNSUPPORTEDCOLORARG 21 | #undef D3DERR_UNSUPPORTEDALPHAOPERATION 22 | #undef D3DERR_UNSUPPORTEDALPHAARG 23 | #undef D3DERR_TOOMANYOPERATIONS 24 | #undef D3DERR_CONFLICTINGTEXTUREFILTER 25 | #undef D3DERR_UNSUPPORTEDFACTORVALUE 26 | #undef D3DERR_CONFLICTINGRENDERSTATE 27 | #undef D3DERR_UNSUPPORTEDTEXTUREFILTER 28 | #undef D3DERR_CONFLICTINGTEXTUREPALETTE 29 | #undef D3D_OK 30 | 31 | #include 32 | #include 33 | 34 | #undef D3DFVF_POSITION_MASK 35 | #undef D3DFVF_RESERVED2 36 | #undef D3DERR_WRONGTEXTUREFORMAT 37 | #undef D3DERR_UNSUPPORTEDCOLOROPERATION 38 | #undef D3DERR_UNSUPPORTEDCOLORARG 39 | #undef D3DERR_UNSUPPORTEDALPHAOPERATION 40 | #undef D3DERR_UNSUPPORTEDALPHAARG 41 | #undef D3DERR_TOOMANYOPERATIONS 42 | #undef D3DERR_CONFLICTINGTEXTUREFILTER 43 | #undef D3DERR_UNSUPPORTEDFACTORVALUE 44 | #undef D3DERR_CONFLICTINGRENDERSTATE 45 | #undef D3DERR_UNSUPPORTEDTEXTUREFILTER 46 | #undef D3DERR_CONFLICTINGTEXTUREPALETTE 47 | #undef D3D_OK 48 | 49 | 50 | CONST DWORD D3DFVF_POSITION_MASK = 0x400E; 51 | CONST DWORD D3DFVF_RESERVED2 = 0x6000; 52 | 53 | CONST HRESULT D3DERR_WRONGTEXTUREFORMAT = MAKE_D3DHRESULT(2072); 54 | CONST HRESULT D3DERR_UNSUPPORTEDCOLOROPERATION = MAKE_D3DHRESULT(2073); 55 | CONST HRESULT D3DERR_UNSUPPORTEDCOLORARG = MAKE_D3DHRESULT(2074); 56 | CONST HRESULT D3DERR_UNSUPPORTEDALPHAOPERATION = MAKE_D3DHRESULT(2075); 57 | CONST HRESULT D3DERR_UNSUPPORTEDALPHAARG = MAKE_D3DHRESULT(2076); 58 | CONST HRESULT D3DERR_TOOMANYOPERATIONS = MAKE_D3DHRESULT(2077); 59 | CONST HRESULT D3DERR_CONFLICTINGTEXTUREFILTER = MAKE_D3DHRESULT(2078); 60 | CONST HRESULT D3DERR_UNSUPPORTEDFACTORVALUE = MAKE_D3DHRESULT(2079); 61 | CONST HRESULT D3DERR_CONFLICTINGRENDERSTATE = MAKE_D3DHRESULT(2081); 62 | CONST HRESULT D3DERR_UNSUPPORTEDTEXTUREFILTER = MAKE_D3DHRESULT(2082); 63 | CONST HRESULT D3DERR_CONFLICTINGTEXTUREPALETTE = MAKE_D3DHRESULT(2086); 64 | 65 | CONST HRESULT D3D_OK = S_OK; 66 | 67 | #undef D3DTS_WORLDMATRIX 68 | #undef D3DTS_WORLD 69 | #undef D3DTS_WORLD1 70 | #undef D3DTS_WORLD2 71 | #undef D3DTS_WORLD3 72 | __forceinline D3DTRANSFORMSTATETYPE D3DTS_WORLDMATRIX(DWORD index) { return (D3DTRANSFORMSTATETYPE)(index + 256); } 73 | CONST D3DTRANSFORMSTATETYPE D3DTS_WORLD = D3DTS_WORLDMATRIX(0); 74 | CONST D3DTRANSFORMSTATETYPE D3DTS_WORLD1 = D3DTS_WORLDMATRIX(1); 75 | CONST D3DTRANSFORMSTATETYPE D3DTS_WORLD2 = D3DTS_WORLDMATRIX(2); 76 | CONST D3DTRANSFORMSTATETYPE D3DTS_WORLD3 = D3DTS_WORLDMATRIX(3); 77 | 78 | 79 | #undef DIRECT3D_VERSION 80 | }; 81 | -------------------------------------------------------------------------------- /D2GI/src/ddraw/dd_surface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/common.h" 4 | #include "../common/d3d7.h" 5 | 6 | 7 | class SurfaceProxy : public D3D7::IDirectDrawSurface7, public Unknown 8 | { 9 | public: 10 | SurfaceProxy(); 11 | virtual ~SurfaceProxy(); 12 | 13 | STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj) { return Unknown::QueryInterface(riid, ppvObj); }; 14 | STDMETHOD_(ULONG, AddRef) () { return Unknown::AddRef(); }; 15 | STDMETHOD_(ULONG, Release) () { return Unknown::Release(); }; 16 | 17 | STDMETHOD(AddAttachedSurface)(D3D7::LPDIRECTDRAWSURFACE7) ; 18 | STDMETHOD(AddOverlayDirtyRect)( LPRECT) ; 19 | STDMETHOD(Blt)( LPRECT, D3D7::LPDIRECTDRAWSURFACE7, LPRECT, DWORD, D3D7::LPDDBLTFX) ; 20 | STDMETHOD(BltBatch)(D3D7::LPDDBLTBATCH, DWORD, DWORD) ; 21 | STDMETHOD(BltFast)( DWORD, DWORD, D3D7::LPDIRECTDRAWSURFACE7, LPRECT, DWORD) ; 22 | STDMETHOD(DeleteAttachedSurface)( DWORD, D3D7::LPDIRECTDRAWSURFACE7) ; 23 | STDMETHOD(EnumAttachedSurfaces)( LPVOID, D3D7::LPDDENUMSURFACESCALLBACK7) ; 24 | STDMETHOD(EnumOverlayZOrders)( DWORD, LPVOID, D3D7::LPDDENUMSURFACESCALLBACK7) ; 25 | STDMETHOD(Flip)(D3D7::LPDIRECTDRAWSURFACE7, DWORD) ; 26 | STDMETHOD(GetAttachedSurface)(D3D7::LPDDSCAPS2, D3D7::LPDIRECTDRAWSURFACE7 FAR*) ; 27 | STDMETHOD(GetBltStatus)( DWORD) ; 28 | STDMETHOD(GetCaps)(D3D7::LPDDSCAPS2) ; 29 | STDMETHOD(GetClipper)(D3D7::LPDIRECTDRAWCLIPPER FAR*) ; 30 | STDMETHOD(GetColorKey)( DWORD, D3D7::LPDDCOLORKEY) ; 31 | STDMETHOD(GetDC)( HDC FAR*) ; 32 | STDMETHOD(GetFlipStatus)( DWORD) ; 33 | STDMETHOD(GetOverlayPosition)( LPLONG, LPLONG) ; 34 | STDMETHOD(GetPalette)(D3D7::LPDIRECTDRAWPALETTE FAR*) ; 35 | STDMETHOD(GetPixelFormat)(D3D7::LPDDPIXELFORMAT) ; 36 | STDMETHOD(GetSurfaceDesc)(D3D7::LPDDSURFACEDESC2) ; 37 | STDMETHOD(Initialize)(D3D7::LPDIRECTDRAW, D3D7::LPDDSURFACEDESC2) ; 38 | STDMETHOD(IsLost)() ; 39 | STDMETHOD(Lock)( LPRECT, D3D7::LPDDSURFACEDESC2, DWORD, HANDLE) ; 40 | STDMETHOD(ReleaseDC)( HDC) ; 41 | STDMETHOD(Restore)() ; 42 | STDMETHOD(SetClipper)(D3D7::LPDIRECTDRAWCLIPPER) ; 43 | STDMETHOD(SetColorKey)( DWORD, D3D7::LPDDCOLORKEY) ; 44 | STDMETHOD(SetOverlayPosition)( LONG, LONG) ; 45 | STDMETHOD(SetPalette)(D3D7::LPDIRECTDRAWPALETTE) ; 46 | STDMETHOD(Unlock)( LPRECT) ; 47 | STDMETHOD(UpdateOverlay)( LPRECT, D3D7::LPDIRECTDRAWSURFACE7, LPRECT, DWORD, D3D7::LPDDOVERLAYFX) ; 48 | STDMETHOD(UpdateOverlayDisplay)( DWORD) ; 49 | STDMETHOD(UpdateOverlayZOrder)( DWORD, D3D7::LPDIRECTDRAWSURFACE7) ; 50 | STDMETHOD(GetDDInterface)( LPVOID FAR*) ; 51 | STDMETHOD(PageLock)( DWORD) ; 52 | STDMETHOD(PageUnlock)( DWORD) ; 53 | STDMETHOD(SetSurfaceDesc)(D3D7::LPDDSURFACEDESC2, DWORD) ; 54 | STDMETHOD(SetPrivateData)( REFGUID, LPVOID, DWORD, DWORD) ; 55 | STDMETHOD(GetPrivateData)( REFGUID, LPVOID, LPDWORD) ; 56 | STDMETHOD(FreePrivateData)( REFGUID) ; 57 | STDMETHOD(GetUniquenessValue)( LPDWORD) ; 58 | STDMETHOD(ChangeUniquenessValue)() ; 59 | STDMETHOD(SetPriority)( DWORD) ; 60 | STDMETHOD(GetPriority)( LPDWORD) ; 61 | STDMETHOD(SetLOD)( DWORD) ; 62 | STDMETHOD(GetLOD)( LPDWORD) ; 63 | }; 64 | -------------------------------------------------------------------------------- /D2GI/src/common/d3d7.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include 5 | 6 | 7 | namespace D3D7 8 | { 9 | #undef DIRECT3D_VERSION 10 | #define DIRECT3D_VERSION 0x0700 11 | #undef D3DCOLOR_DEFINED 12 | #undef D3DCOLORVALUE_DEFINED 13 | #undef D3DVECTOR_DEFINED 14 | #undef D3DRECT_DEFINED 15 | #undef D3DMATRIX_DEFINED 16 | 17 | #undef D3DFVF_POSITION_MASK 18 | #undef D3DFVF_RESERVED2 19 | #undef D3DERR_WRONGTEXTUREFORMAT 20 | #undef D3DERR_UNSUPPORTEDCOLOROPERATION 21 | #undef D3DERR_UNSUPPORTEDCOLORARG 22 | #undef D3DERR_UNSUPPORTEDALPHAOPERATION 23 | #undef D3DERR_UNSUPPORTEDALPHAARG 24 | #undef D3DERR_TOOMANYOPERATIONS 25 | #undef D3DERR_CONFLICTINGTEXTUREFILTER 26 | #undef D3DERR_UNSUPPORTEDFACTORVALUE 27 | #undef D3DERR_CONFLICTINGRENDERSTATE 28 | #undef D3DERR_UNSUPPORTEDTEXTUREFILTER 29 | #undef D3DERR_CONFLICTINGTEXTUREPALETTE 30 | #undef D3D_OK 31 | 32 | #include 33 | 34 | #undef D3DFVF_POSITION_MASK 35 | #undef D3DFVF_RESERVED2 36 | #undef D3DERR_WRONGTEXTUREFORMAT 37 | #undef D3DERR_UNSUPPORTEDCOLOROPERATION 38 | #undef D3DERR_UNSUPPORTEDCOLORARG 39 | #undef D3DERR_UNSUPPORTEDALPHAOPERATION 40 | #undef D3DERR_UNSUPPORTEDALPHAARG 41 | #undef D3DERR_TOOMANYOPERATIONS 42 | #undef D3DERR_CONFLICTINGTEXTUREFILTER 43 | #undef D3DERR_UNSUPPORTEDFACTORVALUE 44 | #undef D3DERR_CONFLICTINGRENDERSTATE 45 | #undef D3DERR_UNSUPPORTEDTEXTUREFILTER 46 | #undef D3DERR_CONFLICTINGTEXTUREPALETTE 47 | #undef D3D_OK 48 | CONST DWORD D3DFVF_POSITION_MASK = 0x00E; 49 | CONST DWORD D3DFVF_RESERVED2 = 0xf000; 50 | 51 | CONST HRESULT D3DERR_WRONGTEXTUREFORMAT = MAKE_DDHRESULT(2072); 52 | CONST HRESULT D3DERR_UNSUPPORTEDCOLOROPERATION = MAKE_DDHRESULT(2073); 53 | CONST HRESULT D3DERR_UNSUPPORTEDCOLORARG = MAKE_DDHRESULT(2074); 54 | CONST HRESULT D3DERR_UNSUPPORTEDALPHAOPERATION = MAKE_DDHRESULT(2075); 55 | CONST HRESULT D3DERR_UNSUPPORTEDALPHAARG = MAKE_DDHRESULT(2076); 56 | CONST HRESULT D3DERR_TOOMANYOPERATIONS = MAKE_DDHRESULT(2077); 57 | CONST HRESULT D3DERR_CONFLICTINGTEXTUREFILTER = MAKE_DDHRESULT(2078); 58 | CONST HRESULT D3DERR_UNSUPPORTEDFACTORVALUE = MAKE_DDHRESULT(2079); 59 | CONST HRESULT D3DERR_CONFLICTINGRENDERSTATE = MAKE_DDHRESULT(2081); 60 | CONST HRESULT D3DERR_UNSUPPORTEDTEXTUREFILTER = MAKE_DDHRESULT(2082); 61 | CONST HRESULT D3DERR_CONFLICTINGTEXTUREPALETTE = MAKE_DDHRESULT(2086); 62 | CONST HRESULT D3D_OK = DD_OK; 63 | 64 | 65 | __forceinline BOOL operator == (CONST DDPIXELFORMAT& v1, CONST DDPIXELFORMAT& v2) 66 | { 67 | if (v1.dwSize != v2.dwSize) 68 | return FALSE; 69 | 70 | if (v1.dwFlags != v2.dwFlags) 71 | return FALSE; 72 | 73 | if ((v1.dwFlags & DDPF_FOURCC) && v1.dwFourCC != v2.dwFourCC) 74 | return FALSE; 75 | 76 | if ((v1.dwFlags & DDPF_RGB) 77 | && (v1.dwRGBBitCount != v2.dwRGBBitCount || v1.dwRBitMask != v2.dwRBitMask 78 | || v1.dwBBitMask != v2.dwBBitMask || v1.dwGBitMask != v2.dwGBitMask)) 79 | return FALSE; 80 | 81 | if ((v1.dwFlags & DDPF_BUMPDUDV) 82 | && (v1.dwBumpBitCount != v2.dwBumpBitCount || v1.dwBumpDuBitMask != v2.dwBumpDuBitMask 83 | || v1.dwBumpDvBitMask != v2.dwBumpDvBitMask)) 84 | return FALSE; 85 | 86 | if ((v1.dwFlags & DDPF_ALPHAPIXELS) && v1.dwRGBAlphaBitMask != v2.dwRGBAlphaBitMask) 87 | return FALSE; 88 | 89 | return TRUE; 90 | } 91 | 92 | 93 | #undef DIRECT3D_VERSION 94 | }; 95 | -------------------------------------------------------------------------------- /D2GI/src/d3d/d3d_device.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/common.h" 4 | #include "../common/d3d7.h" 5 | 6 | 7 | class DeviceProxy : public D3D7::IDirect3DDevice7, public Unknown 8 | { 9 | public: 10 | DeviceProxy(); 11 | virtual ~DeviceProxy(); 12 | 13 | STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppvObj) { return Unknown::QueryInterface(riid, ppvObj); }; 14 | STDMETHOD_(ULONG, AddRef)() { return Unknown::AddRef(); }; 15 | STDMETHOD_(ULONG, Release)() { return Unknown::Release(); }; 16 | 17 | STDMETHOD(GetCaps)(D3D7::LPD3DDEVICEDESC7); 18 | STDMETHOD(EnumTextureFormats)(D3D7::LPD3DENUMPIXELFORMATSCALLBACK, LPVOID); 19 | STDMETHOD(BeginScene)(); 20 | STDMETHOD(EndScene)(); 21 | STDMETHOD(GetDirect3D)(D3D7::LPDIRECT3D7*); 22 | STDMETHOD(SetRenderTarget)(D3D7::LPDIRECTDRAWSURFACE7, DWORD); 23 | STDMETHOD(GetRenderTarget)(D3D7::LPDIRECTDRAWSURFACE7*); 24 | STDMETHOD(Clear)( DWORD, D3D7::LPD3DRECT, DWORD, D3D7::D3DCOLOR, D3D7::D3DVALUE, DWORD); 25 | STDMETHOD(SetTransform)(D3D7::D3DTRANSFORMSTATETYPE, D3D7::LPD3DMATRIX); 26 | STDMETHOD(GetTransform)(D3D7::D3DTRANSFORMSTATETYPE, D3D7::LPD3DMATRIX); 27 | STDMETHOD(SetViewport)(D3D7::LPD3DVIEWPORT7); 28 | STDMETHOD(MultiplyTransform)(D3D7::D3DTRANSFORMSTATETYPE, D3D7::LPD3DMATRIX); 29 | STDMETHOD(GetViewport)(D3D7::LPD3DVIEWPORT7); 30 | STDMETHOD(SetMaterial)(D3D7::LPD3DMATERIAL7); 31 | STDMETHOD(GetMaterial)(D3D7::LPD3DMATERIAL7); 32 | STDMETHOD(SetLight)( DWORD, D3D7::LPD3DLIGHT7); 33 | STDMETHOD(GetLight)( DWORD, D3D7::LPD3DLIGHT7); 34 | STDMETHOD(SetRenderState)(D3D7::D3DRENDERSTATETYPE, DWORD); 35 | STDMETHOD(GetRenderState)(D3D7::D3DRENDERSTATETYPE, LPDWORD); 36 | STDMETHOD(BeginStateBlock)(); 37 | STDMETHOD(EndStateBlock)( LPDWORD); 38 | STDMETHOD(PreLoad)(D3D7::LPDIRECTDRAWSURFACE7); 39 | STDMETHOD(DrawPrimitive)(D3D7::D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, DWORD); 40 | STDMETHOD(DrawIndexedPrimitive)(D3D7::D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, LPWORD, DWORD, DWORD); 41 | STDMETHOD(SetClipStatus)(D3D7::LPD3DCLIPSTATUS); 42 | STDMETHOD(GetClipStatus)(D3D7::LPD3DCLIPSTATUS); 43 | STDMETHOD(DrawPrimitiveStrided)(D3D7::D3DPRIMITIVETYPE, DWORD, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, DWORD); 44 | STDMETHOD(DrawIndexedPrimitiveStrided)(D3D7::D3DPRIMITIVETYPE, DWORD, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, LPWORD, DWORD, DWORD); 45 | STDMETHOD(DrawPrimitiveVB)(D3D7::D3DPRIMITIVETYPE, D3D7::LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, DWORD); 46 | STDMETHOD(DrawIndexedPrimitiveVB)(D3D7::D3DPRIMITIVETYPE, D3D7::LPDIRECT3DVERTEXBUFFER7, DWORD, DWORD, LPWORD, DWORD, DWORD); 47 | STDMETHOD(ComputeSphereVisibility)(D3D7::LPD3DVECTOR, D3D7::LPD3DVALUE, DWORD, DWORD, LPDWORD); 48 | STDMETHOD(GetTexture)( DWORD, D3D7::LPDIRECTDRAWSURFACE7*); 49 | STDMETHOD(SetTexture)( DWORD, D3D7::LPDIRECTDRAWSURFACE7); 50 | STDMETHOD(GetTextureStageState)( DWORD, D3D7::D3DTEXTURESTAGESTATETYPE, LPDWORD); 51 | STDMETHOD(SetTextureStageState)( DWORD, D3D7::D3DTEXTURESTAGESTATETYPE, DWORD); 52 | STDMETHOD(ValidateDevice)( LPDWORD); 53 | STDMETHOD(ApplyStateBlock)( DWORD); 54 | STDMETHOD(CaptureStateBlock)( DWORD); 55 | STDMETHOD(DeleteStateBlock)( DWORD); 56 | STDMETHOD(CreateStateBlock)(D3D7::D3DSTATEBLOCKTYPE, LPDWORD); 57 | STDMETHOD(Load)(D3D7::LPDIRECTDRAWSURFACE7, LPPOINT, D3D7::LPDIRECTDRAWSURFACE7, LPRECT, DWORD); 58 | STDMETHOD(LightEnable)( DWORD, BOOL); 59 | STDMETHOD(GetLightEnable)( DWORD, BOOL*); 60 | STDMETHOD(SetClipPlane)( DWORD, D3D7::D3DVALUE*); 61 | STDMETHOD(GetClipPlane)( DWORD, D3D7::D3DVALUE*); 62 | STDMETHOD(GetInfo)( DWORD, LPVOID, DWORD); 63 | }; -------------------------------------------------------------------------------- /D2GI/src/ddraw/dd_ddraw.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/common.h" 3 | 4 | #include "dd_ddraw.h" 5 | 6 | 7 | using namespace D3D7; 8 | 9 | 10 | DDrawProxy::DDrawProxy() 11 | { 12 | } 13 | 14 | 15 | DDrawProxy::~DDrawProxy() 16 | { 17 | } 18 | 19 | 20 | HRESULT DDrawProxy::Compact() 21 | { 22 | return DDERR_GENERIC; 23 | } 24 | 25 | 26 | HRESULT DDrawProxy::CreateClipper(DWORD arg1, LPDIRECTDRAWCLIPPER FAR* lpClipper, IUnknown FAR* pUnknown) 27 | { 28 | return DDERR_GENERIC; 29 | } 30 | 31 | 32 | HRESULT DDrawProxy::CreatePalette(DWORD dwFlags, LPPALETTEENTRY lpPalEntry, LPDIRECTDRAWPALETTE FAR* lpPal, IUnknown FAR* pUnknown) 33 | { 34 | return DDERR_GENERIC; 35 | } 36 | 37 | 38 | HRESULT DDrawProxy::CreateSurface(LPDDSURFACEDESC2 lpSurfDesc, LPDIRECTDRAWSURFACE7 FAR* lpDDS, IUnknown FAR* pUnknown) 39 | { 40 | return DDERR_GENERIC; 41 | } 42 | 43 | 44 | HRESULT DDrawProxy::DuplicateSurface(LPDIRECTDRAWSURFACE7 pSurf, LPDIRECTDRAWSURFACE7 FAR* lpSurf) 45 | { 46 | return DDERR_GENERIC; 47 | } 48 | 49 | 50 | HRESULT DDrawProxy::EnumDisplayModes(DWORD dwFlags, LPDDSURFACEDESC2 lpSurfDesc, LPVOID lpArg, LPDDENUMMODESCALLBACK2 lpCallback) 51 | { 52 | return DDERR_GENERIC; 53 | } 54 | 55 | 56 | HRESULT DDrawProxy::EnumSurfaces(DWORD dwFlags, LPDDSURFACEDESC2 lpSurfDesc, LPVOID lpArg, LPDDENUMSURFACESCALLBACK7 lpCallback) 57 | { 58 | return DDERR_GENERIC; 59 | } 60 | 61 | 62 | HRESULT DDrawProxy::FlipToGDISurface() 63 | { 64 | return DDERR_GENERIC; 65 | } 66 | 67 | 68 | HRESULT DDrawProxy::GetCaps(LPDDCAPS lpCaps1, LPDDCAPS lpCaps2) 69 | { 70 | return DDERR_GENERIC; 71 | } 72 | 73 | 74 | HRESULT DDrawProxy::GetDisplayMode(LPDDSURFACEDESC2 lpSurfDesc) 75 | { 76 | return DDERR_GENERIC; 77 | } 78 | 79 | 80 | HRESULT DDrawProxy::GetFourCCCodes(LPDWORD lpNums, LPDWORD lpVars) 81 | { 82 | return DDERR_GENERIC; 83 | } 84 | 85 | 86 | HRESULT DDrawProxy::GetGDISurface(LPDIRECTDRAWSURFACE7 FAR* lpSurf) 87 | { 88 | return DDERR_GENERIC; 89 | } 90 | 91 | 92 | HRESULT DDrawProxy::GetMonitorFrequency(LPDWORD lpFreq) 93 | { 94 | return DDERR_GENERIC; 95 | } 96 | 97 | 98 | HRESULT DDrawProxy::GetScanLine(LPDWORD lpOut) 99 | { 100 | return DDERR_GENERIC; 101 | } 102 | 103 | 104 | HRESULT DDrawProxy::GetVerticalBlankStatus(LPBOOL lpOut) 105 | { 106 | return DDERR_GENERIC; 107 | } 108 | 109 | 110 | HRESULT DDrawProxy::Initialize(GUID FAR* pGUID) 111 | { 112 | return DDERR_GENERIC; 113 | } 114 | 115 | 116 | HRESULT DDrawProxy::RestoreDisplayMode() 117 | { 118 | return DDERR_GENERIC; 119 | } 120 | 121 | 122 | HRESULT DDrawProxy::SetCooperativeLevel(HWND hWnd, DWORD dwFlags) 123 | { 124 | return DDERR_GENERIC; 125 | } 126 | 127 | 128 | HRESULT DDrawProxy::SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) 129 | { 130 | return DDERR_GENERIC; 131 | } 132 | 133 | 134 | HRESULT DDrawProxy::WaitForVerticalBlank(DWORD dwFlags, HANDLE handle) 135 | { 136 | return DDERR_GENERIC; 137 | } 138 | 139 | 140 | HRESULT DDrawProxy::GetAvailableVidMem(LPDDSCAPS2 lpCaps, LPDWORD lpTotal, LPDWORD lpFree) 141 | { 142 | return DDERR_GENERIC; 143 | } 144 | 145 | 146 | HRESULT DDrawProxy::GetSurfaceFromDC(HDC hDC, LPDIRECTDRAWSURFACE7* lpSurf) 147 | { 148 | return DDERR_GENERIC; 149 | } 150 | 151 | 152 | HRESULT DDrawProxy::RestoreAllSurfaces() 153 | { 154 | return DDERR_GENERIC; 155 | } 156 | 157 | 158 | HRESULT DDrawProxy::TestCooperativeLevel() 159 | { 160 | return DDERR_GENERIC; 161 | } 162 | 163 | 164 | HRESULT DDrawProxy::GetDeviceIdentifier(LPDDDEVICEIDENTIFIER2 lpDevID, DWORD dwFlags) 165 | { 166 | return DDERR_GENERIC; 167 | } 168 | 169 | 170 | HRESULT DDrawProxy::StartModeTest(LPSIZE lpSizes, DWORD dwCount, DWORD dwFlags) 171 | { 172 | return DDERR_GENERIC; 173 | } 174 | 175 | 176 | HRESULT DDrawProxy::EvaluateMode(DWORD dwFlags, DWORD* lpOut) 177 | { 178 | return DDERR_GENERIC; 179 | } 180 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_hooks.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/common.h" 3 | #include "../common/logger.h" 4 | #include "../common/dir.h" 5 | 6 | #include "d2gi.h" 7 | #include "d2gi_device.h" 8 | #include "d2gi_hooks.h" 9 | #include "d2gi_config.h" 10 | 11 | 12 | #define CALL_INSTRUCTION_SIZE 5 13 | #define OPCODE_SIZE 1 14 | 15 | 16 | D2GIHookInjector::D2VERSION D2GIHookInjector::s_eCurrentD2Version; 17 | 18 | 19 | D2GI* D2GIHookInjector::ObtainD2GI() 20 | { 21 | static DWORD c_adwDeviceAddresses[] = 22 | { 23 | 0x00720908, 0x00720928 24 | }; 25 | 26 | DWORD dwDevAddr = c_adwDeviceAddresses[s_eCurrentD2Version]; 27 | D3D7::IDirect3DDevice7* pDev = *(D3D7::IDirect3DDevice7**)dwDevAddr; 28 | 29 | if (pDev == NULL) 30 | return NULL; 31 | 32 | return ((D2GIDevice*)pDev)->GetD2GI(); 33 | } 34 | 35 | 36 | INT D2GIHookInjector::SetupTransforms(VOID* pThis, MAT3X4* pmView, MAT3X4* pmProj) 37 | { 38 | D2GI* pD2GI = ObtainD2GI(); 39 | MAT3X4 mPatchedView = *pmView, mPatchedProj = *pmProj; 40 | 41 | if(pD2GI != NULL) 42 | pD2GI->OnTransformsSetup(pThis, &mPatchedView, &mPatchedProj); 43 | 44 | return CallOriginalSetupTransforms(pThis, &mPatchedView, &mPatchedProj); 45 | } 46 | 47 | 48 | __declspec(naked) VOID SetupTransformsHook() 49 | { 50 | __asm 51 | { 52 | mov eax, [esp + 8]; 53 | push eax; 54 | mov eax, [esp + 8]; 55 | push eax; 56 | push ecx; 57 | call D2GIHookInjector::SetupTransforms; 58 | ret 8; 59 | }; 60 | } 61 | 62 | 63 | INT D2GIHookInjector::CallOriginalSetupTransforms(VOID* pThis, MAT3X4* pmView, MAT3X4* pmProj) 64 | { 65 | static DWORD c_adwSetupTransformsAddresses[] = 66 | { 67 | 0x005AE0E0, 0x005AE070 68 | }; 69 | 70 | INT nResult, nAddr = c_adwSetupTransformsAddresses[s_eCurrentD2Version]; 71 | 72 | __asm 73 | { 74 | push ecx; 75 | push eax; 76 | 77 | mov ecx, pThis; 78 | push pmProj; 79 | push pmView; 80 | call nAddr; 81 | 82 | mov nResult, eax; 83 | pop eax; 84 | pop ecx; 85 | }; 86 | 87 | return nResult; 88 | } 89 | 90 | 91 | D2GIHookInjector::D2VERSION D2GIHookInjector::DetectD2Version() 92 | { 93 | static DWORD c_adwTimestamps[] = 94 | { 95 | 0x400502EA, 0x4760F7AC 96 | }; 97 | 98 | FILE* pFile; 99 | IMAGE_DOS_HEADER sDOSHeader; 100 | IMAGE_FILE_HEADER sImageHeader; 101 | INT i; 102 | 103 | pFile = _tfopen(Directory::GetEXEPath(), TEXT("rb")); 104 | if (pFile == NULL) 105 | { 106 | Logger::Warning( 107 | TEXT("Failed to open D2 EXE file to detect version (%s)"), Directory::GetEXEPath()); 108 | return D2V_UNKNOWN; 109 | } 110 | 111 | fread(&sDOSHeader, sizeof(sDOSHeader), 1, pFile); 112 | fseek(pFile, sDOSHeader.e_lfanew + 4, SEEK_SET); 113 | fread(&sImageHeader, sizeof(sImageHeader), 1, pFile); 114 | fclose(pFile); 115 | 116 | for (i = 0; i < ARRAYSIZE(c_adwTimestamps); i++) 117 | if (c_adwTimestamps[i] == sImageHeader.TimeDateStamp) 118 | return (D2VERSION)i; 119 | 120 | return D2V_UNKNOWN; 121 | } 122 | 123 | 124 | BOOL D2GIHookInjector::PatchCallOperation(DWORD dwOperationAddress, DWORD dwNewCallAddress) 125 | { 126 | INT nCallOffset; 127 | 128 | nCallOffset = (INT32)dwNewCallAddress; 129 | nCallOffset -= (INT32)dwOperationAddress + CALL_INSTRUCTION_SIZE; 130 | 131 | return WriteProcessMemory(GetCurrentProcess(), 132 | (BYTE*)dwOperationAddress + OPCODE_SIZE, &nCallOffset, sizeof(nCallOffset), NULL); 133 | } 134 | 135 | 136 | VOID D2GIHookInjector::InjectHooks() 137 | { 138 | static DWORD c_adwSetupTransformsCalls[] = 139 | { 140 | 0x005EB682, 0x005EB622 141 | }; 142 | static TCHAR* c_lpszVersionNames[] = 143 | { 144 | TEXT("8.1"), 145 | TEXT("8.1B") 146 | }; 147 | 148 | 149 | if (!D2GIConfig::HooksEnabled()) 150 | { 151 | Logger::Log(TEXT("Hook injection is not enabled.")); 152 | return; 153 | } 154 | 155 | Logger::Log(TEXT("Trying to inject hooks...")); 156 | 157 | s_eCurrentD2Version = DetectD2Version(); 158 | if (s_eCurrentD2Version == D2V_UNKNOWN) 159 | { 160 | Logger::Log(TEXT("Current D2 executable version is unknown, injection aborted")); 161 | return; 162 | } 163 | 164 | Logger::Log(TEXT("Detected D2 version %s"), c_lpszVersionNames[s_eCurrentD2Version]); 165 | if (PatchCallOperation(c_adwSetupTransformsCalls[s_eCurrentD2Version], (DWORD)SetupTransformsHook)) 166 | Logger::Log(TEXT("Successfully injected hooks")); 167 | else 168 | Logger::Log(TEXT("Unable to write process memory to inject hooks")); 169 | } 170 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_mipmap_surf.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/logger.h" 3 | 4 | #include "d2gi_texture.h" 5 | #include "d2gi_mipmap_surf.h" 6 | #include "d2gi_enums.h" 7 | #include "d2gi_palette.h" 8 | 9 | 10 | D2GIMipMapSurface::D2GIMipMapSurface(D2GITexture* pParent, UINT uLevelID, D2GIMipMapSurface* pNextSurf, 11 | DWORD dwWidth, DWORD dwHeight, D2GIPIXELFORMAT eFormat) 12 | : D2GISurface(pParent->GetD2GI(), dwWidth, dwHeight, eFormat) 13 | { 14 | m_pSurface = NULL; 15 | m_pNextLevel = pNextSurf; 16 | 17 | m_pParent = pParent; 18 | m_pNextLevel = pNextSurf; 19 | m_uLevelID = uLevelID; 20 | 21 | m_pSurface = NULL; 22 | m_uDataPitch = (m_dwBPP / 8) * m_dwWidth; 23 | m_uDataSize = m_uDataPitch * m_dwHeight; 24 | m_pData = new BYTE[m_uDataSize]; 25 | } 26 | 27 | 28 | D2GIMipMapSurface::~D2GIMipMapSurface() 29 | { 30 | DEL(m_pData); 31 | RELEASE(m_pSurface); 32 | } 33 | 34 | 35 | VOID D2GIMipMapSurface::SetD3D9Surface(D3D9::IDirect3DSurface9* pSurf) 36 | { 37 | if (pSurf == m_pSurface) 38 | return; 39 | 40 | RELEASE(m_pSurface); 41 | m_pSurface = pSurf; 42 | UpdateSurface(); 43 | } 44 | 45 | 46 | HRESULT D2GIMipMapSurface::Lock(LPRECT pRect, D3D7::LPDDSURFACEDESC2 pDesc, DWORD, HANDLE) 47 | { 48 | if (pRect == NULL) 49 | { 50 | ZeroMemory(pDesc, sizeof(D3D7::DDSURFACEDESC2)); 51 | pDesc->dwSize = sizeof(D3D7::DDSURFACEDESC2); 52 | pDesc->dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; 53 | 54 | pDesc->dwMipMapCount = m_pParent->GetMipMapCount() - m_uLevelID; 55 | 56 | /*if (m_dwCKFlags & DDCKEY_SRCBLT) 57 | { 58 | pDesc->dwFlags |= DDSD_CKSRCBLT; 59 | pDesc->ddckCKSrcBlt = m_sColorKey; 60 | }*/ 61 | 62 | pDesc->ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX; 63 | pDesc->dwWidth = m_dwWidth; 64 | pDesc->dwHeight = m_dwHeight; 65 | pDesc->ddpfPixelFormat = m_sDD7PixelFormat; 66 | pDesc->lpSurface = m_pData; 67 | pDesc->lPitch = m_uDataPitch; 68 | 69 | return DD_OK; 70 | } 71 | 72 | return DDERR_GENERIC; 73 | } 74 | 75 | 76 | HRESULT D2GIMipMapSurface::Unlock(LPRECT) 77 | { 78 | UpdateSurface(); 79 | return DD_OK; 80 | } 81 | 82 | 83 | VOID D2GIMipMapSurface::UpdateSurface() 84 | { 85 | D3D9::D3DLOCKED_RECT sRect; 86 | 87 | if (m_pSurface == NULL) 88 | return; 89 | 90 | if (m_dwBPP != 16) 91 | return; 92 | 93 | if (FAILED(m_pSurface->LockRect(&sRect, NULL, 0))) 94 | Logger::Error(TEXT("Failed to lock mip map surface")); 95 | 96 | if (m_pParent->HasColorKeyConversion()) 97 | { 98 | INT i, j; 99 | 100 | for (i = 0; i < (INT)m_dwHeight; i++) 101 | { 102 | for (j = 0; j < (INT)m_dwWidth; j++) 103 | { 104 | UINT16 uSrcColor = *((UINT16*)m_pData + i * m_dwWidth + j); 105 | UINT32 uDstColor; 106 | BYTE r, g, b, a; 107 | 108 | r = ((uSrcColor >> 11) & 0x1F) * 255 / 31; 109 | g = ((uSrcColor >> 5) & 0x3F) * 255 / 63; 110 | b = (uSrcColor & 0x1F) * 255 / 31; 111 | a = (uSrcColor == (UINT16)m_pParent->GetOriginalColorKeyValue()) ? 0 : 255; 112 | 113 | uDstColor = (a << 24) | (r << 16) | (g << 8) | b; 114 | 115 | ((UINT32*)((BYTE*)sRect.pBits + i * sRect.Pitch))[j] = uDstColor; 116 | } 117 | } 118 | } 119 | else 120 | { 121 | INT i; 122 | 123 | for (i = 0; i < (INT)m_dwHeight; i++) 124 | CopyMemory((BYTE*)sRect.pBits + i * sRect.Pitch, (BYTE*)m_pData + i * m_uDataPitch, m_uDataPitch); 125 | } 126 | 127 | m_pSurface->UnlockRect(); 128 | } 129 | 130 | 131 | HRESULT D2GIMipMapSurface::GetAttachedSurface(D3D7::LPDDSCAPS2 pCaps, D3D7::LPDIRECTDRAWSURFACE7 FAR* lpSurf) 132 | { 133 | if ((pCaps->dwCaps & DDSCAPS_MIPMAP) && m_pNextLevel != NULL) 134 | { 135 | m_pNextLevel->AddRef(); 136 | *lpSurf = (D3D7::IDirectDrawSurface7*)m_pNextLevel; 137 | return DD_OK; 138 | } 139 | 140 | Logger::Warning(TEXT("Requested unknown attached surface to mipmap")); 141 | return DDERR_NOTFOUND; 142 | } 143 | 144 | 145 | VOID D2GIMipMapSurface::UpdateWithPalette(D2GIPalette* pPal) 146 | { 147 | D3D9::D3DLOCKED_RECT sLockedRect; 148 | UINT16* pPalette16 = pPal->GetEntries16(); 149 | INT i, j; 150 | 151 | if (FAILED(m_pSurface->LockRect(&sLockedRect, NULL, D3DLOCK_DISCARD))) 152 | Logger::Error(TEXT("Failed to lock mipmap surface to update with palette")); 153 | 154 | for (i = 0; i < (INT)m_dwHeight; i++) 155 | for (j = 0; j < (INT)m_dwWidth; j++) 156 | ((UINT16*)((BYTE*)sLockedRect.pBits + i * sLockedRect.Pitch))[j] = pPalette16[((BYTE*)m_pData)[i * m_dwWidth + j]]; 157 | 158 | m_pSurface->UnlockRect(); 159 | } 160 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_device.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/common.h" 3 | #include "../common/logger.h" 4 | 5 | #include "d2gi_device.h" 6 | #include "d2gi_surface.h" 7 | #include "d2gi_enums.h" 8 | #include "d2gi.h" 9 | 10 | 11 | using namespace D3D7; 12 | 13 | 14 | D2GIDevice::D2GIDevice(D2GI* pD2GI) : DeviceProxy(), D2GIBase(pD2GI) 15 | { 16 | 17 | } 18 | 19 | 20 | D2GIDevice::~D2GIDevice() 21 | { 22 | 23 | } 24 | 25 | 26 | HRESULT D2GIDevice::SetTexture(DWORD i, LPDIRECTDRAWSURFACE7 pTex) 27 | { 28 | if (pTex != NULL && ((D2GISurface*)pTex)->GetType() != ST_TEXTURE) 29 | { 30 | Logger::Warning(TEXT("Setting invalid surface as texture")); 31 | return DDERR_GENERIC; 32 | } 33 | 34 | m_pD2GI->OnTextureSet(i, (pTex == NULL) ? NULL : (D2GITexture*)pTex); 35 | return DD_OK; 36 | } 37 | 38 | 39 | HRESULT D2GIDevice::EnumTextureFormats(LPD3DENUMPIXELFORMATSCALLBACK pCallback, LPVOID pArg) 40 | { 41 | INT i; 42 | 43 | for (i = 0; i < (INT)g_uTextureFormatsCount; i++) 44 | { 45 | if (!pCallback(g_asTextureFormats + i, pArg)) 46 | break; 47 | } 48 | 49 | return DD_OK; 50 | } 51 | 52 | 53 | HRESULT D2GIDevice::SetViewport(D3D7::LPD3DVIEWPORT7 pVP) 54 | { 55 | m_pD2GI->OnViewportSet(pVP); 56 | return DD_OK; 57 | } 58 | 59 | 60 | HRESULT D2GIDevice::Clear(DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags, D3DCOLOR col, D3DVALUE z, DWORD dwStencil) 61 | { 62 | m_pD2GI->OnClear(dwCount, lpRects, dwFlags, col, z, dwStencil); 63 | return DD_OK; 64 | } 65 | 66 | 67 | HRESULT D2GIDevice::LightEnable(DWORD i, BOOL bEnable) 68 | { 69 | m_pD2GI->OnLightEnable(i, bEnable); 70 | return DD_OK; 71 | } 72 | 73 | 74 | HRESULT D2GIDevice::BeginScene() 75 | { 76 | m_pD2GI->OnSceneBegin(); 77 | return DD_OK; 78 | } 79 | 80 | 81 | HRESULT D2GIDevice::EndScene() 82 | { 83 | m_pD2GI->OnSceneEnd(); 84 | return DD_OK; 85 | } 86 | 87 | 88 | HRESULT D2GIDevice::SetRenderState(D3D7::D3DRENDERSTATETYPE eState, DWORD dwValue) 89 | { 90 | m_pD2GI->OnRenderStateSet(eState, dwValue); 91 | return DD_OK; 92 | } 93 | 94 | 95 | HRESULT D2GIDevice::SetTextureStageState(DWORD i, D3D7::D3DTEXTURESTAGESTATETYPE eState, DWORD dwValue) 96 | { 97 | m_pD2GI->OnTextureStageSet(i, eState, dwValue); 98 | return DD_OK; 99 | } 100 | 101 | 102 | HRESULT D2GIDevice::ValidateDevice(LPDWORD pdw) 103 | { 104 | if (m_pD2GI->OnDeviceValidate(pdw)) 105 | return DD_OK; 106 | 107 | Logger::Log(TEXT("Device validation failed")); 108 | return DDERR_GENERIC; 109 | } 110 | 111 | 112 | HRESULT D2GIDevice::SetTransform(D3D7::D3DTRANSFORMSTATETYPE eType, D3D7::LPD3DMATRIX pMatrix) 113 | { 114 | m_pD2GI->OnTransformSet(eType, pMatrix); 115 | return DD_OK; 116 | } 117 | 118 | 119 | HRESULT D2GIDevice::SetLight(DWORD i, D3D7::LPD3DLIGHT7 pLight) 120 | { 121 | m_pD2GI->OnLightSet(i, pLight); 122 | return DD_OK; 123 | } 124 | 125 | 126 | HRESULT D2GIDevice::SetMaterial(D3D7::LPD3DMATERIAL7 pMaterial) 127 | { 128 | m_pD2GI->OnMaterialSet(pMaterial); 129 | return DD_OK; 130 | } 131 | 132 | 133 | HRESULT D2GIDevice::SetClipStatus(D3D7::D3DCLIPSTATUS* pStatus) 134 | { 135 | m_pD2GI->OnClipStatusSet(pStatus); 136 | return DD_OK; 137 | } 138 | 139 | 140 | HRESULT D2GIDevice::DrawIndexedPrimitiveStrided( 141 | D3D7::D3DPRIMITIVETYPE pt, DWORD dwFVF, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA pData, 142 | DWORD dwCount, LPWORD pIdx, DWORD dwIdxCount, DWORD dwFlags) 143 | { 144 | m_pD2GI->OnIndexedPrimitiveStridedDraw(pt, dwFVF, pData, dwCount, pIdx, dwIdxCount, dwFlags); 145 | return DD_OK; 146 | } 147 | 148 | 149 | HRESULT D2GIDevice::DrawPrimitiveStrided(D3DPRIMITIVETYPE pt, DWORD dwFVF, LPD3DDRAWPRIMITIVESTRIDEDDATA pData, DWORD dwCount, DWORD dwFlags) 150 | { 151 | m_pD2GI->OnPrimitiveStridedDraw(pt, dwFVF, pData, dwCount, dwFlags); 152 | return DD_OK; 153 | } 154 | 155 | 156 | 157 | HRESULT D2GIDevice::DrawPrimitive(D3DPRIMITIVETYPE pt, DWORD dwFVF, LPVOID pVerts, DWORD dwVertCount, DWORD dwFlags) 158 | { 159 | m_pD2GI->OnPrimitiveDraw(pt, dwFVF, pVerts, dwVertCount, dwFlags); 160 | return DD_OK; 161 | } 162 | 163 | 164 | HRESULT D2GIDevice::DrawIndexedPrimitive(D3DPRIMITIVETYPE pt, DWORD dwFVF, LPVOID pVerts, DWORD dwVertCount, LPWORD pIdx, DWORD dwIdxCount, DWORD dwFlags) 165 | { 166 | m_pD2GI->OnIndexedPrimitiveDraw(pt, dwFVF, pVerts, dwVertCount, pIdx, dwIdxCount, dwFlags); 167 | return DD_OK; 168 | } 169 | 170 | 171 | HRESULT D2GIDevice::GetRenderState(D3D7::D3DRENDERSTATETYPE eState, LPDWORD pV) 172 | { 173 | if (m_pD2GI->OnRenderStateGet(eState, pV)) 174 | return DD_OK; 175 | 176 | Logger::Warning(TEXT("Requested render state %i (not implemented)"), eState); 177 | return DDERR_GENERIC; 178 | } 179 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_backbuf_surf.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/logger.h" 3 | 4 | #include "d2gi_backbuf_surf.h" 5 | #include "d2gi.h" 6 | #include "d2gi_enums.h" 7 | 8 | 9 | D2GIBackBufferSurface::D2GIBackBufferSurface(D2GI* pD2GI, DWORD dwWidth, 10 | DWORD dwHeight, D2GIPIXELFORMAT eFormat) 11 | : D2GISurface(pD2GI, dwWidth, dwHeight, eFormat) 12 | { 13 | m_pStreamingTexture = NULL; 14 | m_pStreamingSurface = NULL; 15 | m_pReadingSurface = NULL; 16 | m_pOffSurface = NULL; 17 | 18 | LoadResource(); 19 | } 20 | 21 | 22 | D2GIBackBufferSurface::~D2GIBackBufferSurface() 23 | { 24 | ReleaseResource(); 25 | } 26 | 27 | 28 | VOID D2GIBackBufferSurface::ReleaseResource() 29 | { 30 | RELEASE(m_pStreamingTexture); 31 | RELEASE(m_pStreamingSurface); 32 | RELEASE(m_pReadingSurface); 33 | RELEASE(m_pOffSurface); 34 | } 35 | 36 | 37 | VOID D2GIBackBufferSurface::LoadResource() 38 | { 39 | D3D9::IDirect3DDevice9* pDev = GetD3D9Device(); 40 | 41 | if (FAILED(pDev->CreateTexture(m_dwWidth, m_dwHeight, 1, D3DUSAGE_DYNAMIC, 42 | g_asD2GIPF_To_D3D9PF[m_eD2GIPixelFormat], 43 | D3D9::D3DPOOL_DEFAULT, &m_pStreamingTexture, NULL))) 44 | Logger::Error(TEXT("Failed to create backbuffer streaming texture")); 45 | 46 | if (FAILED(m_pStreamingTexture->GetSurfaceLevel(0, &m_pStreamingSurface))) 47 | Logger::Error(TEXT("Failed to get backbuffer streaming surface")); 48 | 49 | if (FAILED(pDev->CreateRenderTarget(m_dwWidth, m_dwHeight, g_asD2GIPF_To_D3D9PF[m_eD2GIPixelFormat], 50 | D3D9::D3DMULTISAMPLE_NONE, 0, FALSE, &m_pReadingSurface, NULL))) 51 | Logger::Error(TEXT("Failed to create backbuffer reading render target")); 52 | 53 | if (FAILED(pDev->CreateOffscreenPlainSurface(m_dwWidth, m_dwHeight, 54 | g_asD2GIPF_To_D3D9PF[m_eD2GIPixelFormat], D3D9::D3DPOOL_SYSTEMMEM, &m_pOffSurface, NULL))) 55 | Logger::Error(TEXT("Failed to create backbuffer reading offscreen surface")); 56 | } 57 | 58 | 59 | HRESULT D2GIBackBufferSurface::Lock(LPRECT pRect, D3D7::LPDDSURFACEDESC2 pDesc, DWORD dwFlags, HANDLE) 60 | { 61 | if (pRect == NULL) 62 | { 63 | m_bLastLockReadOnly = !(dwFlags & DDLOCK_WRITEONLY); 64 | 65 | m_pD2GI->OnBackBufferLock(m_bLastLockReadOnly); 66 | 67 | D3D9::D3DLOCKED_RECT sLockedRect; 68 | 69 | if (m_bLastLockReadOnly) 70 | { 71 | GetD3D9Device()->GetRenderTargetData(m_pReadingSurface, m_pOffSurface); 72 | if (FAILED(m_pOffSurface->LockRect(&sLockedRect, NULL, D3DLOCK_READONLY))) 73 | Logger::Error(TEXT("Failed to lock backbuffer offscreen surface")); 74 | } 75 | else 76 | { 77 | if (FAILED(m_pStreamingSurface->LockRect(&sLockedRect, NULL, D3DLOCK_DISCARD))) 78 | Logger::Error(TEXT("Failed to lock backbuffer streaming surface")); 79 | } 80 | 81 | ZeroMemory(pDesc, sizeof(D3D7::DDSURFACEDESC2)); 82 | pDesc->dwSize = sizeof(D3D7::DDSURFACEDESC2); 83 | pDesc->dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_LPSURFACE; 84 | pDesc->ddsCaps.dwCaps = DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_3DDEVICE | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY; 85 | pDesc->dwWidth = m_dwWidth; 86 | pDesc->dwHeight = m_dwHeight; 87 | pDesc->ddpfPixelFormat = m_sDD7PixelFormat; 88 | pDesc->lPitch = sLockedRect.Pitch; 89 | pDesc->lpSurface = sLockedRect.pBits; 90 | 91 | return DD_OK; 92 | } 93 | 94 | return DDERR_GENERIC; 95 | } 96 | 97 | 98 | HRESULT D2GIBackBufferSurface::Unlock(LPRECT) 99 | { 100 | if (m_bLastLockReadOnly) 101 | m_pOffSurface->UnlockRect(); 102 | else 103 | m_pStreamingSurface->UnlockRect(); 104 | return DD_OK; 105 | } 106 | 107 | 108 | HRESULT D2GIBackBufferSurface::IsLost() 109 | { 110 | return DD_OK; 111 | } 112 | 113 | 114 | HRESULT D2GIBackBufferSurface::AddAttachedSurface(D3D7::LPDIRECTDRAWSURFACE7 pSurf) 115 | { 116 | if (((D2GISurface*)pSurf)->GetType() == ST_ZBUFFER) 117 | return DD_OK; 118 | 119 | Logger::Warning(TEXT("Attaching unknown surface to backbuffer")); 120 | return DDERR_GENERIC; 121 | } 122 | 123 | 124 | HRESULT D2GIBackBufferSurface::Blt(LPRECT pDestRT, D3D7::LPDIRECTDRAWSURFACE7 pSrc, LPRECT pSrcRT, DWORD dwFlags, D3D7::LPDDBLTFX pFX) 125 | { 126 | if (dwFlags & DDBLT_COLORFILL) 127 | { 128 | // TODO: this color fill must affect backbuffer locked data 129 | // while streaming video playback 130 | 131 | m_pD2GI->OnColorFillOnBackBuffer(pFX->dwFillColor, pDestRT); 132 | return DD_OK; 133 | } 134 | 135 | D2GISurface* pSurf = (D2GISurface*)pSrc; 136 | 137 | if (pSrc == NULL || pSurf->GetType() != ST_SYSMEM) 138 | return DDERR_GENERIC; 139 | 140 | m_pD2GI->OnSysMemSurfaceBltOnBackBuffer((D2GISystemMemorySurface*)pSurf, pSrcRT, this, pDestRT); 141 | 142 | return DD_OK; 143 | } 144 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "d2gi_common.h" 7 | #include "d2gi_ddraw.h" 8 | 9 | 10 | enum RENDERSTATE 11 | { 12 | RS_UNKNOWN, 13 | RS_BACKBUFFER_STREAMING, 14 | RS_PRIMARY_SURFACE_BLITTING, 15 | RS_BACKBUFFER_BLITTING, 16 | RS_3D_RENDERING, 17 | }; 18 | 19 | 20 | class D2GISystemMemorySurface; 21 | class D2GIPrimarySingleSurface; 22 | class D2GIBackBufferSurface; 23 | class D2GIBlitter; 24 | class D2GITexture; 25 | class D2GIStridedPrimitiveRenderer; 26 | 27 | struct MAT3X4; 28 | struct FRECT; 29 | 30 | typedef std::vector D3D9RECTVector; 31 | typedef std::vector ByteBuffer; 32 | 33 | 34 | class D2GI 35 | { 36 | D2GIDirectDraw* m_pDirectDrawProxy; 37 | 38 | HMODULE m_hD3D9Lib; 39 | D3D9::IDirect3D9* m_pD3D9; 40 | D3D9::IDirect3DDevice9* m_pDev; 41 | D3D9::IDirect3DTexture9* m_pBackBufferCopy; 42 | D3D9::IDirect3DSurface9* m_pBackBufferCopySurf; 43 | 44 | HWND m_hWnd; 45 | WNDPROC m_pfnOriginalWndProc; 46 | DWORD m_dwOriginalWidth, m_dwOriginalHeight, m_dwOriginalBPP; 47 | 48 | DWORD m_dwForcedWidth, m_dwForcedHeight; 49 | FLOAT m_fAspectRatioScale, m_fWidthScale, m_fHeightScale; 50 | 51 | RENDERSTATE m_eRenderState; 52 | BOOL m_bSceneBegun; 53 | BOOL m_bColorKeyEnabled; 54 | D2GITexture* m_lpCurrentTextures[8]; 55 | 56 | D3D9RECTVector* m_pClearRects; 57 | ByteBuffer* m_p2DBuffer; 58 | 59 | D2GIBlitter* m_pBlitter; 60 | D2GIStridedPrimitiveRenderer* m_pStridedRenderer; 61 | 62 | VOID LoadD3D9Library(); 63 | VOID ResetD3D9Device(); 64 | VOID ReleaseResources(); 65 | VOID LoadResources(); 66 | VOID BeginScene(); 67 | VOID EndScene(); 68 | VOID Present(); 69 | VOID DrawPrimitive(D3D7::D3DPRIMITIVETYPE, DWORD dwFVF, BOOL bStrided, VOID* pVertexData, 70 | DWORD dwVertexCount, WORD* pIndexData, DWORD dwIndexCount, DWORD dwFlags); 71 | VOID ScaleFRect(FRECT* pSrc, FRECT* pOut); 72 | VOID ScaleRect(RECT* pSrc, RECT* pOut); 73 | static LRESULT CALLBACK WndProc_Static(HWND, UINT, WPARAM, LPARAM); 74 | LRESULT WndProc(HWND, UINT, WPARAM, LPARAM); 75 | VOID AttachWndProc(); 76 | VOID DetachWndProc(); 77 | VOID ScaleD3D9Rect(D3D9::D3DRECT* pSrc, D3D9::D3DRECT* pOut); 78 | VOID SetupWindow(); 79 | public: 80 | D2GI(); 81 | ~D2GI(); 82 | 83 | D2GIDirectDraw* GetDirectDrawProxy() { return m_pDirectDrawProxy; } 84 | D3D9::IDirect3D9* GetD3D9() { return m_pD3D9; } 85 | D3D9::IDirect3DDevice9* GetD3D9Device() { return m_pDev; } 86 | DWORD GetOriginalWidth() { return m_dwOriginalWidth; } 87 | DWORD GetOriginalHeight() { return m_dwOriginalHeight; } 88 | DWORD GetOriginalBPP() { return m_dwOriginalBPP; } 89 | DWORD GetForcedWidth() { return m_dwForcedWidth; } 90 | DWORD GetForcedHeight() { return m_dwForcedHeight; } 91 | 92 | VOID OnDirectDrawReleased(); 93 | VOID OnCooperativeLevelSet(HWND, DWORD); 94 | VOID OnDisplayModeSet(DWORD, DWORD, DWORD, DWORD dwFlags); 95 | VOID OnViewportSet(D3D7::LPD3DVIEWPORT7); 96 | VOID OnFlip(); 97 | VOID OnBackBufferLock(BOOL bRead); 98 | VOID OnSysMemSurfaceBltOnPrimarySingle(D2GISystemMemorySurface*, RECT*, D2GIPrimarySingleSurface*, RECT*); 99 | VOID OnClear(DWORD dwCount, D3D7::LPD3DRECT lpRects, DWORD dwFlags, D3D7::D3DCOLOR col, D3D7::D3DVALUE z, DWORD dwStencil); 100 | VOID OnLightEnable(DWORD, BOOL); 101 | VOID OnSysMemSurfaceBltOnBackBuffer(D2GISystemMemorySurface*, RECT*, D2GIBackBufferSurface*, RECT*); 102 | VOID OnSysMemSurfaceBltOnTexture(D2GISystemMemorySurface*, RECT*, D2GITexture*, RECT*); 103 | VOID OnSceneBegin(); 104 | VOID OnSceneEnd(); 105 | VOID OnRenderStateSet(D3D7::D3DRENDERSTATETYPE, DWORD); 106 | VOID OnTextureStageSet(DWORD, D3D7::D3DTEXTURESTAGESTATETYPE, DWORD); 107 | VOID OnTextureSet(DWORD, D2GITexture*); 108 | BOOL OnDeviceValidate(DWORD*); 109 | VOID OnTransformSet(D3D7::D3DTRANSFORMSTATETYPE, D3D7::LPD3DMATRIX); 110 | VOID OnLightSet(DWORD, D3D7::LPD3DLIGHT7); 111 | VOID OnMaterialSet(D3D7::LPD3DMATERIAL7); 112 | VOID OnClipStatusSet(D3D7::LPD3DCLIPSTATUS); 113 | VOID OnIndexedPrimitiveStridedDraw(D3D7::D3DPRIMITIVETYPE, DWORD, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, LPWORD, DWORD, DWORD); 114 | VOID OnPrimitiveStridedDraw(D3D7::D3DPRIMITIVETYPE, DWORD, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA, DWORD, DWORD); 115 | VOID OnPrimitiveDraw(D3D7::D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, DWORD); 116 | VOID OnIndexedPrimitiveDraw(D3D7::D3DPRIMITIVETYPE, DWORD, LPVOID, DWORD, LPWORD, DWORD, DWORD); 117 | BOOL OnRenderStateGet(D3D7::D3DRENDERSTATETYPE, DWORD*); 118 | VOID OnColorFillOnBackBuffer(DWORD, RECT*); 119 | VOID OnTransformsSetup(VOID* pThis, MAT3X4* pmView, MAT3X4* pmProj); 120 | VOID OnDisplayModeEnum(LPVOID pArg, D3D7::LPDDENUMMODESCALLBACK2 pCallback); 121 | }; 122 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_strided_renderer.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/utils.h" 3 | #include "../common/logger.h" 4 | 5 | #include "d2gi_strided_renderer.h" 6 | #include "d2gi_vb_container.h" 7 | #include "d2gi_ib_container.h" 8 | 9 | 10 | D2GIStridedPrimitiveRenderer::D2GIStridedPrimitiveRenderer(D2GI* pD2GI) : D2GIBase(pD2GI) 11 | { 12 | m_pVBContainer = new D2GIVertexBufferContainer(pD2GI); 13 | m_pIBContainer = new D2GIIndexBufferContainer(pD2GI); 14 | } 15 | 16 | 17 | D2GIStridedPrimitiveRenderer::~D2GIStridedPrimitiveRenderer() 18 | { 19 | DEL(m_pVBContainer); 20 | DEL(m_pIBContainer); 21 | } 22 | 23 | 24 | VOID D2GIStridedPrimitiveRenderer::ReleaseResource() 25 | { 26 | m_pVBContainer->ReleaseResource(); 27 | m_pIBContainer->ReleaseResource(); 28 | } 29 | 30 | 31 | VOID D2GIStridedPrimitiveRenderer::LoadResource() 32 | { 33 | m_pVBContainer->LoadResource(); 34 | m_pIBContainer->LoadResource(); 35 | } 36 | 37 | 38 | VOID D2GIStridedPrimitiveRenderer::OnPresentationFinished() 39 | { 40 | m_pVBContainer->Clear(); 41 | m_pIBContainer->Clear(); 42 | } 43 | 44 | 45 | VOID D2GIStridedPrimitiveRenderer::DrawIndexedPrimitiveStrided( 46 | D3D7::D3DPRIMITIVETYPE pt, DWORD dwFVF, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA pData, 47 | DWORD dwCount, LPWORD pIdx, DWORD dwIdxCount, DWORD dwFlags) 48 | { 49 | D3D9::IDirect3DDevice9* pDev = GetD3D9Device(); 50 | 51 | if (pt != D3D7::D3DPT_TRIANGLELIST) 52 | return; 53 | 54 | SetupVertexStream(dwFVF, pData, dwCount); 55 | 56 | VOID* pIBData; 57 | UINT uIdxOffset; 58 | 59 | if ((pIBData = m_pIBContainer->LockStreamingSpace(sizeof(UINT16) * dwIdxCount)) == NULL) 60 | Logger::Error(TEXT("Failed to continue index streaming")); 61 | 62 | CopyMemory(pIBData, pIdx, sizeof(UINT16) * dwIdxCount); 63 | m_pIBContainer->UnlockStreamingSpace(); 64 | 65 | uIdxOffset = m_pIBContainer->SetAsSource(); 66 | 67 | pDev->DrawIndexedPrimitive((D3D9::D3DPRIMITIVETYPE)pt, 0, 0, dwCount, uIdxOffset, dwIdxCount / 3); 68 | } 69 | 70 | 71 | VOID D2GIStridedPrimitiveRenderer::SetupVertexStream( 72 | DWORD dwFVF, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA pData, 73 | DWORD dwCount) 74 | { 75 | D3D9::IDirect3DDevice9* pDev = GetD3D9Device(); 76 | UINT uVertexStride; 77 | 78 | 79 | uVertexStride = CalcFVFStride(dwFVF); 80 | 81 | if (dwFVF & ~(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 | D3DFVF_TEX2 | D3DFVF_DIFFUSE)) 82 | return; 83 | 84 | VOID* pVBData; 85 | INT i, j; 86 | UINT uCurrentVertexStructOffset = 0; 87 | UINT uTextureCount = CalcFVFTextureCount(dwFVF); 88 | 89 | if((pVBData = m_pVBContainer->LockStreamingSpace(uVertexStride * dwCount)) == NULL) 90 | Logger::Error(TEXT("Failed to continue vertex streaming")); 91 | 92 | if (dwFVF & D3DFVF_XYZ) 93 | { 94 | for (i = 0; i < (INT)dwCount; i++) 95 | { 96 | CopyMemory((BYTE*)pVBData + i * uVertexStride + uCurrentVertexStructOffset, 97 | (BYTE*)pData->position.lpvData + i * pData->position.dwStride, sizeof(FLOAT) * 3); 98 | } 99 | 100 | uCurrentVertexStructOffset += sizeof(FLOAT) * 3; 101 | } 102 | 103 | if (dwFVF & D3DFVF_NORMAL) 104 | { 105 | for (i = 0; i < (INT)dwCount; i++) 106 | { 107 | CopyMemory((BYTE*)pVBData + i * uVertexStride + uCurrentVertexStructOffset, 108 | (BYTE*)pData->normal.lpvData + i * pData->normal.dwStride, sizeof(FLOAT) * 3); 109 | } 110 | 111 | uCurrentVertexStructOffset += sizeof(FLOAT) * 3; 112 | } 113 | 114 | if (dwFVF & D3DFVF_DIFFUSE) 115 | { 116 | for (i = 0; i < (INT)dwCount; i++) 117 | { 118 | CopyMemory((BYTE*)pVBData + i * uVertexStride + uCurrentVertexStructOffset, 119 | (BYTE*)pData->diffuse.lpvData + i * pData->diffuse.dwStride, sizeof(DWORD)); 120 | } 121 | 122 | uCurrentVertexStructOffset += sizeof(DWORD); 123 | } 124 | 125 | for(i = 0; i < (INT)uTextureCount; i++) 126 | { 127 | for (j = 0; j < (INT)dwCount; j++) 128 | { 129 | CopyMemory((BYTE*)pVBData + j * uVertexStride + uCurrentVertexStructOffset, 130 | (BYTE*)pData->textureCoords[i].lpvData + j * pData->textureCoords[i].dwStride, sizeof(FLOAT) * 2); 131 | } 132 | 133 | uCurrentVertexStructOffset += sizeof(FLOAT) * 2; 134 | } 135 | 136 | m_pVBContainer->UnlockStreamingSpace(); 137 | 138 | pDev->SetFVF(dwFVF); 139 | 140 | m_pVBContainer->SetAsSource(uVertexStride); 141 | } 142 | 143 | 144 | VOID D2GIStridedPrimitiveRenderer::DrawPrimitiveStrided( 145 | D3D7::D3DPRIMITIVETYPE pt, DWORD dwFVF, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA pData, 146 | DWORD dwCount, DWORD dwFlags) 147 | { 148 | D3D9::IDirect3DDevice9* pDev = GetD3D9Device(); 149 | UINT uPrimCount; 150 | 151 | SetupVertexStream(dwFVF, pData, dwCount); 152 | 153 | uPrimCount = CalcPrimitiveCount(pt, dwCount); 154 | 155 | pDev->DrawPrimitive((D3D9::D3DPRIMITIVETYPE)pt, 0, uPrimCount); 156 | } 157 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_texture.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/utils.h" 3 | #include "../common/logger.h" 4 | 5 | #include "d2gi_texture.h" 6 | #include "d2gi_enums.h" 7 | #include "d2gi_sysmem_surf.h" 8 | #include "d2gi.h" 9 | 10 | 11 | D2GITexture::D2GITexture(D2GI* pD2GI, DWORD dwWidth, DWORD dwHeight, 12 | D2GIPIXELFORMAT eFormat, DWORD dwMipMapCount) 13 | : D2GISurface(pD2GI, dwWidth, dwHeight, eFormat) 14 | { 15 | m_dwMipMapCount = (dwMipMapCount == 0) ? 1 : dwMipMapCount; 16 | m_lpMipMapLevels = NULL; 17 | m_pTexture = NULL; 18 | m_bColorKeySet = FALSE; 19 | 20 | INT i; 21 | 22 | m_lpMipMapLevels = new D2GIMipMapSurface* [m_dwMipMapCount]; 23 | for (i = (INT)m_dwMipMapCount - 1; i >= 0; i--) 24 | { 25 | DWORD dwMipMapWidth, dwMipMapHeight; 26 | D2GIMipMapSurface* pNextMipMap = (i < (INT)m_dwMipMapCount - 1) ? m_lpMipMapLevels[i + 1] : NULL; 27 | 28 | CalcMipMapLevelSize(m_dwWidth, m_dwHeight, i, &dwMipMapWidth, &dwMipMapHeight); 29 | m_lpMipMapLevels[i] = new D2GIMipMapSurface(this, i, pNextMipMap, 30 | dwMipMapWidth, dwMipMapHeight, m_eD2GIPixelFormat); 31 | } 32 | 33 | LoadResource(); 34 | } 35 | 36 | 37 | D2GITexture::~D2GITexture() 38 | { 39 | INT i; 40 | 41 | ReleaseResource(); 42 | 43 | for (i = 0; i < (INT)m_dwMipMapCount; i++) 44 | RELEASE(m_lpMipMapLevels[i]); 45 | 46 | DEL(m_lpMipMapLevels); 47 | } 48 | 49 | 50 | VOID D2GITexture::LoadResource() 51 | { 52 | D3D9::IDirect3DDevice9* pDev = GetD3D9Device(); 53 | D3D9::D3DFORMAT eFormat; 54 | DWORD i; 55 | 56 | eFormat = g_asD2GIPF_To_D3D9PF[m_eD2GIPixelFormat]; 57 | 58 | if (HasColorKeyConversion()) 59 | eFormat = D3D9::D3DFMT_A8R8G8B8; 60 | if (m_dwBPP == 8) 61 | eFormat = D3D9::D3DFMT_R5G6B5; 62 | 63 | if (FAILED(pDev->CreateTexture(m_dwWidth, m_dwHeight, 64 | m_dwMipMapCount, D3DUSAGE_DYNAMIC, 65 | eFormat, D3D9::D3DPOOL_DEFAULT, &m_pTexture, NULL))) 66 | Logger::Error(TEXT("Failed to create texture")); 67 | 68 | for (i = 0; i < m_dwMipMapCount; i++) 69 | { 70 | D3D9::IDirect3DSurface9* pSurf; 71 | 72 | if (FAILED(m_pTexture->GetSurfaceLevel(i, &pSurf))) 73 | Logger::Error(TEXT("Failed to get surface for texture")); 74 | m_lpMipMapLevels[i]->SetD3D9Surface(pSurf); 75 | } 76 | } 77 | 78 | 79 | VOID D2GITexture::ReleaseResource() 80 | { 81 | INT i; 82 | 83 | for (i = 0; i < (INT)m_dwMipMapCount; i++) 84 | m_lpMipMapLevels[i]->SetD3D9Surface(NULL); 85 | 86 | RELEASE(m_pTexture); 87 | } 88 | 89 | 90 | HRESULT D2GITexture::SetColorKey(DWORD dwFlags, D3D7::LPDDCOLORKEY pCK) 91 | { 92 | INT i; 93 | 94 | if (!(dwFlags & DDCKEY_SRCBLT)) 95 | { 96 | Logger::Warning(TEXT("Setting unknown color key for texture")); 97 | return DDERR_GENERIC; 98 | } 99 | 100 | if (pCK != NULL) 101 | { 102 | m_sColorKey = *pCK; 103 | m_bColorKeySet = TRUE; 104 | } 105 | else 106 | m_bColorKeySet = FALSE; 107 | 108 | ReleaseResource(); 109 | LoadResource(); 110 | for (i = 0; i < (INT)m_dwMipMapCount; i++) 111 | m_lpMipMapLevels[i]->UpdateSurface(); 112 | 113 | return DD_OK; 114 | } 115 | 116 | 117 | HRESULT D2GITexture::IsLost() 118 | { 119 | return DD_OK; 120 | } 121 | 122 | 123 | HRESULT D2GITexture::Lock(LPRECT pRect, D3D7::LPDDSURFACEDESC2 pDesc, DWORD dwFlags, HANDLE h) 124 | { 125 | return m_lpMipMapLevels[0]->Lock(pRect, pDesc, dwFlags, h); 126 | } 127 | 128 | 129 | HRESULT D2GITexture::Unlock(LPRECT pRect) 130 | { 131 | return m_lpMipMapLevels[0]->Unlock(pRect); 132 | } 133 | 134 | 135 | HRESULT D2GITexture::Blt(LPRECT pDestRT, D3D7::LPDIRECTDRAWSURFACE7 pSrc, LPRECT pSrcRT, DWORD dwFlags, D3D7::LPDDBLTFX lpFX) 136 | { 137 | D2GISurface* pSurf = (D2GISurface*)pSrc; 138 | 139 | if (pSrc == NULL || pSurf->GetType() != ST_SYSMEM) 140 | return DDERR_GENERIC; 141 | 142 | m_pD2GI->OnSysMemSurfaceBltOnTexture((D2GISystemMemorySurface*)pSurf, pSrcRT, this, pDestRT); 143 | 144 | return DD_OK; 145 | } 146 | 147 | 148 | D3D9::IDirect3DSurface9* D2GITexture::GetD3D9Surface() 149 | { 150 | return m_lpMipMapLevels[0]->GetD3D9Surface(); 151 | } 152 | 153 | 154 | HRESULT D2GITexture::GetAttachedSurface(D3D7::LPDDSCAPS2 pCaps, D3D7::LPDIRECTDRAWSURFACE7 FAR* lpSurf) 155 | { 156 | return m_lpMipMapLevels[0]->GetAttachedSurface(pCaps, lpSurf); 157 | } 158 | 159 | 160 | HRESULT D2GITexture::GetSurfaceDesc(D3D7::LPDDSURFACEDESC2 pDesc) 161 | { 162 | ZeroMemory(pDesc, sizeof(D3D7::DDSURFACEDESC2)); 163 | pDesc->dwSize = sizeof(D3D7::DDSURFACEDESC2); 164 | pDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT; 165 | pDesc->dwMipMapCount = m_dwMipMapCount; 166 | pDesc->dwWidth = m_dwWidth; 167 | pDesc->dwHeight = m_dwHeight; 168 | pDesc->ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_TEXTURE | DDSCAPS_MIPMAP; 169 | pDesc->ddpfPixelFormat = m_sDD7PixelFormat; 170 | 171 | return DD_OK; 172 | } 173 | 174 | 175 | BOOL D2GITexture::HasColorKeyConversion() 176 | { 177 | return m_bColorKeySet && m_eD2GIPixelFormat == D2GIPF_16_565; 178 | } 179 | 180 | 181 | DWORD D2GITexture::GetOriginalColorKeyValue() 182 | { 183 | return m_sColorKey.dwColorSpaceLowValue; 184 | } 185 | 186 | 187 | VOID D2GITexture::UpdateWithPalette(D2GIPalette* pPal) 188 | { 189 | INT i; 190 | 191 | for (i = 0; i < (INT)m_dwMipMapCount; i++) 192 | m_lpMipMapLevels[i]->UpdateWithPalette(pPal); 193 | } 194 | 195 | 196 | BOOL D2GITexture::CopyFrom(D2GITexture* pSrc) 197 | { 198 | if (m_dwWidth != pSrc->GetWidth() || m_dwHeight != pSrc->GetHeight()) 199 | return FALSE; 200 | 201 | D3D9::D3DLOCKED_RECT rt; 202 | INT i; 203 | 204 | m_lpMipMapLevels[0]->GetD3D9Surface()->LockRect(&rt, NULL, D3DLOCK_DISCARD); 205 | 206 | for (i = 0; i < (INT)m_dwHeight; i++) 207 | CopyMemory( 208 | (BYTE*)rt.pBits + i * rt.Pitch, 209 | (BYTE*)pSrc->m_lpMipMapLevels[0]->GetData() + i * pSrc->m_lpMipMapLevels[0]->GetDataPitch(), 210 | pSrc->m_lpMipMapLevels[0]->GetDataPitch()); 211 | 212 | m_lpMipMapLevels[0]->GetD3D9Surface()->UnlockRect(); 213 | 214 | return TRUE; 215 | } 216 | -------------------------------------------------------------------------------- /D2GI/src/ddraw/dd_surface.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/common.h" 3 | 4 | #include "dd_surface.h" 5 | 6 | 7 | using namespace D3D7; 8 | 9 | 10 | SurfaceProxy::SurfaceProxy() : Unknown() 11 | { 12 | 13 | } 14 | 15 | 16 | SurfaceProxy::~SurfaceProxy() 17 | { 18 | 19 | } 20 | 21 | 22 | HRESULT SurfaceProxy::AddAttachedSurface(LPDIRECTDRAWSURFACE7 lpSurf) 23 | { 24 | return DDERR_GENERIC; 25 | } 26 | 27 | 28 | HRESULT SurfaceProxy::AddOverlayDirtyRect(LPRECT lpRect) 29 | { 30 | return DDERR_GENERIC; 31 | } 32 | 33 | 34 | HRESULT SurfaceProxy::Blt(LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 lpSrc, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpFX) 35 | { 36 | return DDERR_GENERIC; 37 | } 38 | 39 | 40 | HRESULT SurfaceProxy::BltBatch(LPDDBLTBATCH lpBatch, DWORD dwCount, DWORD dw) 41 | { 42 | return DDERR_GENERIC; 43 | } 44 | 45 | 46 | HRESULT SurfaceProxy::BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE7 lpSrc, LPRECT lpSrcRect, DWORD dwFlags) 47 | { 48 | return DDERR_GENERIC; 49 | } 50 | 51 | 52 | HRESULT SurfaceProxy::DeleteAttachedSurface(DWORD dw, LPDIRECTDRAWSURFACE7 lpSurf) 53 | { 54 | return DDERR_GENERIC; 55 | } 56 | 57 | 58 | HRESULT SurfaceProxy::EnumAttachedSurfaces(LPVOID lpArg, LPDDENUMSURFACESCALLBACK7 lpCallback) 59 | { 60 | return DDERR_GENERIC; 61 | } 62 | 63 | 64 | HRESULT SurfaceProxy::EnumOverlayZOrders(DWORD dwFlags, LPVOID lpArg, LPDDENUMSURFACESCALLBACK7 lpCallback) 65 | { 66 | return DDERR_GENERIC; 67 | } 68 | 69 | 70 | HRESULT SurfaceProxy::Flip(LPDIRECTDRAWSURFACE7 lpSurf, DWORD dwFlags) 71 | { 72 | return DDERR_GENERIC; 73 | } 74 | 75 | 76 | HRESULT SurfaceProxy::GetAttachedSurface(LPDDSCAPS2 lpCaps, LPDIRECTDRAWSURFACE7 FAR* lpSurf) 77 | { 78 | return DDERR_GENERIC; 79 | } 80 | 81 | 82 | HRESULT SurfaceProxy::GetBltStatus(DWORD dw) 83 | { 84 | return DDERR_GENERIC; 85 | } 86 | 87 | 88 | HRESULT SurfaceProxy::GetCaps(LPDDSCAPS2 lpCaps) 89 | { 90 | return DDERR_GENERIC; 91 | } 92 | 93 | 94 | HRESULT SurfaceProxy::GetClipper(LPDIRECTDRAWCLIPPER FAR* lpClipper) 95 | { 96 | return DDERR_GENERIC; 97 | } 98 | 99 | 100 | HRESULT SurfaceProxy::GetColorKey(DWORD dwFlags, LPDDCOLORKEY lpCK) 101 | { 102 | return DDERR_GENERIC; 103 | } 104 | 105 | 106 | HRESULT SurfaceProxy::GetDC(HDC FAR* lpDC) 107 | { 108 | return DDERR_GENERIC; 109 | } 110 | 111 | 112 | HRESULT SurfaceProxy::GetFlipStatus(DWORD dw) 113 | { 114 | return DDERR_GENERIC; 115 | } 116 | 117 | 118 | HRESULT SurfaceProxy::GetOverlayPosition(LPLONG lpX, LPLONG lpY) 119 | { 120 | return DDERR_GENERIC; 121 | } 122 | 123 | 124 | HRESULT SurfaceProxy::GetPalette(LPDIRECTDRAWPALETTE FAR* lpPal) 125 | { 126 | return DDERR_GENERIC; 127 | } 128 | 129 | 130 | HRESULT SurfaceProxy::GetPixelFormat(LPDDPIXELFORMAT lpPF) 131 | { 132 | return DDERR_GENERIC; 133 | } 134 | 135 | 136 | HRESULT SurfaceProxy::GetSurfaceDesc(LPDDSURFACEDESC2 lpDesc) 137 | { 138 | return DDERR_GENERIC; 139 | } 140 | 141 | 142 | HRESULT SurfaceProxy::Initialize(LPDIRECTDRAW lpDD, LPDDSURFACEDESC2 lpSurf) 143 | { 144 | return DDERR_GENERIC; 145 | } 146 | 147 | 148 | HRESULT SurfaceProxy::IsLost() 149 | { 150 | return DDERR_GENERIC; 151 | } 152 | 153 | 154 | HRESULT SurfaceProxy::Lock(LPRECT lpRect, LPDDSURFACEDESC2 lpDesc, DWORD dwFlags, HANDLE h) 155 | { 156 | return DDERR_GENERIC; 157 | } 158 | 159 | 160 | HRESULT SurfaceProxy::ReleaseDC(HDC hDC) 161 | { 162 | return DDERR_GENERIC; 163 | } 164 | 165 | 166 | HRESULT SurfaceProxy::Restore() 167 | { 168 | return DDERR_GENERIC; 169 | } 170 | 171 | 172 | HRESULT SurfaceProxy::SetClipper(LPDIRECTDRAWCLIPPER lpClipper) 173 | { 174 | return DDERR_GENERIC; 175 | } 176 | 177 | 178 | HRESULT SurfaceProxy::SetColorKey(DWORD dwFlags, LPDDCOLORKEY lpCK) 179 | { 180 | return DDERR_GENERIC; 181 | } 182 | 183 | 184 | HRESULT SurfaceProxy::SetOverlayPosition(LONG lX, LONG lY) 185 | { 186 | return DDERR_GENERIC; 187 | } 188 | 189 | 190 | HRESULT SurfaceProxy::SetPalette(LPDIRECTDRAWPALETTE lpPal) 191 | { 192 | return DDERR_GENERIC; 193 | } 194 | 195 | 196 | HRESULT SurfaceProxy::Unlock(LPRECT lpRect) 197 | { 198 | return DDERR_GENERIC; 199 | } 200 | 201 | 202 | HRESULT SurfaceProxy::UpdateOverlay(LPRECT lpSrcRect, LPDIRECTDRAWSURFACE7 lpSurf, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpFX) 203 | { 204 | return DDERR_GENERIC; 205 | } 206 | 207 | 208 | HRESULT SurfaceProxy::UpdateOverlayDisplay(DWORD dw) 209 | { 210 | return DDERR_GENERIC; 211 | } 212 | 213 | 214 | HRESULT SurfaceProxy::UpdateOverlayZOrder(DWORD dwFlags, LPDIRECTDRAWSURFACE7 lpSurf) 215 | { 216 | return DDERR_GENERIC; 217 | } 218 | 219 | 220 | HRESULT SurfaceProxy::GetDDInterface(LPVOID FAR* lpOut) 221 | { 222 | return DDERR_GENERIC; 223 | } 224 | 225 | 226 | HRESULT SurfaceProxy::PageLock(DWORD dw) 227 | { 228 | return DDERR_GENERIC; 229 | } 230 | 231 | 232 | HRESULT SurfaceProxy::PageUnlock(DWORD dw) 233 | { 234 | return DDERR_GENERIC; 235 | } 236 | 237 | 238 | HRESULT SurfaceProxy::SetSurfaceDesc(LPDDSURFACEDESC2 lpDesc, DWORD dw) 239 | { 240 | return DDERR_GENERIC; 241 | } 242 | 243 | 244 | HRESULT SurfaceProxy::SetPrivateData(REFGUID iid, LPVOID lpData, DWORD dwSize, DWORD dwFlags) 245 | { 246 | return DDERR_GENERIC; 247 | } 248 | 249 | 250 | HRESULT SurfaceProxy::GetPrivateData(REFGUID iid, LPVOID lpData, LPDWORD lpSize) 251 | { 252 | return DDERR_GENERIC; 253 | } 254 | 255 | 256 | HRESULT SurfaceProxy::FreePrivateData(REFGUID iid) 257 | { 258 | return DDERR_GENERIC; 259 | } 260 | 261 | 262 | HRESULT SurfaceProxy::GetUniquenessValue(LPDWORD lpdw) 263 | { 264 | return DDERR_GENERIC; 265 | } 266 | 267 | 268 | HRESULT SurfaceProxy::ChangeUniquenessValue() 269 | { 270 | return DDERR_GENERIC; 271 | } 272 | 273 | 274 | HRESULT SurfaceProxy::SetPriority(DWORD dw) 275 | { 276 | return DDERR_GENERIC; 277 | } 278 | 279 | 280 | HRESULT SurfaceProxy::GetPriority(LPDWORD lpdw) 281 | { 282 | return DDERR_GENERIC; 283 | } 284 | 285 | 286 | HRESULT SurfaceProxy::SetLOD(DWORD dw) 287 | { 288 | return DDERR_GENERIC; 289 | } 290 | 291 | 292 | HRESULT SurfaceProxy::GetLOD(LPDWORD lpdw) 293 | { 294 | return DDERR_GENERIC; 295 | } 296 | -------------------------------------------------------------------------------- /D2GI/src/d3d/d3d_device.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/common.h" 3 | 4 | #include "d3d_device.h" 5 | 6 | 7 | using namespace D3D7; 8 | 9 | 10 | DeviceProxy::DeviceProxy() 11 | { 12 | 13 | } 14 | 15 | 16 | DeviceProxy::~DeviceProxy() 17 | { 18 | } 19 | 20 | 21 | 22 | HRESULT DeviceProxy::GetCaps(LPD3DDEVICEDESC7 lpDesc) 23 | { 24 | return DDERR_GENERIC; 25 | } 26 | 27 | 28 | HRESULT DeviceProxy::EnumTextureFormats(LPD3DENUMPIXELFORMATSCALLBACK lpCallback, LPVOID lpArg) 29 | { 30 | return DDERR_GENERIC; 31 | } 32 | 33 | 34 | HRESULT DeviceProxy::BeginScene() 35 | { 36 | return DDERR_GENERIC; 37 | } 38 | 39 | 40 | HRESULT DeviceProxy::EndScene() 41 | { 42 | return DDERR_GENERIC; 43 | } 44 | 45 | 46 | HRESULT DeviceProxy::GetDirect3D(LPDIRECT3D7* lpD3D) 47 | { 48 | return DDERR_GENERIC; 49 | } 50 | 51 | 52 | HRESULT DeviceProxy::SetRenderTarget(LPDIRECTDRAWSURFACE7 lpSurf, DWORD dwFlags) 53 | { 54 | return DDERR_GENERIC; 55 | } 56 | 57 | 58 | HRESULT DeviceProxy::GetRenderTarget(LPDIRECTDRAWSURFACE7* lpSurf) 59 | { 60 | return DDERR_GENERIC; 61 | } 62 | 63 | 64 | HRESULT DeviceProxy::Clear(DWORD dwCount, LPD3DRECT lpRects, DWORD dwFlags, D3DCOLOR col, D3DVALUE z, DWORD dwStencil) 65 | { 66 | return DDERR_GENERIC; 67 | } 68 | 69 | 70 | HRESULT DeviceProxy::SetTransform(D3DTRANSFORMSTATETYPE state, LPD3DMATRIX lpMatrix) 71 | { 72 | return DDERR_GENERIC; 73 | } 74 | 75 | 76 | HRESULT DeviceProxy::GetTransform(D3DTRANSFORMSTATETYPE state, LPD3DMATRIX lpMatrix) 77 | { 78 | return DDERR_GENERIC; 79 | } 80 | 81 | 82 | HRESULT DeviceProxy::SetViewport(LPD3DVIEWPORT7 lpViewport) 83 | { 84 | return DDERR_GENERIC; 85 | } 86 | 87 | 88 | HRESULT DeviceProxy::MultiplyTransform(D3DTRANSFORMSTATETYPE state, LPD3DMATRIX lpMatrix) 89 | { 90 | return DDERR_GENERIC; 91 | } 92 | 93 | 94 | HRESULT DeviceProxy::GetViewport(LPD3DVIEWPORT7 lpViewport) 95 | { 96 | return DDERR_GENERIC; 97 | } 98 | 99 | 100 | HRESULT DeviceProxy::SetMaterial(LPD3DMATERIAL7 lpMaterial) 101 | { 102 | return DDERR_GENERIC; 103 | } 104 | 105 | 106 | HRESULT DeviceProxy::GetMaterial(LPD3DMATERIAL7 lpMaterial) 107 | { 108 | return DDERR_GENERIC; 109 | } 110 | 111 | 112 | HRESULT DeviceProxy::SetLight(DWORD i, LPD3DLIGHT7 lpLight) 113 | { 114 | return DDERR_GENERIC; 115 | } 116 | 117 | 118 | HRESULT DeviceProxy::GetLight(DWORD i, LPD3DLIGHT7 lpLight) 119 | { 120 | return DDERR_GENERIC; 121 | } 122 | 123 | 124 | HRESULT DeviceProxy::SetRenderState(D3DRENDERSTATETYPE state, DWORD v) 125 | { 126 | return DDERR_GENERIC; 127 | } 128 | 129 | 130 | HRESULT DeviceProxy::GetRenderState(D3DRENDERSTATETYPE state, LPDWORD lpv) 131 | { 132 | return DDERR_GENERIC; 133 | } 134 | 135 | 136 | HRESULT DeviceProxy::BeginStateBlock() 137 | { 138 | return DDERR_GENERIC; 139 | } 140 | 141 | 142 | HRESULT DeviceProxy::EndStateBlock(LPDWORD lpdw) 143 | { 144 | return DDERR_GENERIC; 145 | } 146 | 147 | 148 | HRESULT DeviceProxy::PreLoad(LPDIRECTDRAWSURFACE7 lpSurf) 149 | { 150 | return DDERR_GENERIC; 151 | } 152 | 153 | 154 | HRESULT DeviceProxy::DrawPrimitive(D3DPRIMITIVETYPE pt, DWORD dwFVF, LPVOID lpVerts, DWORD dwVertCount, DWORD dwFlags) 155 | { 156 | return DDERR_GENERIC; 157 | } 158 | 159 | 160 | HRESULT DeviceProxy::DrawIndexedPrimitive(D3DPRIMITIVETYPE pt, DWORD dwFVF, LPVOID lpVerts, DWORD dwVertCount, LPWORD lpIdx, DWORD dwIdxCount, DWORD dwFlags) 161 | { 162 | return DDERR_GENERIC; 163 | } 164 | 165 | 166 | HRESULT DeviceProxy::SetClipStatus(LPD3DCLIPSTATUS lpStatus) 167 | { 168 | return DDERR_GENERIC; 169 | } 170 | 171 | 172 | HRESULT DeviceProxy::GetClipStatus(LPD3DCLIPSTATUS lpStatus) 173 | { 174 | return DDERR_GENERIC; 175 | } 176 | 177 | 178 | HRESULT DeviceProxy::DrawPrimitiveStrided(D3DPRIMITIVETYPE pt, DWORD dwFVF, LPD3DDRAWPRIMITIVESTRIDEDDATA lpData, DWORD dwCount, DWORD dwFlags) 179 | { 180 | return DDERR_GENERIC; 181 | } 182 | 183 | 184 | HRESULT DeviceProxy::DrawIndexedPrimitiveStrided(D3DPRIMITIVETYPE pt, DWORD dwFVF, LPD3DDRAWPRIMITIVESTRIDEDDATA lpData, DWORD dwCount, LPWORD lpIdx, DWORD dwIdxCount, DWORD dwFlags) 185 | { 186 | return DDERR_GENERIC; 187 | } 188 | 189 | 190 | HRESULT DeviceProxy::DrawPrimitiveVB(D3DPRIMITIVETYPE pt, LPDIRECT3DVERTEXBUFFER7 lpVB, DWORD dwStartVert, DWORD dwCount, DWORD dwFlags) 191 | { 192 | return DDERR_GENERIC; 193 | } 194 | 195 | 196 | HRESULT DeviceProxy::DrawIndexedPrimitiveVB(D3DPRIMITIVETYPE pt, LPDIRECT3DVERTEXBUFFER7 lpVB, DWORD dwStartVert, DWORD dwCount, LPWORD lpIdx, DWORD dwIdxCount, DWORD dwFlags) 197 | { 198 | return DDERR_GENERIC; 199 | } 200 | 201 | 202 | HRESULT DeviceProxy::ComputeSphereVisibility(LPD3DVECTOR lpCenters, LPD3DVALUE lpRads, DWORD dwCount, DWORD dwFlags, LPDWORD lpResults) 203 | { 204 | return DDERR_GENERIC; 205 | } 206 | 207 | 208 | HRESULT DeviceProxy::GetTexture(DWORD i, LPDIRECTDRAWSURFACE7* lpTex) 209 | { 210 | return DDERR_GENERIC; 211 | } 212 | 213 | 214 | HRESULT DeviceProxy::SetTexture(DWORD i, LPDIRECTDRAWSURFACE7 lpTex) 215 | { 216 | return DDERR_GENERIC; 217 | } 218 | 219 | 220 | HRESULT DeviceProxy::GetTextureStageState(DWORD i, D3DTEXTURESTAGESTATETYPE state, LPDWORD lpdw) 221 | { 222 | return DDERR_GENERIC; 223 | } 224 | 225 | 226 | HRESULT DeviceProxy::SetTextureStageState(DWORD i, D3DTEXTURESTAGESTATETYPE state, DWORD dw) 227 | { 228 | return DDERR_GENERIC; 229 | } 230 | 231 | 232 | HRESULT DeviceProxy::ValidateDevice(LPDWORD lpdw) 233 | { 234 | return DDERR_GENERIC; 235 | } 236 | 237 | 238 | HRESULT DeviceProxy::ApplyStateBlock(DWORD dwHandle) 239 | { 240 | return DDERR_GENERIC; 241 | } 242 | 243 | 244 | HRESULT DeviceProxy::CaptureStateBlock(DWORD dwHandle) 245 | { 246 | return DDERR_GENERIC; 247 | } 248 | 249 | 250 | HRESULT DeviceProxy::DeleteStateBlock(DWORD dwHandle) 251 | { 252 | return DDERR_GENERIC; 253 | } 254 | 255 | 256 | HRESULT DeviceProxy::CreateStateBlock(D3DSTATEBLOCKTYPE type, LPDWORD lpHandle) 257 | { 258 | return DDERR_GENERIC; 259 | } 260 | 261 | 262 | HRESULT DeviceProxy::Load(LPDIRECTDRAWSURFACE7 lpDestSurf, LPPOINT lpDestPoint, LPDIRECTDRAWSURFACE7 lpSrcSurf, LPRECT lpSrcRect, DWORD dwFlags) 263 | { 264 | return DDERR_GENERIC; 265 | } 266 | 267 | 268 | HRESULT DeviceProxy::LightEnable(DWORD i, BOOL bEnable) 269 | { 270 | return DDERR_GENERIC; 271 | } 272 | 273 | 274 | HRESULT DeviceProxy::GetLightEnable(DWORD i, BOOL* lpEnable) 275 | { 276 | return DDERR_GENERIC; 277 | } 278 | 279 | 280 | HRESULT DeviceProxy::SetClipPlane(DWORD i, D3DVALUE* lpV) 281 | { 282 | return DDERR_GENERIC; 283 | } 284 | 285 | 286 | HRESULT DeviceProxy::GetClipPlane(DWORD i, D3DVALUE* lpV) 287 | { 288 | return DDERR_GENERIC; 289 | } 290 | 291 | 292 | HRESULT DeviceProxy::GetInfo(DWORD i, LPVOID lpOut, DWORD dwSize) 293 | { 294 | return DDERR_GENERIC; 295 | } 296 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_ddraw.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define INITGUID 3 | #include "../common/common.h" 4 | #include "../common/utils.h" 5 | #include "../common/logger.h" 6 | 7 | #include "../common/d3d7.h" 8 | #include "../common/d3d9.h" 9 | 10 | #include "d2gi.h" 11 | #include "d2gi_ddraw.h" 12 | #include "d2gi_direct3d.h" 13 | #include "d2gi_enums.h" 14 | #include "d2gi_prim_flip_surf.h" 15 | #include "d2gi_sysmem_surf.h" 16 | #include "d2gi_prim_single_surf.h" 17 | #include "d2gi_palette.h" 18 | #include "d2gi_zbuf_surf.h" 19 | #include "d2gi_texture.h" 20 | 21 | 22 | D2GIDirectDraw::D2GIDirectDraw(D2GI* pD2GI) : DDrawProxy(), D2GIBase(pD2GI) 23 | { 24 | m_pResourceContainer = new D2GIResourceContainer(m_pD2GI); 25 | } 26 | 27 | 28 | D2GIDirectDraw::~D2GIDirectDraw() 29 | { 30 | m_pD2GI->OnDirectDrawReleased(); 31 | DEL(m_pResourceContainer); 32 | } 33 | 34 | 35 | HRESULT D2GIDirectDraw::QueryInterface(REFIID riid, LPVOID FAR* ppvObj) 36 | { 37 | if (IsEqualIID(riid, D3D7::IID_IDirect3D7)) 38 | { 39 | *ppvObj = (D3D7::IDirect3D7*)new D2GIDirect3D(m_pD2GI); 40 | 41 | return DD_OK; 42 | } 43 | 44 | Logger::Warning(TEXT("Requested unknown interface from DDraw")); 45 | return DDERR_GENERIC; 46 | } 47 | 48 | 49 | HRESULT D2GIDirectDraw::CreateSurface(D3D7::LPDDSURFACEDESC2 lpDesc, D3D7::LPDIRECTDRAWSURFACE7 FAR* lpSurf, IUnknown FAR* pUnknown) 50 | { 51 | D2GIPIXELFORMAT eStdPF = (m_pD2GI->GetOriginalBPP() == 8) ? D2GIPF_8_PAL : D2GIPF_16_565; 52 | 53 | if ((lpDesc->dwFlags & DDSD_CAPS) && (lpDesc->ddsCaps.dwCaps & DDSCAPS_FLIP)) 54 | { 55 | m_pPrimaryFlippableSurf = new D2GIPrimaryFlippableSurface(m_pD2GI, 56 | m_pD2GI->GetOriginalWidth(), m_pD2GI->GetOriginalHeight(), eStdPF); 57 | 58 | m_pResourceContainer->Add((D2GIResource*)m_pPrimaryFlippableSurf); 59 | *lpSurf = (D3D7::IDirectDrawSurface7*)m_pPrimaryFlippableSurf; 60 | 61 | return DD_OK; 62 | } 63 | 64 | if ((lpDesc->dwFlags & DDSD_CAPS) && (lpDesc->dwFlags & DDSD_WIDTH) 65 | && (lpDesc->dwFlags & DDSD_HEIGHT) && (lpDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) 66 | { 67 | D2GISystemMemorySurface* pSurf = new D2GISystemMemorySurface(m_pD2GI, lpDesc->dwWidth, lpDesc->dwHeight, 68 | (lpDesc->dwFlags & DDSD_PIXELFORMAT) ? DD7PF_To_D2GIPF(&lpDesc->ddpfPixelFormat) : eStdPF); 69 | 70 | m_pResourceContainer->Add((D2GIResource*)pSurf); 71 | *lpSurf = (D3D7::IDirectDrawSurface7*)pSurf; 72 | 73 | return DD_OK; 74 | } 75 | 76 | if ((lpDesc->dwFlags & DDSD_CAPS) && (lpDesc->ddsCaps.dwCaps == DDSCAPS_PRIMARYSURFACE)) 77 | { 78 | m_pPrimarySingleSurf = new D2GIPrimarySingleSurface(m_pD2GI, 79 | m_pD2GI->GetOriginalWidth(), m_pD2GI->GetOriginalHeight(), eStdPF); 80 | 81 | m_pResourceContainer->Add((D2GIResource*)m_pPrimarySingleSurf); 82 | *lpSurf = (D3D7::IDirectDrawSurface7*)m_pPrimarySingleSurf; 83 | 84 | return DD_OK; 85 | } 86 | 87 | if ((lpDesc->dwFlags & DDSD_CAPS) && (lpDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) 88 | { 89 | D2GIZBufferSurface* pSurf = new D2GIZBufferSurface(m_pD2GI, 90 | m_pD2GI->GetOriginalWidth(), m_pD2GI->GetOriginalHeight(), D2GIPF_16_DEPTH); 91 | 92 | m_pResourceContainer->Add((D2GIResource*)pSurf); 93 | *lpSurf = (D3D7::IDirectDrawSurface7*)pSurf; 94 | 95 | return DD_OK; 96 | } 97 | 98 | if ((lpDesc->dwFlags & DDSD_CAPS) && (lpDesc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) 99 | && (lpDesc->dwFlags & DDSD_WIDTH) && (lpDesc->dwFlags & DDSD_HEIGHT) 100 | && (lpDesc->dwFlags & DDSD_PIXELFORMAT)) 101 | { 102 | // MULTITHREADED ACCESS 103 | DWORD dwMipMapCount = (lpDesc->dwFlags & DDSD_MIPMAPCOUNT) ? lpDesc->dwMipMapCount : 0; 104 | D2GITexture* pTex = new D2GITexture(m_pD2GI, lpDesc->dwWidth, lpDesc->dwHeight, 105 | DD7PF_To_D2GIPF(&lpDesc->ddpfPixelFormat), dwMipMapCount); 106 | 107 | m_pResourceContainer->Add((D2GIResource*)pTex); // MT-safe 108 | *lpSurf = (D3D7::IDirectDrawSurface7*)pTex; 109 | 110 | return DD_OK; 111 | } 112 | 113 | Logger::Warning(TEXT("Requested unknown surface creation")); 114 | return DDERR_GENERIC; 115 | } 116 | 117 | 118 | HRESULT D2GIDirectDraw::SetCooperativeLevel(HWND hWnd, DWORD dwFlags) 119 | { 120 | m_pD2GI->OnCooperativeLevelSet(hWnd, dwFlags); 121 | return DD_OK; 122 | } 123 | 124 | 125 | HRESULT D2GIDirectDraw::SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) 126 | { 127 | m_pD2GI->OnDisplayModeSet(dwWidth, dwHeight, dwBPP, dwFlags); 128 | return DD_OK; 129 | } 130 | 131 | 132 | HRESULT D2GIDirectDraw::EnumDisplayModes(DWORD dwFlags, D3D7::LPDDSURFACEDESC2 lpSurfDesc, LPVOID pArg, D3D7::LPDDENUMMODESCALLBACK2 pCallback) 133 | { 134 | m_pD2GI->OnDisplayModeEnum(pArg, pCallback); 135 | return DD_OK; 136 | } 137 | 138 | 139 | HRESULT D2GIDirectDraw::GetDeviceIdentifier(D3D7::LPDDDEVICEIDENTIFIER2 lpDID, DWORD) 140 | { 141 | D3D9::D3DADAPTER_IDENTIFIER9 sAdapterID; 142 | D3D9::IDirect3D9* pD3D9 = GetD3D9(); 143 | 144 | pD3D9->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &sAdapterID); 145 | 146 | strcpy(lpDID->szDescription, sAdapterID.Description); 147 | strcpy(lpDID->szDriver, sAdapterID.Driver); 148 | lpDID->dwDeviceId = sAdapterID.DeviceId; 149 | lpDID->dwRevision = sAdapterID.Revision; 150 | lpDID->dwSubSysId = sAdapterID.SubSysId; 151 | lpDID->dwVendorId = sAdapterID.VendorId; 152 | lpDID->dwWHQLLevel = sAdapterID.WHQLLevel; 153 | lpDID->guidDeviceIdentifier = sAdapterID.DeviceIdentifier; 154 | lpDID->liDriverVersion = sAdapterID.DriverVersion; 155 | 156 | return DD_OK; 157 | } 158 | 159 | 160 | HRESULT D2GIDirectDraw::GetCaps(D3D7::LPDDCAPS lpHALCaps, D3D7::LPDDCAPS lpHELCaps) 161 | { 162 | *lpHALCaps = g_sHALCaps; 163 | *lpHELCaps = g_sHELCaps; 164 | 165 | return DD_OK; 166 | } 167 | 168 | 169 | VOID D2GIDirectDraw::ReleaseResources() 170 | { 171 | m_pResourceContainer->ReleaseResources(); 172 | } 173 | 174 | 175 | VOID D2GIDirectDraw::LoadResources() 176 | { 177 | m_pResourceContainer->LoadResources(); 178 | } 179 | 180 | 181 | HRESULT D2GIDirectDraw::GetAvailableVidMem(D3D7::LPDDSCAPS2 pCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) 182 | { 183 | // TODO: think about this vmemory profiling 184 | *lpdwTotal = *lpdwFree = 1778384896; 185 | return DD_OK; 186 | } 187 | 188 | 189 | HRESULT D2GIDirectDraw::RestoreDisplayMode() 190 | { 191 | return DD_OK; 192 | } 193 | 194 | 195 | HRESULT D2GIDirectDraw::CreatePalette(DWORD dwFlags, LPPALETTEENTRY pEntries, D3D7::LPDIRECTDRAWPALETTE FAR* lpPalette, IUnknown FAR*) 196 | { 197 | if (dwFlags == (DDPCAPS_8BIT | DDPCAPS_ALLOW256)) 198 | { 199 | D2GIPalette* pPalette = new D2GIPalette(m_pD2GI, pEntries); 200 | 201 | m_pResourceContainer->Add((D2GIResource*)pPalette); 202 | *lpPalette = (D3D7::IDirectDrawPalette*)pPalette; 203 | 204 | return DD_OK; 205 | } 206 | 207 | Logger::Warning(TEXT("Requested unknown palette creation")); 208 | return DDERR_GENERIC; 209 | } 210 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_blitter.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/common.h" 3 | #include "../common/frect.h" 4 | #include "../common/logger.h" 5 | 6 | #include "d2gi.h" 7 | #include "d2gi_blitter.h" 8 | 9 | #include "d2gi_blitter_vs.h" 10 | #include "d2gi_blitter_ps.h" 11 | 12 | 13 | using namespace D3D9; 14 | 15 | 16 | D2GIBlitter::D2GIBlitter(D2GI* pD2GI) 17 | : D2GIBase(pD2GI), m_pVDecl(NULL), m_pVB(NULL), m_pVS(NULL), m_pPS(NULL) 18 | { 19 | 20 | } 21 | 22 | 23 | D2GIBlitter::~D2GIBlitter() 24 | { 25 | ReleaseResource(); 26 | } 27 | 28 | 29 | VOID D2GIBlitter::ReleaseResource() 30 | { 31 | RELEASE(m_pVB); 32 | RELEASE(m_pVDecl); 33 | RELEASE(m_pVS); 34 | RELEASE(m_pPS); 35 | } 36 | 37 | 38 | VOID D2GIBlitter::LoadResource() 39 | { 40 | D3DVERTEXELEMENT9 asVertexElements[] = 41 | { 42 | {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, 43 | {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, 44 | D3DDECL_END() 45 | }; 46 | IDirect3DDevice9* pDev = GetD3D9Device(); 47 | 48 | if (FAILED(pDev->CreateVertexDeclaration(asVertexElements, &m_pVDecl))) 49 | Logger::Error(TEXT("Failed to create blitter vertex declaration")); 50 | 51 | FLOAT afVerts[] = 52 | { 53 | -0.5f, 0.5f, 0.0, 0.0, 0.0, 54 | 0.5f, 0.5f, 0.0, 1.0f, 0.0, 55 | -0.5f, -0.5f, 0.0, 0.0, 1.0f, 56 | 57 | 0.5f, 0.5f, 0.0, 1.0f, 0.0, 58 | 0.5f, -0.5f, 0.0, 1.0f, 1.0f, 59 | -0.5f, -0.5f, 0.0, 0.0, 1.0f, 60 | }; 61 | VOID* pData; 62 | 63 | if (FAILED(pDev->CreateVertexBuffer(sizeof(afVerts), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_pVB, NULL))) 64 | Logger::Error(TEXT("Failed to create blitter vertex buffer")); 65 | 66 | if (FAILED(m_pVB->Lock(0, 0, &pData, 0))) 67 | Logger::Error(TEXT("Failed to lock blitter vertex buffer")); 68 | 69 | CopyMemory(pData, afVerts, sizeof(afVerts)); 70 | m_pVB->Unlock(); 71 | 72 | 73 | if (FAILED(pDev->CreateVertexShader((DWORD*)g_pBlitterVS, &m_pVS))) 74 | Logger::Error(TEXT("Failed to create blitter vertex shader")); 75 | 76 | if (FAILED(pDev->CreatePixelShader((DWORD*)g_pBlitterPS, &m_pPS))) 77 | Logger::Error(TEXT("Failed to create blitter pixel shader")); 78 | } 79 | 80 | 81 | VOID D2GIBlitter::Blit(IDirect3DSurface9* pDst, FRECT* pDstRT, 82 | IDirect3DTexture9* pSrc, FRECT* pSrcRT, BOOL bEmulateCK) 83 | { 84 | IDirect3DDevice9* pDev = GetD3D9Device(); 85 | 86 | D3DXVECTOR4 vTextureRect, vScreenPosRect, vTextureBorder; 87 | 88 | D3DSURFACE_DESC sDstDesc, sSrcDesc; 89 | FRECT rtSrc, rtDst; 90 | 91 | IDirect3DSurface9* pOriginalRT = NULL, *pOriginalDS; 92 | IDirect3DBaseTexture9* pCurrentTexture1 = NULL, * pCurrentTexture2 = NULL; 93 | DWORD dwMinFilter, dwMagFilter, dwCullMode, dwAlphaTestEnable; 94 | DWORD dwAlphaBlending, dwAlphaOp, dwAlphaSrc, dwAlphaDst; 95 | DWORD dwZEnable, dwZWriteEnable; 96 | D3DVIEWPORT9 sOriginalVP, sUsedVP; 97 | 98 | pDst->GetDesc(&sDstDesc); 99 | pSrc->GetLevelDesc(0, &sSrcDesc); 100 | 101 | if (pSrcRT != NULL) 102 | rtSrc = *pSrcRT; 103 | else 104 | rtSrc = FRECT(0.0, 0.0, (FLOAT)sSrcDesc.Width, (FLOAT)sSrcDesc.Height); 105 | 106 | if (pDstRT != NULL) 107 | rtDst = *pDstRT; 108 | else 109 | rtDst = FRECT(0.0, 0.0, (FLOAT)sDstDesc.Width, (FLOAT)sDstDesc.Height); 110 | 111 | pDev->GetRenderTarget(0, &pOriginalRT); 112 | pDev->GetDepthStencilSurface(&pOriginalDS); 113 | pDev->GetViewport(&sOriginalVP); 114 | pDev->GetRenderState(D3DRS_ZENABLE, &dwZEnable); 115 | pDev->GetRenderState(D3DRS_ZWRITEENABLE, &dwZWriteEnable); 116 | pDev->GetTexture(0, &pCurrentTexture1); 117 | pDev->GetTexture(1, &pCurrentTexture2); 118 | pDev->GetSamplerState(0, D3DSAMP_MINFILTER, &dwMinFilter); 119 | pDev->GetSamplerState(0, D3DSAMP_MAGFILTER, &dwMagFilter); 120 | pDev->GetRenderState(D3DRS_CULLMODE, &dwCullMode); 121 | pDev->GetRenderState(D3DRS_ALPHABLENDENABLE, &dwAlphaBlending); 122 | pDev->GetRenderState(D3D9::D3DRS_ALPHATESTENABLE, &dwAlphaTestEnable); 123 | if (bEmulateCK) 124 | { 125 | pDev->GetRenderState(D3D9::D3DRS_BLENDOP, &dwAlphaOp); 126 | pDev->GetRenderState(D3D9::D3DRS_SRCBLEND, &dwAlphaSrc); 127 | pDev->GetRenderState(D3D9::D3DRS_DESTBLEND, &dwAlphaDst); 128 | } 129 | 130 | vTextureRect.x = rtSrc.GetWidth() / (FLOAT)sSrcDesc.Width; 131 | vTextureRect.y = rtSrc.GetHeight() / (FLOAT)sSrcDesc.Height; 132 | vTextureRect.z = rtSrc.fLeft / (FLOAT)sSrcDesc.Width; 133 | vTextureRect.w = rtSrc.fTop / (FLOAT)sSrcDesc.Height; 134 | 135 | vTextureBorder.x = (rtSrc.fLeft + 0.5f) / sSrcDesc.Width; 136 | vTextureBorder.y = (rtSrc.fTop + 0.5f) / sSrcDesc.Height; 137 | vTextureBorder.z = (rtSrc.fRight - 0.5f) / sSrcDesc.Width; 138 | vTextureBorder.w = (rtSrc.fBottom - 0.5f) / sSrcDesc.Height; 139 | 140 | vScreenPosRect.x = 2.0f * rtDst.GetWidth() / (FLOAT)sDstDesc.Width; 141 | vScreenPosRect.y = 2.0f * rtDst.GetHeight() / (FLOAT)sDstDesc.Height; 142 | vScreenPosRect.z = 2.0f * (-0.5f + rtDst.GetXCenter()) / (FLOAT)sDstDesc.Width - 1.0f; 143 | vScreenPosRect.w = -2.0f * (-0.5f + rtDst.GetYCenter()) / (FLOAT)sDstDesc.Height + 1.0f; 144 | 145 | sUsedVP.X = 0; 146 | sUsedVP.Y = 0; 147 | sUsedVP.Width = sDstDesc.Width; 148 | sUsedVP.Height = sDstDesc.Height; 149 | sUsedVP.MinZ = 0.0; 150 | sUsedVP.MaxZ = 1.0f; 151 | 152 | if(pDst != pOriginalRT) 153 | pDev->SetRenderTarget(0, pDst); 154 | pDev->SetDepthStencilSurface(NULL); 155 | pDev->SetViewport(&sUsedVP); 156 | 157 | pDev->SetVertexDeclaration(m_pVDecl); 158 | pDev->SetStreamSource(0, m_pVB, 0, sizeof(FLOAT) * 5); 159 | 160 | pDev->SetVertexShader(m_pVS); 161 | pDev->SetVertexShaderConstantF(0, &vScreenPosRect.x, 1); 162 | pDev->SetVertexShaderConstantF(1, &vTextureRect.x, 1); 163 | 164 | pDev->SetPixelShader(m_pPS); 165 | pDev->SetPixelShaderConstantF(0, &vTextureBorder.x, 1); 166 | 167 | 168 | pDev->SetTexture(0, pSrc); 169 | pDev->SetTexture(1, NULL); 170 | pDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 171 | pDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 172 | pDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 173 | 174 | pDev->SetRenderState(D3DRS_ZENABLE, FALSE); 175 | pDev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); 176 | pDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); 177 | if (bEmulateCK) 178 | { 179 | pDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); 180 | pDev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); 181 | pDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); 182 | pDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 183 | }else 184 | pDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); 185 | 186 | pDev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); 187 | 188 | pDev->SetPixelShader(NULL); 189 | pDev->SetVertexShader(NULL); 190 | pDev->SetTexture(0, pCurrentTexture1); 191 | pDev->SetTexture(1, pCurrentTexture2); 192 | RELEASE(pCurrentTexture1); 193 | RELEASE(pCurrentTexture2); 194 | pDev->SetViewport(&sOriginalVP); 195 | pDev->SetSamplerState(0, D3DSAMP_MINFILTER, dwMinFilter); 196 | pDev->SetSamplerState(0, D3DSAMP_MAGFILTER, dwMagFilter); 197 | pDev->SetRenderState(D3DRS_ZENABLE, dwZEnable); 198 | pDev->SetRenderState(D3DRS_ZWRITEENABLE, dwZWriteEnable); 199 | pDev->SetRenderState(D3DRS_CULLMODE, dwCullMode); 200 | pDev->SetRenderState(D3DRS_ALPHABLENDENABLE, dwAlphaBlending); 201 | pDev->SetRenderState(D3D9::D3DRS_ALPHATESTENABLE, dwAlphaTestEnable); 202 | if (bEmulateCK) 203 | { 204 | pDev->SetRenderState(D3DRS_BLENDOP, dwAlphaOp); 205 | pDev->SetRenderState(D3DRS_SRCBLEND, dwAlphaSrc); 206 | pDev->SetRenderState(D3DRS_DESTBLEND, dwAlphaDst); 207 | } 208 | if (pDst != pOriginalRT) 209 | pDev->SetRenderTarget(0, pOriginalRT); 210 | pDev->SetDepthStencilSurface(pOriginalDS); 211 | RELEASE(pOriginalDS); 212 | RELEASE(pOriginalRT); 213 | } 214 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi_enums.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define INITGUID 3 | #include "d2gi_enums.h" 4 | 5 | 6 | using namespace D3D7; 7 | 8 | 9 | DDPIXELFORMAT g_pf16_565 = 10 | { 11 | sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 63488, 2016, 31, 0, 12 | }; 13 | 14 | 15 | DDPIXELFORMAT g_pf16_555 = 16 | { 17 | sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 31744, 992, 31, 0, 18 | }; 19 | 20 | 21 | DDPIXELFORMAT g_pf16_1555 = 22 | { 23 | sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0, 16, 31744, 992, 31, 32768 24 | }; 25 | 26 | 27 | DDPIXELFORMAT g_pf16_4444 = 28 | { 29 | sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0, 16, 3840, 240, 15, 61440 30 | }; 31 | 32 | 33 | DDPIXELFORMAT g_pf16_v8u8 = 34 | { 35 | sizeof(DDPIXELFORMAT), DDPF_BUMPDUDV, 0, 16, 255, 65280, 0, 0 36 | }; 37 | 38 | 39 | DDPIXELFORMAT g_pf8_Pal = 40 | { 41 | sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_PALETTEINDEXED8, 0, 8, 0, 0, 0, 0, 42 | }; 43 | 44 | 45 | DDPIXELFORMAT g_pf16_depth = 46 | { 47 | sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0, 16, 0, 65535, 0, 0 48 | }; 49 | 50 | 51 | DDSURFACEDESC2 g_asStdDisplayModes[] = 52 | { 53 | // 640x480x8 54 | { 55 | sizeof(DDSURFACEDESC2), DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_PITCH | DDSD_PIXELFORMAT, 56 | 480, 640, 640, 0, 0, 0, 0, NULL, {0, 0}, {0, 0}, {0, 0}, {0, 0}, g_pf8_Pal 57 | }, 58 | // 640x480x16 59 | { 60 | sizeof(DDSURFACEDESC2), DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_PITCH | DDSD_PIXELFORMAT, 61 | 480, 640, 1280, 0, 0, 0, 0, NULL, {0, 0}, {0, 0}, {0, 0}, {0, 0}, g_pf16_565 62 | }, 63 | // 800x600x8 64 | { 65 | sizeof(DDSURFACEDESC2), DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_PITCH | DDSD_PIXELFORMAT, 66 | 600, 800, 800, 0, 0, 0, 0, NULL, {0, 0}, {0, 0}, {0, 0}, {0, 0}, g_pf8_Pal 67 | }, 68 | // 800x600x16 69 | { 70 | sizeof(DDSURFACEDESC2), DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_PITCH | DDSD_PIXELFORMAT, 71 | 600, 800, 1600, 0, 0, 0, 0, NULL, {0, 0}, {0, 0}, {0, 0}, {0, 0}, g_pf16_565 72 | }, 73 | // 1024x768x8 74 | { 75 | sizeof(DDSURFACEDESC2), DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_PITCH | DDSD_PIXELFORMAT, 76 | 768, 1024, 1024, 0, 0, 0, 0, NULL, {0, 0}, {0, 0}, {0, 0}, {0, 0}, g_pf8_Pal 77 | }, 78 | // 1024x768x16 79 | { 80 | sizeof(DDSURFACEDESC2), DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_PITCH | DDSD_PIXELFORMAT, 81 | 768, 1024, 2048, 0, 0, 0, 0, NULL, {0, 0}, {0, 0}, {0, 0}, {0, 0}, g_pf16_565 82 | }, 83 | // 1600x1200x8 84 | { 85 | sizeof(DDSURFACEDESC2), DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_PITCH | DDSD_PIXELFORMAT, 86 | 1200, 1600, 1600, 0, 0, 0, 0, NULL, {0, 0}, {0, 0}, {0, 0}, {0, 0}, g_pf8_Pal 87 | }, 88 | // 1600x1200x16 89 | { 90 | sizeof(DDSURFACEDESC2), DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_PITCH | DDSD_PIXELFORMAT, 91 | 1200, 1600, 3200, 0, 0, 0, 0, NULL, {0, 0}, {0, 0}, {0, 0}, {0, 0}, g_pf16_565 92 | }, 93 | }; 94 | 95 | UINT g_uStdDisplayModesCount = ARRAYSIZE(g_asStdDisplayModes); 96 | 97 | 98 | DDCAPS g_sHALCaps = 99 | { 100 | 380, 2513600449, 2691346992, 189201, 581784800, 101 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102 | 1778384896, 1774188544, 1, 0, 18, 0, 0, 0, 0, 0, 103 | {0, 0, 0, 0, 0, 0, 4096, 0}, {809923324}, 104 | 32, 2048000, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 105 | {0, 0, 0, 0, 0, 0, 4096, 0}, 64, 0, 0, 106 | {0, 0, 0, 0, 0, 0, 4096, 0}, 0, 0, 0, 107 | {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 2513600449, 108 | 2690822704, 189201, 581784800, 109 | {0, 0, 0, 0, 0, 0, 4096, 0}, 809923324, 512, 0, 0, 110 | }; 111 | 112 | 113 | DDCAPS g_sHELCaps = 114 | { 115 | 380, 4106256961, 1, 512, 261347, 0, 839, 116 | 0, 0, 0, 0, 0, 0, 0, 1024, 117 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118 | {1, 0, 0, 0, 0, 0, 4096, 2147483648}, {4330320}, 119 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 4106256961, 512, 120 | 261347, {1, 0, 0, 0, 0, 0, 4096, 2147483648}, 121 | 4106256961, 512, 261347, 122 | {1, 0, 0, 0, 0, 0, 4096, 2147483648}, 123 | 4106256961, 512, 261347, 124 | {1, 0, 0, 0, 0, 0, 4096, 2147483648}, 125 | 0, 0, 0, 4106256961, 1, 512, 261347, 126 | {1, 0, 0, 0, 0, 0, 4096, 2147483648}, 127 | 4330320, 512, 0, 0, 128 | }; 129 | 130 | 131 | D3DDEVICEDESC7 g_asDeviceDescs[] = 132 | { 133 | { 134 | 1361, 135 | { 136 | 56, 112, 2171383, 255, 8191, 2047, 255, 137 | 807562, 223, 50529087, 207, 31, 4, 4, 138 | }, 139 | { 140 | 56, 112, 2171383, 255, 8191, 2047, 141 | 255, 807562, 223, 50529087, 207, 31, 4, 4, 142 | }, 143 | 3840, 1024, 1, 1, 1024, 1024, 256, 0, 1, 144 | -4096.0, -4096.0, 4095.0, 4095.0, 0.0, 255, 8, 145 | 30975, 8, 8, 4294967295, 10000.0, 146 | IID_IDirect3DRGBDevice, 6, 4, 63, 0, 0, 0, 0, 147 | }, 148 | { 149 | 235449937, 150 | { 151 | 56, 2, 3301809, 255, 8191, 2047, 255, 152 | 807562, 6237, 117638975, 207, 63, 0, 0, 153 | }, 154 | { 155 | 56, 114, 3301809, 255, 8191, 2047, 255, 156 | 807562, 6237, 117638975, 207, 63, 0, 0, 157 | }, 158 | 1280, 1536, 1, 1, 8192, 8192, 8192, 8192, 16, 159 | -16384.0, -16384.0, 16384.0, 16384.0, 0.0, 160 | 255, 524296, 16777215, 4, 4, 4294967295, 161 | 1.0e+10, IID_IDirect3DHALDevice, 6, 4, 63, 162 | 0, 0, 0, 0, 163 | }, 164 | { 165 | 235515473, 166 | { 167 | 56, 2, 3301809, 255, 8191, 2047, 255, 168 | 807562, 6237, 117638975, 207, 63, 0, 0 169 | }, 170 | { 171 | 56, 114, 3301809, 255, 8191, 2047, 255, 172 | 807562, 6237, 117638975, 207, 63, 0, 0 173 | }, 174 | 1280, 1536, 1, 1, 8192, 8192, 8192, 8192, 16, 175 | -16384.0, -16384.0, 16384.0, 16384.0, 0.0, 176 | 255, 524296, 16777215, 4, 4, 8, 1.0e+10, 177 | IID_IDirect3DTnLHalDevice, 6, 4, 379, 0, 0, 0, 0, 178 | }, 179 | }; 180 | 181 | 182 | CHAR* g_lpszDeviceDescs[] = 183 | { 184 | "Microsoft Direct3D RGB Software Emulation", 185 | "Microsoft Direct3D Hardware acceleration through Direct3D HAL", 186 | "Microsoft Direct3D Hardware Transform and Lighting acceleration capable device" 187 | }; 188 | 189 | CHAR* g_lpszDeviceNames[] = { 190 | "RGB Emulation", 191 | "Direct3D HAL", 192 | "Direct3D T&L HAL" 193 | }; 194 | 195 | UINT g_uDeviceCount = ARRAYSIZE(g_asDeviceDescs); 196 | 197 | 198 | DDPIXELFORMAT g_asTextureFormats[] = 199 | { 200 | g_pf16_565, 201 | g_pf16_555, 202 | g_pf16_1555, 203 | g_pf16_4444, 204 | {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32, 16711680, 65280, 255, 0}, 205 | {sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0, 32, 16711680, 65280, 255, 4278190080}, 206 | {sizeof(DDPIXELFORMAT), DDPF_LUMINANCE | DDPF_ALPHAPIXELS, 0, 16, 255, 0, 0, 65280}, 207 | {sizeof(DDPIXELFORMAT), DDPF_LUMINANCE, 0, 8, 255, 0, 0, 0}, 208 | {sizeof(DDPIXELFORMAT), DDPF_LUMINANCE | DDPF_ALPHAPIXELS, 0, 8, 15, 0, 0, 240}, 209 | {sizeof(DDPIXELFORMAT), DDPF_ALPHA, 0, 8, 0, 0, 0, 0}, 210 | g_pf16_v8u8, 211 | {sizeof(DDPIXELFORMAT), DDPF_BUMPDUDV | DDPF_BUMPLUMINANCE, 0, 16, 31, 992, 64512, 0}, 212 | {sizeof(DDPIXELFORMAT), DDPF_FOURCC, 844715353}, 213 | {sizeof(DDPIXELFORMAT), DDPF_FOURCC, 1498831189}, 214 | {sizeof(DDPIXELFORMAT), DDPF_FOURCC, 1448433985}, 215 | {sizeof(DDPIXELFORMAT), DDPF_FOURCC, 827611204}, 216 | {sizeof(DDPIXELFORMAT), DDPF_FOURCC, 844388420}, 217 | {sizeof(DDPIXELFORMAT), DDPF_FOURCC, 861165636}, 218 | {sizeof(DDPIXELFORMAT), DDPF_FOURCC, 877942852}, 219 | {sizeof(DDPIXELFORMAT), DDPF_FOURCC, 894720068}, 220 | }; 221 | UINT g_uTextureFormatsCount = ARRAYSIZE(g_asTextureFormats); 222 | 223 | 224 | DDPIXELFORMAT g_asZBufferFormats[] = 225 | { 226 | g_pf16_depth, 227 | {sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0, 32, 0, 16777215, 0, 0}, 228 | {sizeof(DDPIXELFORMAT), DDPF_ZBUFFER | DDPF_STENCILBUFFER, 0, 32, 8, 65535, 4278190080, 0}, 229 | {sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0, 24, 0, 16777215, 0, 0}, 230 | }; 231 | 232 | UINT g_uZBufferFormatsCount = ARRAYSIZE(g_asZBufferFormats); 233 | 234 | 235 | DDPIXELFORMAT g_asD2GIPF_To_DD7PF[] = 236 | { 237 | g_pf8_Pal, 238 | g_pf16_565, 239 | g_pf16_1555, 240 | g_pf16_4444, 241 | g_pf16_v8u8, 242 | g_pf16_depth, 243 | g_pf16_555, 244 | }; 245 | 246 | 247 | D3D9::D3DFORMAT g_asD2GIPF_To_D3D9PF[] = 248 | { 249 | D3D9::D3DFMT_P8, 250 | D3D9::D3DFMT_R5G6B5, 251 | D3D9::D3DFMT_A1R5G5B5, 252 | D3D9::D3DFMT_A4R4G4B4, 253 | D3D9::D3DFMT_V8U8, 254 | D3D9::D3DFMT_D16, 255 | D3D9::D3DFMT_A1R5G5B5, 256 | }; 257 | 258 | 259 | D2GIPIXELFORMAT DD7PF_To_D2GIPF(D3D7::DDPIXELFORMAT* ppf) 260 | { 261 | if (*ppf == g_pf8_Pal) 262 | return D2GIPF_8_PAL; 263 | else if (*ppf == g_pf16_565) 264 | return D2GIPF_16_565; 265 | else if (*ppf == g_pf16_1555) 266 | return D2GIPF_16_1555; 267 | else if (*ppf == g_pf16_4444) 268 | return D2GIPF_16_4444; 269 | else if (*ppf == g_pf16_v8u8) 270 | return D2GIPF_16_V8U8; 271 | else if (*ppf == g_pf16_depth) 272 | return D2GIPF_16_DEPTH; 273 | else if (*ppf == g_pf16_555) 274 | return D2GIPF_16_555; 275 | 276 | return D2GIPF_UNKNOWN; 277 | } 278 | 279 | 280 | BOOL IsStdDisplayMode(DWORD dwWidth, DWORD dwHeight) 281 | { 282 | INT i; 283 | 284 | for (i = 0; i < (INT)g_uStdDisplayModesCount; i++) 285 | { 286 | DDSURFACEDESC2* pDesc = g_asStdDisplayModes + i; 287 | 288 | if (pDesc->dwWidth == dwWidth && pDesc->dwHeight == dwHeight) 289 | return TRUE; 290 | } 291 | 292 | return FALSE; 293 | } 294 | -------------------------------------------------------------------------------- /D2GI/D2GI.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {5111b702-4ed8-45b3-a688-718300a07769} 18 | 19 | 20 | {a416cc5f-0267-4d35-94e9-e2f567752d5d} 21 | 22 | 23 | {22f3ddd1-7596-470a-a858-a4597a8cb42d} 24 | 25 | 26 | {d9eef7fa-b360-4fb3-8a56-b112a46f1fc4} 27 | 28 | 29 | {0f4a5234-e205-4cec-ba8e-b258a3f7cbf6} 30 | 31 | 32 | {1f5536a1-1470-43f7-9cb7-50819d4a39fc} 33 | 34 | 35 | {c33bf210-2946-4139-a99d-5e76a5b25fff} 36 | 37 | 38 | {0ee434d0-487f-4979-8df3-435bd80533e6} 39 | 40 | 41 | {58f671c2-31ab-4b74-8aec-5f4909d01d0b} 42 | 43 | 44 | {42d854fc-89f3-44f7-9a17-92de53608636} 45 | 46 | 47 | {9369cae6-08cd-4e67-9b15-b80bc184b70c} 48 | 49 | 50 | {8a3b8274-abc7-40e3-8c0e-ce04aac64cd0} 51 | 52 | 53 | 54 | 55 | Файлы ресурсов 56 | 57 | 58 | 59 | Исходные файлы\d2gi 60 | 61 | 62 | Исходные файлы\d2gi 63 | 64 | 65 | 66 | 67 | Исходные файлы\d2gi 68 | 69 | 70 | Исходные файлы\d3d 71 | 72 | 73 | Исходные файлы\ddraw 74 | 75 | 76 | Исходные файлы\d3d 77 | 78 | 79 | Исходные файлы\d2gi 80 | 81 | 82 | Исходные файлы\ddraw 83 | 84 | 85 | Исходные файлы\d2gi 86 | 87 | 88 | Исходные файлы\d2gi 89 | 90 | 91 | Исходные файлы\d2gi 92 | 93 | 94 | Исходные файлы\d2gi 95 | 96 | 97 | Исходные файлы\d2gi 98 | 99 | 100 | Исходные файлы\d2gi 101 | 102 | 103 | Исходные файлы\ddraw 104 | 105 | 106 | Исходные файлы\d2gi 107 | 108 | 109 | Исходные файлы\d2gi 110 | 111 | 112 | Исходные файлы\d2gi 113 | 114 | 115 | Исходные файлы\d2gi\surfaces 116 | 117 | 118 | Исходные файлы\d2gi\surfaces 119 | 120 | 121 | Исходные файлы\d2gi\surfaces 122 | 123 | 124 | Исходные файлы\d2gi\surfaces 125 | 126 | 127 | Исходные файлы\d2gi\surfaces 128 | 129 | 130 | Исходные файлы\d2gi\surfaces 131 | 132 | 133 | Исходные файлы\d2gi\surfaces 134 | 135 | 136 | Исходные файлы\d2gi\surfaces 137 | 138 | 139 | Исходные файлы\common 140 | 141 | 142 | Исходные файлы\common 143 | 144 | 145 | Исходные файлы\common 146 | 147 | 148 | Исходные файлы 149 | 150 | 151 | Исходные файлы\d2gi 152 | 153 | 154 | Исходные файлы\d2gi\g-streaming 155 | 156 | 157 | Исходные файлы\d2gi\g-streaming 158 | 159 | 160 | Исходные файлы\d2gi\g-streaming 161 | 162 | 163 | Исходные файлы\d2gi 164 | 165 | 166 | 167 | 168 | Файлы заголовков\d2gi 169 | 170 | 171 | Файлы заголовков\d3d 172 | 173 | 174 | Файлы заголовков\d3d 175 | 176 | 177 | Файлы заголовков\ddraw 178 | 179 | 180 | Файлы заголовков\d2gi 181 | 182 | 183 | Файлы заголовков\ddraw 184 | 185 | 186 | Файлы заголовков\d2gi 187 | 188 | 189 | Файлы заголовков\d2gi 190 | 191 | 192 | Файлы заголовков\d2gi 193 | 194 | 195 | Файлы заголовков\d2gi 196 | 197 | 198 | Файлы заголовков\d2gi 199 | 200 | 201 | Файлы заголовков\d2gi 202 | 203 | 204 | Файлы заголовков\ddraw 205 | 206 | 207 | Файлы заголовков\d2gi 208 | 209 | 210 | Файлы заголовков\d2gi 211 | 212 | 213 | Файлы заголовков\d2gi 214 | 215 | 216 | Файлы заголовков\d2gi\surfaces 217 | 218 | 219 | Файлы заголовков\d2gi\surfaces 220 | 221 | 222 | Файлы заголовков\d2gi\surfaces 223 | 224 | 225 | Файлы заголовков\d2gi\surfaces 226 | 227 | 228 | Файлы заголовков\d2gi\surfaces 229 | 230 | 231 | Файлы заголовков\d2gi\surfaces 232 | 233 | 234 | Файлы заголовков\d2gi\surfaces 235 | 236 | 237 | Файлы заголовков\d2gi\surfaces 238 | 239 | 240 | Файлы заголовков\common 241 | 242 | 243 | Файлы заголовков\common 244 | 245 | 246 | Файлы заголовков\common 247 | 248 | 249 | Файлы заголовков\common 250 | 251 | 252 | Файлы заголовков\common 253 | 254 | 255 | Файлы заголовков\common 256 | 257 | 258 | Файлы заголовков\common 259 | 260 | 261 | Файлы заголовков\common 262 | 263 | 264 | Файлы заголовков\d2gi 265 | 266 | 267 | Файлы заголовков\d2gi\g-streaming 268 | 269 | 270 | Файлы заголовков\d2gi\g-streaming 271 | 272 | 273 | Файлы заголовков\d2gi\g-streaming 274 | 275 | 276 | Файлы заголовков\d2gi 277 | 278 | 279 | Файлы заголовков\d2gi 280 | 281 | 282 | Файлы заголовков\d2gi 283 | 284 | 285 | -------------------------------------------------------------------------------- /D2GI/D2GI.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {D32A70F2-AADF-4E5B-B11B-D78C75EC98B4} 24 | D2GI 25 | 10.0 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v142 32 | Unicode 33 | 34 | 35 | DynamicLibrary 36 | false 37 | v142 38 | true 39 | Unicode 40 | 41 | 42 | Application 43 | true 44 | v142 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v142 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | ddraw 77 | .dll 78 | $(DXSDK_DIR)\Include\;$(IncludePath) 79 | $(D2DIR) 80 | $(DXSDK_DIR)\Lib\$(PlatformTarget);$(LibraryPath) 81 | 82 | 83 | ddraw 84 | .dll 85 | $(DXSDK_DIR)\Include\;$(IncludePath) 86 | $(D2DIR) 87 | $(DXSDK_DIR)\Lib\$(PlatformTarget);$(LibraryPath) 88 | 89 | 90 | 91 | Level3 92 | Disabled 93 | false 94 | false 95 | MultiThreadedDebug 96 | _CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;_WINDLL;%(PreprocessorDefinitions) 97 | 98 | 99 | Console 100 | d2gi.def 101 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 102 | 103 | 104 | "$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" /T vs_3_0 /Vn g_pBlitterVS /Fh "$(ProjectDir)src\d2gi\d2gi_blitter_vs.h" "$(ProjectDir)src\d2gi\d2gi_blitter_vs.hlsl" 105 | "$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" /T ps_3_0 /Vn g_pBlitterPS /Fh "$(ProjectDir)src\d2gi\d2gi_blitter_ps.h" "$(ProjectDir)src\d2gi\d2gi_blitter_ps.hlsl" 106 | call echo Shaders compiled. 107 | 108 | 109 | 110 | 111 | Level3 112 | Disabled 113 | true 114 | true 115 | 116 | 117 | Console 118 | d2gi.def 119 | 120 | 121 | 122 | 123 | Level3 124 | MaxSpeed 125 | true 126 | true 127 | false 128 | false 129 | MultiThreaded 130 | _CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 131 | 132 | 133 | Console 134 | true 135 | true 136 | d2gi.def 137 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 138 | 139 | 140 | "$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" /T vs_3_0 /Vn g_pBlitterVS /Fh "$(ProjectDir)src\d2gi\d2gi_blitter_vs.h" "$(ProjectDir)src\d2gi\d2gi_blitter_vs.hlsl" 141 | "$(DXSDK_DIR)Utilities\bin\x86\fxc.exe" /T ps_3_0 /Vn g_pBlitterPS /Fh "$(ProjectDir)src\d2gi\d2gi_blitter_ps.h" "$(ProjectDir)src\d2gi\d2gi_blitter_ps.hlsl" 142 | call echo Shaders compiled. 143 | 144 | 145 | 146 | 147 | Level3 148 | MaxSpeed 149 | true 150 | true 151 | true 152 | true 153 | 154 | 155 | Console 156 | true 157 | true 158 | d2gi.def 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | false 179 | false 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | Compute 247 | 4.0 248 | Compute 249 | 4.0 250 | Compute 251 | 4.0 252 | Compute 253 | 4.0 254 | Document 255 | 256 | 257 | Compute 258 | 4.0 259 | Compute 260 | 4.0 261 | Compute 262 | 4.0 263 | Compute 264 | 4.0 265 | Document 266 | 267 | 268 | 269 | 270 | -------------------------------------------------------------------------------- /D2GI/src/d2gi/d2gi.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../common/common.h" 3 | #include "../common/utils.h" 4 | #include "../common/m3x4.h" 5 | #include "../common/frect.h" 6 | #include "../common/logger.h" 7 | #include "../common/dir.h" 8 | 9 | #include "d2gi.h" 10 | #include "d2gi_ddraw.h" 11 | #include "d2gi_prim_flip_surf.h" 12 | #include "d2gi_backbuf_surf.h" 13 | #include "d2gi_blitter.h" 14 | #include "d2gi_prim_single_surf.h" 15 | #include "d2gi_sysmem_surf.h" 16 | #include "d2gi_texture.h" 17 | #include "d2gi_strided_renderer.h" 18 | #include "d2gi_config.h" 19 | 20 | 21 | D2GI::D2GI() 22 | { 23 | m_hD3D9Lib = NULL; 24 | m_pD3D9 = NULL; 25 | m_pDev = NULL; 26 | m_pBackBufferCopy = NULL; 27 | m_pBackBufferCopySurf = NULL; 28 | m_pfnOriginalWndProc = NULL; 29 | 30 | m_eRenderState = RS_UNKNOWN; 31 | m_bSceneBegun = FALSE; 32 | m_bColorKeyEnabled = FALSE; 33 | 34 | ZeroMemory(m_lpCurrentTextures, sizeof(m_lpCurrentTextures)); 35 | 36 | m_pClearRects = new D3D9RECTVector(); 37 | m_p2DBuffer = new ByteBuffer(); 38 | 39 | m_pDirectDrawProxy = new D2GIDirectDraw(this); 40 | m_pBlitter = new D2GIBlitter(this); 41 | m_pStridedRenderer = new D2GIStridedPrimitiveRenderer(this); 42 | 43 | LoadD3D9Library(); 44 | } 45 | 46 | 47 | D2GI::~D2GI() 48 | { 49 | ReleaseResources(); 50 | 51 | DetachWndProc(); 52 | DEL(m_pStridedRenderer); 53 | DEL(m_pBlitter); 54 | DEL(m_pClearRects); 55 | 56 | RELEASE(m_pBackBufferCopySurf); 57 | RELEASE(m_pBackBufferCopy); 58 | RELEASE(m_pDev); 59 | RELEASE(m_pD3D9); 60 | FreeLibrary(m_hD3D9Lib); 61 | } 62 | 63 | 64 | VOID D2GI::OnDirectDrawReleased() 65 | { 66 | delete this; 67 | } 68 | 69 | 70 | VOID D2GI::LoadD3D9Library() 71 | { 72 | typedef D3D9::IDirect3D9* (WINAPI* DIRECT3DCREATE9)(UINT); 73 | 74 | TCHAR szPath[MAX_PATH]; 75 | DIRECT3DCREATE9 pfnDirect3DCreate9; 76 | 77 | _tcscpy(szPath, Directory::GetSysDirectory()); 78 | _tcscat(szPath, TEXT("\\d3d9.dll")); 79 | 80 | m_hD3D9Lib = LoadLibrary(szPath); 81 | if (m_hD3D9Lib == NULL) 82 | Logger::Error(TEXT("Failed to load D3D9 library")); 83 | 84 | pfnDirect3DCreate9 = (DIRECT3DCREATE9)GetProcAddress(m_hD3D9Lib, "Direct3DCreate9"); 85 | if (pfnDirect3DCreate9 == NULL) 86 | Logger::Error(TEXT("Failed to get Direct3DCreate9 address")); 87 | 88 | m_pD3D9 = pfnDirect3DCreate9(D3D_SDK_VERSION); 89 | if (m_pD3D9 == NULL) 90 | Logger::Error(TEXT("Failed to obtain IDirect3D9 interface")); 91 | } 92 | 93 | 94 | VOID D2GI::OnCooperativeLevelSet(HWND hWnd, DWORD dwFlags) 95 | { 96 | m_hWnd = hWnd; 97 | 98 | Logger::SetHWND(hWnd); 99 | AttachWndProc(); 100 | SetupWindow(); 101 | } 102 | 103 | 104 | VOID D2GI::OnDisplayModeSet(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwFlags) 105 | { 106 | m_dwOriginalWidth = dwWidth; 107 | m_dwOriginalHeight = dwHeight; 108 | m_dwOriginalBPP = dwBPP; 109 | 110 | ResetD3D9Device(); 111 | 112 | m_fWidthScale = (FLOAT)m_dwForcedWidth / (FLOAT)m_dwOriginalWidth; 113 | m_fHeightScale = (FLOAT)m_dwForcedHeight / (FLOAT)m_dwOriginalHeight; 114 | m_fAspectRatioScale = ((FLOAT)m_dwForcedWidth / (FLOAT)m_dwForcedHeight); 115 | m_fAspectRatioScale /= ((FLOAT)m_dwOriginalWidth / (FLOAT)m_dwOriginalHeight); 116 | } 117 | 118 | 119 | VOID D2GI::ReleaseResources() 120 | { 121 | m_pDirectDrawProxy->ReleaseResources(); 122 | m_pBlitter->ReleaseResource(); 123 | m_pStridedRenderer->ReleaseResource(); 124 | } 125 | 126 | 127 | VOID D2GI::LoadResources() 128 | { 129 | m_pDirectDrawProxy->LoadResources(); 130 | m_pBlitter->LoadResource(); 131 | m_pStridedRenderer->LoadResource(); 132 | } 133 | 134 | 135 | VOID D2GI::ResetD3D9Device() 136 | { 137 | D3D9::D3DPRESENT_PARAMETERS sParams; 138 | 139 | if (m_pDev != NULL) 140 | { 141 | while (m_pDev->TestCooperativeLevel() == D3DERR_DEVICELOST) 142 | Sleep(50); 143 | } 144 | 145 | ReleaseResources(); 146 | RELEASE(m_pBackBufferCopySurf); 147 | RELEASE(m_pBackBufferCopy); 148 | 149 | ZeroMemory(&sParams, sizeof(sParams)); 150 | sParams.AutoDepthStencilFormat = D3D9::D3DFMT_D24X8; 151 | sParams.EnableAutoDepthStencil = TRUE; 152 | sParams.BackBufferCount = 1; 153 | sParams.BackBufferWidth = m_dwForcedWidth; 154 | sParams.BackBufferHeight = m_dwForcedHeight; 155 | sParams.BackBufferFormat = D3D9::D3DFMT_X8R8G8B8; 156 | sParams.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 157 | sParams.SwapEffect = D3D9::D3DSWAPEFFECT_FLIP; 158 | sParams.Windowed = TRUE; 159 | sParams.PresentationInterval = 160 | D2GIConfig::VSyncEnabled() ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; 161 | 162 | if (D2GIConfig::GetWindowMode() == WMODE_FULLSCREEN) 163 | { 164 | D3D9::D3DDISPLAYMODE sDisplayMode; 165 | UINT uModeID, uModeCount; 166 | 167 | uModeCount = m_pD3D9->GetAdapterModeCount(D3DADAPTER_DEFAULT, sParams.BackBufferFormat); 168 | for (uModeID = 0; uModeID < uModeCount; uModeID++) 169 | { 170 | if (SUCCEEDED(m_pD3D9->EnumAdapterModes( 171 | D3DADAPTER_DEFAULT, sParams.BackBufferFormat, uModeID, &sDisplayMode))) 172 | { 173 | if (sDisplayMode.Width == m_dwForcedWidth 174 | && sDisplayMode.Height == m_dwForcedHeight) 175 | { 176 | sParams.Windowed = FALSE; 177 | sParams.FullScreen_RefreshRateInHz = sDisplayMode.RefreshRate; 178 | break; 179 | } 180 | } 181 | } 182 | 183 | if (sParams.Windowed) 184 | { 185 | Logger::Warning( 186 | TEXT("Can't set fullscreen mode %ix%i, display mode not found"), 187 | m_dwForcedWidth, m_dwForcedHeight); 188 | } 189 | } 190 | 191 | 192 | if (m_pDev == NULL) 193 | { 194 | if (FAILED(m_pD3D9->CreateDevice(D3DADAPTER_DEFAULT, D3D9::D3DDEVTYPE_HAL, m_hWnd, 195 | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, 196 | &sParams, &m_pDev))) 197 | Logger::Error(TEXT("Failed to create D3D9 device")); 198 | } 199 | else 200 | { 201 | HRESULT hResetResult; 202 | 203 | while ((hResetResult = m_pDev->Reset(&sParams)) == D3DERR_DEVICELOST) 204 | Sleep(50); 205 | 206 | if (FAILED(hResetResult)) 207 | Logger::Error(TEXT("Failed to reset D3D9 device")); 208 | } 209 | 210 | Logger::Log( 211 | TEXT("Working on %ix%i mode (fullscreen: %s)"), 212 | sParams.BackBufferWidth, sParams.BackBufferHeight, 213 | sParams.Windowed ? TEXT("off") : TEXT("on")); 214 | 215 | if (FAILED(m_pDev->CreateTexture(m_dwForcedWidth, m_dwOriginalHeight, 1, D3DUSAGE_RENDERTARGET, 216 | D3D9::D3DFMT_A8R8G8B8, D3D9::D3DPOOL_DEFAULT, &m_pBackBufferCopy, NULL))) 217 | Logger::Error(TEXT("Failed to create backbuffer copy texture")); 218 | 219 | if (FAILED(m_pBackBufferCopy->GetSurfaceLevel(0, &m_pBackBufferCopySurf))) 220 | Logger::Error(TEXT("Failed to get backbuffer copy surface")); 221 | 222 | LoadResources(); 223 | } 224 | 225 | 226 | VOID D2GI::OnViewportSet(D3D7::LPD3DVIEWPORT7 pVP) 227 | { 228 | D3D9::D3DVIEWPORT9 sD3D9Viewport; 229 | FRECT frtVP, frtScaledVP; 230 | 231 | frtVP = FRECT((FLOAT)pVP->dwX, (FLOAT)pVP->dwY, 232 | (FLOAT)(pVP->dwX + pVP->dwWidth), (FLOAT)(pVP->dwY + pVP->dwHeight)); 233 | ScaleFRect(&frtVP, &frtScaledVP); 234 | 235 | // ugly piece of shit 236 | if (pVP->dwX != 0 && pVP->dwY != 0 237 | && pVP->dwWidth != m_dwOriginalWidth && pVP->dwHeight != m_dwOriginalHeight) 238 | { 239 | frtScaledVP.fLeft = max(0.0f, floorf(frtScaledVP.fLeft - 0.5f)); 240 | frtScaledVP.fTop = max(0.0f, floorf(frtScaledVP.fTop - 0.5f)); 241 | frtScaledVP.fRight = min((FLOAT)m_dwForcedWidth, ceilf(frtScaledVP.fRight + 0.5f)); 242 | frtScaledVP.fBottom = min((FLOAT)m_dwForcedWidth, ceilf(frtScaledVP.fBottom + 0.5f)); 243 | } 244 | 245 | sD3D9Viewport.X = (DWORD)frtScaledVP.fLeft; 246 | sD3D9Viewport.Y = (DWORD)frtScaledVP.fTop; 247 | sD3D9Viewport.Width = (DWORD)(frtScaledVP.GetWidth()); 248 | sD3D9Viewport.Height = (DWORD)(frtScaledVP.GetHeight()); 249 | sD3D9Viewport.MinZ = pVP->dvMinZ; 250 | sD3D9Viewport.MaxZ = pVP->dvMaxZ; 251 | m_pDev->SetViewport(&sD3D9Viewport); 252 | } 253 | 254 | 255 | VOID D2GI::OnBackBufferLock(BOOL bRead) 256 | { 257 | if(bRead) 258 | { 259 | D3D9::IDirect3DSurface9* pRT; 260 | D2GIBackBufferSurface* pBackBuf; 261 | 262 | if (!m_bSceneBegun) 263 | m_pDev->BeginScene(); 264 | 265 | pBackBuf = m_pDirectDrawProxy->GetPrimaryFlippableSurface()->GetBackBufferSurface(); 266 | 267 | m_pDev->GetRenderTarget(0, &pRT); 268 | m_pDev->StretchRect(pRT, NULL, m_pBackBufferCopySurf, NULL, D3D9::D3DTEXF_LINEAR); 269 | m_pBlitter->Blit(pBackBuf->GetD3D9ReadingSurface(), NULL, m_pBackBufferCopy, NULL, FALSE); 270 | pRT->Release(); 271 | 272 | if (!m_bSceneBegun) 273 | m_pDev->EndScene(); 274 | }else 275 | m_eRenderState = RS_BACKBUFFER_STREAMING; 276 | } 277 | 278 | 279 | VOID D2GI::OnFlip() 280 | { 281 | if (m_eRenderState == RS_BACKBUFFER_STREAMING) 282 | { 283 | D2GIPrimaryFlippableSurface* pPrimSurf = m_pDirectDrawProxy->GetPrimaryFlippableSurface(); 284 | D3D9::IDirect3DSurface9* pSurf = pPrimSurf->GetBackBufferSurface()->GetD3D9StreamingSurface(); 285 | D3D9::IDirect3DSurface9* pRT; 286 | 287 | m_pDev->GetRenderTarget(0, &pRT); 288 | m_pDev->StretchRect(pSurf, NULL, pRT, NULL, D3D9::D3DTEXF_LINEAR); 289 | pRT->Release(); 290 | 291 | Present(); 292 | } 293 | else if (m_eRenderState == RS_BACKBUFFER_BLITTING || m_eRenderState == RS_3D_RENDERING) 294 | Present(); 295 | } 296 | 297 | 298 | VOID D2GI::OnSysMemSurfaceBltOnPrimarySingle(D2GISystemMemorySurface* pSrc, RECT* pSrcRT, D2GIPrimarySingleSurface* pDst, RECT* pDstRT) 299 | { 300 | D3D9::IDirect3DSurface9* pRT; 301 | 302 | m_eRenderState = RS_PRIMARY_SURFACE_BLITTING; 303 | 304 | if (pDst->GetBPP() == 8) 305 | { 306 | RECT sScaledRect; 307 | 308 | ScaleRect(pDstRT, &sScaledRect); 309 | 310 | pSrc->UpdateWithPalette(pDst->GetPalette()); 311 | m_pDev->GetRenderTarget(0, &pRT); 312 | m_pDev->StretchRect(pSrc->GetD3D9Surface(), pSrcRT, pRT, &sScaledRect, D3D9::D3DTEXF_LINEAR); 313 | pRT->Release(); 314 | 315 | Present(); 316 | } 317 | } 318 | 319 | 320 | VOID D2GI::OnClear(DWORD dwCount, D3D7::LPD3DRECT pRects, DWORD dwFlags, D3D7::D3DCOLOR col, D3D7::D3DVALUE z, DWORD dwStencil) 321 | { 322 | INT i; 323 | 324 | m_pClearRects->clear(); 325 | 326 | for (i = 0; i < (INT)dwCount; i++) 327 | { 328 | D3D9::D3DRECT sRect; 329 | 330 | ScaleD3D9Rect((D3D9::D3DRECT*)pRects + i, &sRect); 331 | m_pClearRects->push_back(sRect); 332 | } 333 | 334 | m_pDev->Clear(dwCount, m_pClearRects->data(), dwFlags, col, z, dwStencil); 335 | } 336 | 337 | 338 | VOID D2GI::OnLightEnable(DWORD i, BOOL bEnable) 339 | { 340 | m_pDev->LightEnable(i, bEnable); 341 | } 342 | 343 | 344 | VOID D2GI::OnSysMemSurfaceBltOnBackBuffer(D2GISystemMemorySurface* pSrc, RECT* pSrcRT, D2GIBackBufferSurface* pDst, RECT* pDstRT) 345 | { 346 | D3D9::IDirect3DSurface9* pRT = NULL; 347 | D3D9::D3DSURFACE_DESC sSrcDesc, sDstDesc; 348 | FRECT frtSrc, frtDst; 349 | FRECT frtScaledDst; 350 | 351 | m_eRenderState = RS_BACKBUFFER_BLITTING; 352 | 353 | m_pDev->GetRenderTarget(0, &pRT); 354 | if(!m_bSceneBegun) 355 | m_pDev->BeginScene(); 356 | 357 | 358 | pSrc->GetD3D9Texture()->GetLevelDesc(0, &sSrcDesc); 359 | pRT->GetDesc(&sDstDesc); 360 | if (pSrcRT != NULL) 361 | frtSrc = FRECT(*pSrcRT); 362 | else 363 | frtSrc = FRECT(0, 0, (FLOAT)sSrcDesc.Width, (FLOAT)sSrcDesc.Height); 364 | 365 | if (pDstRT != NULL) 366 | frtDst = FRECT(*pDstRT); 367 | else 368 | frtDst = FRECT(0, 0, (FLOAT)sDstDesc.Width, (FLOAT)sDstDesc.Height); 369 | 370 | ScaleFRect(&frtDst, &frtScaledDst); 371 | m_pBlitter->Blit(pRT, &frtScaledDst, 372 | pSrc->GetD3D9Texture(), &frtSrc, pSrc->HasColorKeyConversion()); 373 | 374 | if (!m_bSceneBegun) 375 | m_pDev->EndScene(); 376 | 377 | pRT->Release(); 378 | } 379 | 380 | 381 | VOID D2GI::OnSysMemSurfaceBltOnTexture(D2GISystemMemorySurface* pSrc, RECT* pSrcRT, D2GITexture* pDst, RECT* pDstRT) 382 | { 383 | // MULTITHREADED_ACCESS 384 | pDst->CopyFrom((D2GITexture*)pSrc); 385 | } 386 | 387 | 388 | VOID D2GI::OnSceneBegin() 389 | { 390 | m_eRenderState = RS_3D_RENDERING; 391 | BeginScene(); 392 | } 393 | 394 | 395 | VOID D2GI::BeginScene() 396 | { 397 | if (!m_bSceneBegun) 398 | { 399 | m_pDev->BeginScene(); 400 | m_bSceneBegun = TRUE; 401 | } 402 | } 403 | 404 | 405 | VOID D2GI::OnSceneEnd() 406 | { 407 | m_eRenderState = RS_3D_RENDERING; 408 | EndScene(); 409 | } 410 | 411 | 412 | VOID D2GI::EndScene() 413 | { 414 | if (m_bSceneBegun) 415 | { 416 | m_pDev->EndScene(); 417 | m_bSceneBegun = FALSE; 418 | } 419 | } 420 | 421 | 422 | VOID D2GI::OnRenderStateSet(D3D7::D3DRENDERSTATETYPE eState, DWORD dwValue) 423 | { 424 | switch (eState) 425 | { 426 | case D3D7::D3DRENDERSTATE_CULLMODE: 427 | m_pDev->SetRenderState(D3D9::D3DRS_CULLMODE, dwValue); 428 | break; 429 | case D3D7::D3DRENDERSTATE_TEXTUREPERSPECTIVE: 430 | break; 431 | case D3D7::D3DRENDERSTATE_COLORKEYENABLE: 432 | m_bColorKeyEnabled = dwValue; 433 | break; 434 | case D3D7::D3DRENDERSTATE_ZENABLE: 435 | m_pDev->SetRenderState(D3D9::D3DRS_ZENABLE, dwValue); 436 | break; 437 | case D3D7::D3DRENDERSTATE_SHADEMODE: 438 | m_pDev->SetRenderState(D3D9::D3DRS_SHADEMODE, dwValue); 439 | break; 440 | case D3D7::D3DRENDERSTATE_DITHERENABLE: 441 | m_pDev->SetRenderState(D3D9::D3DRS_DITHERENABLE, dwValue); 442 | break; 443 | case D3D7::D3DRENDERSTATE_SRCBLEND: 444 | m_pDev->SetRenderState(D3D9::D3DRS_SRCBLEND, dwValue); 445 | break; 446 | case D3D7::D3DRENDERSTATE_DESTBLEND: 447 | m_pDev->SetRenderState(D3D9::D3DRS_DESTBLEND, dwValue); 448 | break; 449 | case D3D7::D3DRENDERSTATE_ALPHABLENDENABLE: 450 | m_pDev->SetRenderState(D3D9::D3DRS_ALPHABLENDENABLE, dwValue); 451 | break; 452 | case D3D7::D3DRENDERSTATE_SPECULARENABLE: 453 | m_pDev->SetRenderState(D3D9::D3DRS_SPECULARENABLE, dwValue); 454 | break; 455 | case D3D7::D3DRENDERSTATE_COLORVERTEX: 456 | m_pDev->SetRenderState(D3D9::D3DRS_COLORVERTEX, dwValue); 457 | break; 458 | case D3D7::D3DRENDERSTATE_AMBIENTMATERIALSOURCE: 459 | m_pDev->SetRenderState(D3D9::D3DRS_AMBIENTMATERIALSOURCE, dwValue); 460 | break; 461 | case D3D7::D3DRENDERSTATE_SPECULARMATERIALSOURCE: 462 | m_pDev->SetRenderState(D3D9::D3DRS_SPECULARMATERIALSOURCE, dwValue); 463 | break; 464 | case D3D7::D3DRENDERSTATE_EMISSIVEMATERIALSOURCE: 465 | m_pDev->SetRenderState(D3D9::D3DRS_EMISSIVEMATERIALSOURCE, dwValue); 466 | break; 467 | case D3D7::D3DRENDERSTATE_DIFFUSEMATERIALSOURCE: 468 | m_pDev->SetRenderState(D3D9::D3DRS_DIFFUSEMATERIALSOURCE, dwValue); 469 | break; 470 | case D3D7::D3DRENDERSTATE_ALPHATESTENABLE: 471 | m_pDev->SetRenderState(D3D9::D3DRS_ALPHATESTENABLE, dwValue); 472 | break; 473 | case D3D7::D3DRENDERSTATE_FOGENABLE: 474 | m_pDev->SetRenderState(D3D9::D3DRS_FOGENABLE, dwValue); 475 | break; 476 | case D3D7::D3DRENDERSTATE_FOGCOLOR: 477 | m_pDev->SetRenderState(D3D9::D3DRS_FOGCOLOR, dwValue); 478 | break; 479 | case D3D7::D3DRENDERSTATE_FOGVERTEXMODE: 480 | m_pDev->SetRenderState(D3D9::D3DRS_FOGVERTEXMODE, dwValue); 481 | break; 482 | case D3D7::D3DRENDERSTATE_FOGSTART: 483 | m_pDev->SetRenderState(D3D9::D3DRS_FOGSTART, dwValue); 484 | break; 485 | case D3D7::D3DRENDERSTATE_FOGEND: 486 | m_pDev->SetRenderState(D3D9::D3DRS_FOGEND, dwValue); 487 | break; 488 | case D3D7::D3DRENDERSTATE_AMBIENT: 489 | m_pDev->SetRenderState(D3D9::D3DRS_AMBIENT, dwValue); 490 | break; 491 | case D3D7::D3DRENDERSTATE_ZWRITEENABLE: 492 | m_pDev->SetRenderState(D3D9::D3DRS_ZWRITEENABLE, dwValue); 493 | break; 494 | case D3D7::D3DRENDERSTATE_ZFUNC: 495 | m_pDev->SetRenderState(D3D9::D3DRS_ZFUNC, dwValue); 496 | break; 497 | case D3D7::D3DRENDERSTATE_CLIPPING: 498 | m_pDev->SetRenderState(D3D9::D3DRS_CLIPPING, dwValue); 499 | break; 500 | case D3D7::D3DRENDERSTATE_TEXTUREFACTOR: 501 | m_pDev->SetRenderState(D3D9::D3DRS_TEXTUREFACTOR, dwValue); 502 | break; 503 | } 504 | } 505 | 506 | 507 | VOID D2GI::OnTextureStageSet(DWORD i, D3D7::D3DTEXTURESTAGESTATETYPE eState, DWORD dwValue) 508 | { 509 | D3D9::D3DTEXTUREFILTERTYPE aeMagTexFMap[] = 510 | { 511 | D3D9::D3DTEXF_NONE, 512 | D3D9::D3DTEXF_POINT, 513 | D3D9::D3DTEXF_LINEAR, 514 | D3D9::D3DTEXF_PYRAMIDALQUAD, 515 | D3D9::D3DTEXF_GAUSSIANQUAD, 516 | D3D9::D3DTEXF_ANISOTROPIC, 517 | }; 518 | 519 | D3D9::D3DTEXTUREFILTERTYPE aeMinTexFMap[] = 520 | { 521 | D3D9::D3DTEXF_NONE, 522 | D3D9::D3DTEXF_POINT, 523 | D3D9::D3DTEXF_LINEAR, 524 | D3D9::D3DTEXF_ANISOTROPIC, 525 | }; 526 | 527 | D3D9::D3DTEXTUREFILTERTYPE aeMipTexFMap[] = 528 | { 529 | D3D9::D3DTEXF_NONE, 530 | D3D9::D3DTEXF_NONE, 531 | D3D9::D3DTEXF_POINT, 532 | D3D9::D3DTEXF_LINEAR, 533 | }; 534 | 535 | switch (eState) 536 | { 537 | case D3D7::D3DTSS_COLOROP: 538 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_COLOROP, dwValue); 539 | break; 540 | case D3D7::D3DTSS_COLORARG1: 541 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_COLORARG1, dwValue); 542 | break; 543 | case D3D7::D3DTSS_COLORARG2: 544 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_COLORARG2, dwValue); 545 | break; 546 | case D3D7::D3DTSS_ALPHAOP: 547 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_ALPHAOP, dwValue); 548 | break; 549 | case D3D7::D3DTSS_ALPHAARG1: 550 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_ALPHAARG1, dwValue); 551 | break; 552 | case D3D7::D3DTSS_ALPHAARG2: 553 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_ALPHAARG2, dwValue); 554 | break; 555 | case D3D7::D3DTSS_BUMPENVMAT00: 556 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_BUMPENVMAT00, dwValue); 557 | break; 558 | case D3D7::D3DTSS_BUMPENVMAT01: 559 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_BUMPENVMAT01, dwValue); 560 | break; 561 | case D3D7::D3DTSS_BUMPENVMAT10: 562 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_BUMPENVMAT10, dwValue); 563 | break; 564 | case D3D7::D3DTSS_BUMPENVMAT11: 565 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_BUMPENVMAT11, dwValue); 566 | break; 567 | case D3D7::D3DTSS_TEXCOORDINDEX: 568 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_TEXCOORDINDEX, dwValue); 569 | break; 570 | case D3D7::D3DTSS_BUMPENVLSCALE: 571 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_BUMPENVLSCALE, dwValue); 572 | break; 573 | case D3D7::D3DTSS_BUMPENVLOFFSET: 574 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_BUMPENVLOFFSET, dwValue); 575 | break; 576 | case D3D7::D3DTSS_TEXTURETRANSFORMFLAGS: 577 | m_pDev->SetTextureStageState(i, D3D9::D3DTSS_TEXTURETRANSFORMFLAGS, dwValue); 578 | break; 579 | 580 | case D3D7::D3DTSS_ADDRESS: 581 | m_pDev->SetSamplerState(i, D3D9::D3DSAMP_ADDRESSU, dwValue); 582 | m_pDev->SetSamplerState(i, D3D9::D3DSAMP_ADDRESSV, dwValue); 583 | break; 584 | case D3D7::D3DTSS_ADDRESSU: 585 | m_pDev->SetSamplerState(i, D3D9::D3DSAMP_ADDRESSU, dwValue); 586 | break; 587 | case D3D7::D3DTSS_ADDRESSV: 588 | m_pDev->SetSamplerState(i, D3D9::D3DSAMP_ADDRESSV, dwValue); 589 | break; 590 | case D3D7::D3DTSS_BORDERCOLOR: 591 | m_pDev->SetSamplerState(i, D3D9::D3DSAMP_BORDERCOLOR, dwValue); 592 | break; 593 | case D3D7::D3DTSS_MAGFILTER: 594 | m_pDev->SetSamplerState(i, D3D9::D3DSAMP_MAGFILTER, aeMagTexFMap[dwValue]); 595 | break; 596 | case D3D7::D3DTSS_MINFILTER: 597 | m_pDev->SetSamplerState(i, D3D9::D3DSAMP_MINFILTER, aeMinTexFMap[dwValue]); 598 | break; 599 | case D3D7::D3DTSS_MIPFILTER: 600 | m_pDev->SetSamplerState(i, D3D9::D3DSAMP_MIPFILTER, aeMipTexFMap[dwValue]); 601 | break; 602 | case D3D7::D3DTSS_MIPMAPLODBIAS: 603 | m_pDev->SetSamplerState(i, D3D9::D3DSAMP_MIPMAPLODBIAS, dwValue); 604 | break; 605 | case D3D7::D3DTSS_MAXMIPLEVEL: 606 | m_pDev->SetSamplerState(i, D3D9::D3DSAMP_MAXMIPLEVEL, dwValue); 607 | break; 608 | case D3D7::D3DTSS_MAXANISOTROPY: 609 | m_pDev->SetSamplerState(i, D3D9::D3DSAMP_MAXANISOTROPY, dwValue); 610 | break; 611 | } 612 | 613 | } 614 | 615 | 616 | VOID D2GI::OnTextureSet(DWORD i, D2GITexture* pTex) 617 | { 618 | m_lpCurrentTextures[i] = pTex; 619 | 620 | m_pDev->SetTexture(i, pTex == NULL ? NULL : pTex->GetD3D9Texture()); 621 | } 622 | 623 | 624 | BOOL D2GI::OnDeviceValidate(DWORD* pdw) 625 | { 626 | return SUCCEEDED(m_pDev->ValidateDevice(pdw)); 627 | } 628 | 629 | 630 | VOID D2GI::OnTransformSet(D3D7::D3DTRANSFORMSTATETYPE eType, D3D7::D3DMATRIX* pMatrix) 631 | { 632 | switch (eType) 633 | { 634 | case D3D7::D3DTRANSFORMSTATE_WORLD: 635 | m_pDev->SetTransform(D3D9::D3DTS_WORLD, (D3D9::D3DMATRIX*)pMatrix); 636 | break; 637 | case D3D7::D3DTRANSFORMSTATE_WORLD1: 638 | m_pDev->SetTransform(D3D9::D3DTS_WORLD1, (D3D9::D3DMATRIX*)pMatrix); 639 | break; 640 | case D3D7::D3DTRANSFORMSTATE_WORLD2: 641 | m_pDev->SetTransform(D3D9::D3DTS_WORLD2, (D3D9::D3DMATRIX*)pMatrix); 642 | break; 643 | case D3D7::D3DTRANSFORMSTATE_WORLD3: 644 | m_pDev->SetTransform(D3D9::D3DTS_WORLD3, (D3D9::D3DMATRIX*)pMatrix); 645 | break; 646 | default: 647 | m_pDev->SetTransform((D3D9::D3DTRANSFORMSTATETYPE)eType, (D3D9::D3DMATRIX*)pMatrix); 648 | break; 649 | } 650 | } 651 | 652 | 653 | VOID D2GI::OnLightSet(DWORD i, D3D7::LPD3DLIGHT7 pLight) 654 | { 655 | m_pDev->SetLight(i, (D3D9::D3DLIGHT9*)pLight); 656 | } 657 | 658 | 659 | VOID D2GI::OnMaterialSet(D3D7::LPD3DMATERIAL7 pMaterial) 660 | { 661 | m_pDev->SetMaterial((D3D9::D3DMATERIAL9*)pMaterial); 662 | } 663 | 664 | 665 | VOID D2GI::OnClipStatusSet(D3D7::LPD3DCLIPSTATUS pStatus) 666 | { 667 | } 668 | 669 | 670 | VOID D2GI::Present() 671 | { 672 | m_pDev->Present(NULL, NULL, NULL, NULL); 673 | m_pStridedRenderer->OnPresentationFinished(); 674 | 675 | if (FAILED(m_pDev->TestCooperativeLevel())) 676 | ResetD3D9Device(); 677 | } 678 | 679 | 680 | VOID D2GI::OnIndexedPrimitiveStridedDraw( 681 | D3D7::D3DPRIMITIVETYPE pt, DWORD dwFVF, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA pData, 682 | DWORD dwCount, LPWORD pIdx, DWORD dwIdxCount, DWORD dwFlags) 683 | { 684 | DrawPrimitive(pt, dwFVF, TRUE, pData, dwCount, pIdx, dwIdxCount, dwFlags); 685 | } 686 | 687 | 688 | VOID D2GI::OnPrimitiveStridedDraw( 689 | D3D7::D3DPRIMITIVETYPE pt, DWORD dwFVF, D3D7::LPD3DDRAWPRIMITIVESTRIDEDDATA pData, 690 | DWORD dwCount, DWORD dwFlags) 691 | { 692 | DrawPrimitive(pt, dwFVF, TRUE, pData, dwCount, NULL, 0, dwFlags); 693 | } 694 | 695 | 696 | 697 | VOID D2GI::OnPrimitiveDraw(D3D7::D3DPRIMITIVETYPE pt, DWORD dwFVF, LPVOID pVerts, DWORD dwVertCount, DWORD dwFlags) 698 | { 699 | if (dwFVF & D3DFVF_XYZRHW) 700 | { 701 | UINT uStride = CalcFVFStride(dwFVF); 702 | UINT uSize = uStride * dwVertCount; 703 | INT i; 704 | 705 | m_p2DBuffer->clear(); 706 | m_p2DBuffer->insert(m_p2DBuffer->begin(), (BYTE*)pVerts, (BYTE*)pVerts + uSize); 707 | for (i = 0; i < (INT)dwVertCount; i++) 708 | { 709 | FLOAT* pV = (FLOAT*)(m_p2DBuffer->data() + i * uStride); 710 | 711 | pV[0] *= m_fWidthScale; 712 | pV[1] *= m_fHeightScale; 713 | } 714 | pVerts = m_p2DBuffer->data(); 715 | } 716 | 717 | DrawPrimitive(pt, dwFVF, FALSE, pVerts, dwVertCount, NULL, 0, dwFlags); 718 | } 719 | 720 | 721 | VOID D2GI::OnIndexedPrimitiveDraw(D3D7::D3DPRIMITIVETYPE pt, DWORD dwFVF, LPVOID pVerts, DWORD dwVertCount, LPWORD pIdx, DWORD dwIdxCount, DWORD dwFlags) 722 | { 723 | DrawPrimitive(pt, dwFVF, FALSE, pVerts, dwVertCount, pIdx, dwIdxCount, dwFlags); 724 | } 725 | 726 | 727 | BOOL D2GI::OnRenderStateGet(D3D7::D3DRENDERSTATETYPE eState, DWORD* pValue) 728 | { 729 | switch (eState) 730 | { 731 | case D3D7::D3DRENDERSTATE_CULLMODE: 732 | m_pDev->GetRenderState(D3D9::D3DRS_CULLMODE, pValue); 733 | return TRUE; 734 | } 735 | 736 | return FALSE; 737 | } 738 | 739 | 740 | VOID D2GI::OnColorFillOnBackBuffer(DWORD dwColor, RECT* pRect) 741 | { 742 | D3D9::D3DVIEWPORT9 sOriginalViewport, sFillingViewport; 743 | 744 | m_pDev->GetViewport(&sOriginalViewport); 745 | sFillingViewport.X = pRect->left; 746 | sFillingViewport.Y = pRect->top; 747 | sFillingViewport.Width = pRect->right - pRect->left; 748 | sFillingViewport.Height = pRect->bottom - pRect->top; 749 | sFillingViewport.MinZ = 0.0; 750 | sFillingViewport.MaxZ = 1.0f; 751 | 752 | m_pDev->SetViewport(&sFillingViewport); 753 | m_pDev->Clear(0, NULL, D3DCLEAR_TARGET, dwColor, 1.0f, 0); 754 | m_pDev->SetViewport(&sOriginalViewport); 755 | } 756 | 757 | 758 | VOID D2GI::DrawPrimitive(D3D7::D3DPRIMITIVETYPE pt, DWORD dwFVF, BOOL bStrided, VOID* pVertexData, 759 | DWORD dwVertexCount, WORD* pIndexData, DWORD dwIndexCount, DWORD dwFlags) 760 | { 761 | DWORD dwAlphaTestEnable, dwAlphaTestFunc, dwAlphaTestRef; 762 | D2GITexture* pTexture = m_lpCurrentTextures[0]; 763 | 764 | BOOL bEmulateColorKey = (m_bColorKeyEnabled && pTexture != NULL && pTexture->HasColorKeyConversion()); 765 | 766 | 767 | if (bEmulateColorKey) 768 | { 769 | m_pDev->GetRenderState(D3D9::D3DRS_ALPHATESTENABLE, &dwAlphaTestEnable); 770 | m_pDev->GetRenderState(D3D9::D3DRS_ALPHAFUNC, &dwAlphaTestFunc); 771 | m_pDev->GetRenderState(D3D9::D3DRS_ALPHAREF, &dwAlphaTestRef); 772 | m_pDev->SetRenderState(D3D9::D3DRS_ALPHATESTENABLE, TRUE); 773 | m_pDev->SetRenderState(D3D9::D3DRS_ALPHAFUNC, D3D9::D3DCMP_GREATEREQUAL); 774 | m_pDev->SetRenderState(D3D9::D3DRS_ALPHAREF, 0x00000080); 775 | } 776 | 777 | if (bStrided) 778 | { 779 | if (pIndexData != NULL) 780 | { 781 | m_pStridedRenderer->DrawIndexedPrimitiveStrided(pt, dwFVF, 782 | (D3D7::D3DDRAWPRIMITIVESTRIDEDDATA*)pVertexData, dwVertexCount, 783 | pIndexData, dwIndexCount, dwFlags); 784 | } 785 | else 786 | { 787 | m_pStridedRenderer->DrawPrimitiveStrided(pt, dwFVF, 788 | (D3D7::D3DDRAWPRIMITIVESTRIDEDDATA*)pVertexData, dwVertexCount, dwFlags); 789 | } 790 | } 791 | else 792 | { 793 | UINT uVertexStride, uPrimCount; 794 | 795 | uVertexStride = CalcFVFStride(dwFVF); 796 | uPrimCount = CalcPrimitiveCount(pt, (pIndexData != NULL) ? dwIndexCount : dwVertexCount); 797 | 798 | m_pDev->SetFVF(dwFVF); 799 | if (pIndexData != NULL) 800 | { 801 | m_pDev->DrawIndexedPrimitiveUP((D3D9::D3DPRIMITIVETYPE)pt, 0, dwVertexCount, 802 | uPrimCount, pIndexData, D3D9::D3DFMT_INDEX16, pVertexData, uVertexStride); 803 | } 804 | else 805 | { 806 | // TODO: think about this scene begin/end fix 807 | if (!m_bSceneBegun) 808 | m_pDev->BeginScene(); 809 | m_pDev->DrawPrimitiveUP((D3D9::D3DPRIMITIVETYPE)pt, uPrimCount, pVertexData, uVertexStride); 810 | if (!m_bSceneBegun) 811 | m_pDev->EndScene(); 812 | } 813 | } 814 | 815 | if (bEmulateColorKey) 816 | { 817 | m_pDev->SetRenderState(D3D9::D3DRS_ALPHATESTENABLE, dwAlphaTestEnable); 818 | m_pDev->SetRenderState(D3D9::D3DRS_ALPHAFUNC, dwAlphaTestFunc); 819 | m_pDev->SetRenderState(D3D9::D3DRS_ALPHAREF, dwAlphaTestRef); 820 | } 821 | } 822 | 823 | 824 | VOID D2GI::ScaleFRect(FRECT* pSrc, FRECT* pOut) 825 | { 826 | if (pSrc == NULL) 827 | { 828 | pOut->fLeft = pOut->fTop = 0; 829 | pOut->fRight = (FLOAT)m_dwForcedWidth; 830 | pOut->fBottom = (FLOAT)m_dwForcedHeight; 831 | return; 832 | } 833 | 834 | pOut->fLeft = (pSrc->fLeft * m_fWidthScale); 835 | pOut->fTop = (pSrc->fTop * m_fHeightScale); 836 | pOut->fRight = (pSrc->fRight * m_fWidthScale); 837 | pOut->fBottom = (pSrc->fBottom * m_fHeightScale); 838 | } 839 | 840 | 841 | VOID D2GI::ScaleRect(RECT* pSrc, RECT* pOut) 842 | { 843 | if (pSrc == NULL) 844 | { 845 | pOut->left = pOut->top = 0; 846 | pOut->right = m_dwForcedWidth; 847 | pOut->bottom = m_dwForcedHeight; 848 | return; 849 | } 850 | 851 | pOut->left = pSrc->left * m_dwForcedWidth / m_dwOriginalWidth; 852 | pOut->top = pSrc->top * m_dwForcedHeight / m_dwOriginalHeight; 853 | pOut->right = pSrc->right * m_dwForcedWidth / m_dwOriginalWidth; 854 | pOut->bottom = pSrc->bottom * m_dwForcedHeight / m_dwOriginalHeight; 855 | } 856 | 857 | 858 | VOID D2GI::AttachWndProc() 859 | { 860 | if (m_pfnOriginalWndProc != NULL) 861 | return; 862 | 863 | m_pfnOriginalWndProc = (WNDPROC)GetWindowLong(m_hWnd, GWL_WNDPROC); 864 | SetWindowLong(m_hWnd, GWL_WNDPROC, (LONG)WndProc_Static); 865 | SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this); 866 | } 867 | 868 | 869 | VOID D2GI::DetachWndProc() 870 | { 871 | if (m_pfnOriginalWndProc == NULL) 872 | return; 873 | 874 | SetWindowLong(m_hWnd, GWL_WNDPROC, (LONG)m_pfnOriginalWndProc); 875 | SetWindowLong(m_hWnd, GWL_USERDATA, 0); 876 | m_pfnOriginalWndProc = NULL; 877 | } 878 | 879 | 880 | LRESULT D2GI::WndProc_Static(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 881 | { 882 | return ((D2GI*)GetWindowLong(hWnd, GWL_USERDATA))->WndProc(hWnd, uMsg, wParam, lParam); 883 | } 884 | 885 | 886 | LRESULT D2GI::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 887 | { 888 | INT x, y; 889 | 890 | switch (uMsg) 891 | { 892 | case WM_MOUSEMOVE: 893 | case WM_LBUTTONDOWN: 894 | case WM_LBUTTONDBLCLK: 895 | case WM_LBUTTONUP: 896 | case WM_RBUTTONDOWN: 897 | case WM_RBUTTONUP: 898 | case WM_RBUTTONDBLCLK: 899 | case WM_MBUTTONDOWN: 900 | case WM_MBUTTONUP: 901 | case WM_MBUTTONDBLCLK: 902 | x = LOWORD(lParam); 903 | y = HIWORD(lParam); 904 | 905 | x = x * m_dwOriginalWidth / m_dwForcedWidth; 906 | y = y * m_dwOriginalHeight / m_dwForcedHeight; 907 | 908 | lParam = MAKELPARAM(x, y); 909 | break; 910 | case WM_GETMINMAXINFO: 911 | return DefWindowProc(hWnd, uMsg, wParam, lParam); 912 | break; 913 | } 914 | 915 | return CallWindowProc(m_pfnOriginalWndProc, hWnd, uMsg, wParam, lParam); 916 | } 917 | 918 | 919 | VOID D2GI::ScaleD3D9Rect(D3D9::D3DRECT* pSrc, D3D9::D3DRECT* pOut) 920 | { 921 | if (pSrc == NULL) 922 | { 923 | pOut->x1 = pOut->y1 = 0; 924 | pOut->x2 = m_dwForcedWidth; 925 | pOut->y2 = m_dwForcedHeight; 926 | return; 927 | } 928 | 929 | pOut->x1 = pSrc->x1 * m_dwForcedWidth / m_dwOriginalWidth; 930 | pOut->y1 = pSrc->y1 * m_dwForcedHeight / m_dwOriginalHeight; 931 | pOut->x2 = pSrc->x2 * m_dwForcedWidth / m_dwOriginalWidth; 932 | pOut->y2 = pSrc->y2 * m_dwForcedHeight / m_dwOriginalHeight; 933 | } 934 | 935 | 936 | VOID D2GI::OnTransformsSetup(VOID* pThis, MAT3X4* pmView, MAT3X4* pmProj) 937 | { 938 | pmProj->_11 /= m_fAspectRatioScale; 939 | } 940 | 941 | 942 | VOID D2GI::SetupWindow() 943 | { 944 | static DWORD c_adwWinModeToWinStyle[] = 945 | { 946 | WS_VISIBLE | WS_CAPTION | WS_SYSMENU, 947 | WS_VISIBLE | WS_POPUP, 948 | WS_VISIBLE | WS_POPUP, 949 | }; 950 | 951 | DWORD dwWinStyle; 952 | INT nDisplayWidth, nDisplayHeight; 953 | INT nWinX, nWinY, nWinWidth, nWinHeight; 954 | RECT rtClientRect; 955 | 956 | dwWinStyle = c_adwWinModeToWinStyle[D2GIConfig::GetWindowMode()]; 957 | nDisplayWidth = GetSystemMetrics(SM_CXSCREEN); 958 | nDisplayHeight = GetSystemMetrics(SM_CYSCREEN); 959 | nWinWidth = min(nDisplayWidth, (INT)D2GIConfig::GetVideoWidth()); 960 | nWinHeight = min(nDisplayHeight, (INT)D2GIConfig::GetVideoHeight()); 961 | nWinX = (nDisplayWidth - nWinWidth) / 2; 962 | nWinY = (nDisplayHeight - nWinHeight) / 2; 963 | 964 | SetWindowLong(m_hWnd, GWL_STYLE, dwWinStyle); 965 | SetWindowLong(m_hWnd, GWL_EXSTYLE, 0); 966 | SetWindowPos(m_hWnd, HWND_TOP, nWinX, nWinY, nWinWidth, nWinHeight, SWP_DRAWFRAME); 967 | GetClientRect(m_hWnd, &rtClientRect); 968 | 969 | m_dwForcedWidth = rtClientRect.right - rtClientRect.left; 970 | m_dwForcedHeight = rtClientRect.bottom - rtClientRect.top; 971 | } 972 | 973 | 974 | 975 | VOID D2GI::OnDisplayModeEnum(LPVOID pArg, D3D7::LPDDENUMMODESCALLBACK2 pCallback) 976 | { 977 | typedef std::vector DModeContainer; 978 | 979 | INT i, nNum; 980 | DModeContainer descs(g_asStdDisplayModes, g_asStdDisplayModes + g_uStdDisplayModesCount); 981 | D3D9::IDirect3D9* pD3D9 = GetD3D9(); 982 | 983 | nNum = pD3D9->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3D9::D3DFMT_X8R8G8B8); 984 | 985 | for (i = 0; i < nNum; i++) 986 | { 987 | D3D9::D3DDISPLAYMODE sDMode; 988 | D3D7::DDSURFACEDESC2 sDMDesc; 989 | 990 | if (SUCCEEDED(pD3D9->EnumAdapterModes(D3DADAPTER_DEFAULT, D3D9::D3DFMT_X8R8G8B8, i, &sDMode))) 991 | { 992 | if (IsStdDisplayMode(sDMode.Width, sDMode.Height)) 993 | continue; 994 | 995 | ZeroMemory(&sDMDesc, sizeof(sDMDesc)); 996 | sDMDesc.dwSize = sizeof(sDMDesc); 997 | sDMDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_PITCH | DDSD_PIXELFORMAT; 998 | sDMDesc.dwWidth = sDMode.Width; 999 | sDMDesc.dwHeight = sDMode.Height; 1000 | sDMDesc.lPitch = sDMode.Width; 1001 | sDMDesc.ddpfPixelFormat = g_pf8_Pal; 1002 | 1003 | descs.push_back(sDMDesc); 1004 | 1005 | sDMDesc.lPitch = sDMode.Width * sizeof(UINT16); 1006 | sDMDesc.ddpfPixelFormat = g_pf16_565; 1007 | 1008 | descs.push_back(sDMDesc); 1009 | } 1010 | } 1011 | 1012 | for (i = 0; i < (INT)descs.size(); i++) 1013 | if (!pCallback(descs.data() + i, pArg)) 1014 | return; 1015 | } 1016 | --------------------------------------------------------------------------------