1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00
narzoul 0b974e2dd7 Added VertexFixup setting
See issues #164 and #327.
2024-07-01 23:52:25 +02:00

272 lines
9.5 KiB
C++

#pragma once
#include <d3dtypes.h>
#include <d3dumddi.h>
#include <array>
#include <map>
#include <memory>
#include <vector>
#include <Common/BitSet.h>
#include <D3dDdi/ResourceDeleter.h>
const UINT D3DTEXF_NONE = 0;
const UINT D3DTEXF_POINT = 1;
const UINT D3DTEXF_LINEAR = 2;
const UINT D3DTEXF_ANISOTROPIC = 3;
const UINT D3DTEXF_SRGBREAD = 0x10000;
const UINT D3DTEXF_SRGBWRITE = 0x20000;
const UINT D3DTEXF_SRGB = D3DTEXF_SRGBREAD | D3DTEXF_SRGBWRITE;
namespace D3dDdi
{
class Device;
class Resource;
class DeviceState
{
public:
typedef std::array<BOOL, 1> ShaderConstB;
typedef std::array<FLOAT, 4> ShaderConstF;
typedef std::array<INT, 4> ShaderConstI;
struct State
{
D3DDDIARG_SETDEPTHSTENCIL depthStencil;
HANDLE pixelShader;
std::array<UINT, D3DDDIRS_BLENDOPALPHA + 1> renderState;
D3DDDIARG_SETRENDERTARGET renderTarget;
RECT scissorRect;
D3DDDIARG_SETSTREAMSOURCE streamSource;
D3DDDIARG_SETSTREAMSOURCEUM streamSourceUm;
const void* streamSourceUmBuffer;
std::array<HANDLE, 8> textures;
std::array<std::array<UINT, D3DDDITSS_TEXTURECOLORKEYVAL + 1>, 8> textureStageState;
HANDLE vertexShaderDecl;
HANDLE vertexShaderFunc;
D3DDDIARG_VIEWPORTINFO viewport;
D3DDDIARG_WINFO wInfo;
D3DDDIARG_ZRANGE zRange;
};
class TempPixelShaderConst
{
public:
TempPixelShaderConst(DeviceState& state, const D3DDDIARG_SETPIXELSHADERCONST& data, const ShaderConstF* registers);
~TempPixelShaderConst();
private:
DeviceState& m_state;
D3DDDIARG_SETPIXELSHADERCONST m_data;
};
class TempPixelShaderConstB
{
public:
TempPixelShaderConstB(DeviceState& state, const D3DDDIARG_SETPIXELSHADERCONSTB& data, const BOOL* registers);
~TempPixelShaderConstB();
private:
DeviceState& m_state;
D3DDDIARG_SETPIXELSHADERCONSTB m_data;
};
class TempPixelShaderConstI
{
public:
TempPixelShaderConstI(DeviceState& state, const D3DDDIARG_SETPIXELSHADERCONSTI& data, const ShaderConstI* registers);
~TempPixelShaderConstI();
private:
DeviceState& m_state;
D3DDDIARG_SETPIXELSHADERCONSTI m_data;
};
class TempStateLock
{
public:
TempStateLock(DeviceState& state)
: m_state(state)
{
state.m_isLocked = true;
}
~TempStateLock()
{
m_state.m_isLocked = false;
}
private:
DeviceState& m_state;
};
struct VertexDecl
{
std::vector<D3DDDIVERTEXELEMENT> elements;
std::array<UINT, 8> texCoordOffset;
std::array<UINT, 8> texCoordType;
bool isTransformed;
};
struct VertexFixupData
{
ShaderConstF texCoordAdj;
ShaderConstF offset;
ShaderConstF multiplier;
};
DeviceState(Device& device);
HRESULT pfnCreatePixelShader(D3DDDIARG_CREATEPIXELSHADER* data, const UINT* code);
HRESULT pfnCreateVertexShaderDecl(D3DDDIARG_CREATEVERTEXSHADERDECL* data, const D3DDDIVERTEXELEMENT* vertexElements);
HRESULT pfnDeletePixelShader(HANDLE shader);
HRESULT pfnDeleteVertexShaderDecl(HANDLE shader);
HRESULT pfnDeleteVertexShaderFunc(HANDLE shader);
HRESULT pfnSetDepthStencil(const D3DDDIARG_SETDEPTHSTENCIL* data);
HRESULT pfnSetPixelShader(HANDLE shader);
HRESULT pfnSetPixelShaderConst(const D3DDDIARG_SETPIXELSHADERCONST* data, const FLOAT* registers);
HRESULT pfnSetPixelShaderConstB(const D3DDDIARG_SETPIXELSHADERCONSTB* data, const BOOL* registers);
HRESULT pfnSetPixelShaderConstI(const D3DDDIARG_SETPIXELSHADERCONSTI* data, const INT* registers);
HRESULT pfnSetRenderState(const D3DDDIARG_RENDERSTATE* data);
HRESULT pfnSetRenderTarget(const D3DDDIARG_SETRENDERTARGET* data);
HRESULT pfnSetStreamSource(const D3DDDIARG_SETSTREAMSOURCE* data);
HRESULT pfnSetStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM* data, const void* umBuffer);
HRESULT pfnSetTexture(UINT stage, HANDLE texture);
HRESULT pfnSetTextureStageState(const D3DDDIARG_TEXTURESTAGESTATE* data);
HRESULT pfnSetVertexShaderConst(const D3DDDIARG_SETVERTEXSHADERCONST* data, const void* registers);
HRESULT pfnSetVertexShaderConstB(const D3DDDIARG_SETVERTEXSHADERCONSTB* data, const BOOL* registers);
HRESULT pfnSetVertexShaderConstI(const D3DDDIARG_SETVERTEXSHADERCONSTI* data, const INT* registers);
HRESULT pfnSetVertexShaderDecl(HANDLE shader);
HRESULT pfnSetVertexShaderFunc(HANDLE shader);
HRESULT pfnSetViewport(const D3DDDIARG_VIEWPORTINFO* data);
HRESULT pfnSetZRange(const D3DDDIARG_ZRANGE* data);
HRESULT pfnUpdateWInfo(const D3DDDIARG_WINFO* data);
void setSpriteMode(bool spriteMode);
void setTempDepthStencil(const D3DDDIARG_SETDEPTHSTENCIL& depthStencil);
void setTempPixelShader(HANDLE shader);
void setTempRenderState(const D3DDDIARG_RENDERSTATE& renderState);
void setTempRenderTarget(const D3DDDIARG_SETRENDERTARGET& renderTarget);
void setTempStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM& streamSourceUm, const void* umBuffer);
void setTempTexture(UINT stage, HANDLE texture);
void setTempTextureStageState(const D3DDDIARG_TEXTURESTAGESTATE& tss);
void setTempVertexShaderDecl(HANDLE decl);
void setTempViewport(const D3DDDIARG_VIEWPORTINFO& viewport);
void setTempWInfo(const D3DDDIARG_WINFO& wInfo);
void setTempZRange(const D3DDDIARG_ZRANGE& zRange);
void disableTextureClamp(UINT stage);
void flush();
const State& getAppState() const { return m_app; }
const State& getCurrentState() const { return m_current; }
bool getSpriteMode() const { return m_spriteMode; }
Resource* getTextureResource(UINT stage);
UINT getTextureStageCount() const;
const VertexDecl& getVertexDecl() const;
const VertexFixupData& getVertexFixupData() const { return m_vertexFixupData; }
bool isLocked() const { return m_isLocked; }
void onDestroyResource(Resource* resource, HANDLE resourceHandle);
void updateConfig();
void updateStreamSource();
private:
enum ChangedState
{
CS_RENDER_STATE = 1 << 0,
CS_RENDER_TARGET = 1 << 1,
CS_SHADER = 1 << 2,
CS_STREAM_SOURCE = 1 << 3,
CS_TEXTURE_STAGE = 1 << 4,
CS_VERTEX_FIXUP = 1 << 5
};
struct PixelShader
{
std::vector<UINT> tokens;
std::unique_ptr<void, ResourceDeleter> modifiedPixelShader;
UINT textureStageCount;
bool isModified;
};
template <int N>
std::unique_ptr<void, ResourceDeleter> createVertexShader(const BYTE(&code)[N])
{
return createVertexShader(reinterpret_cast<const UINT*>(code), N);
}
std::unique_ptr<void, ResourceDeleter> DeviceState::createVertexShader(const UINT* code, UINT size);
HRESULT deleteShader(HANDLE shader, HANDLE State::* shaderMember,
HRESULT(APIENTRY* origDeleteShaderFunc)(HANDLE, HANDLE));
HANDLE getVsVertexFixup();
bool isColorKeyUsed();
HANDLE mapPixelShader(HANDLE shader);
UINT mapRsValue(D3DDDIRENDERSTATETYPE state, UINT value);
UINT mapTssValue(UINT stage, D3DDDITEXTURESTAGESTATETYPE state, UINT value);
void prepareTextures();
template <typename Data>
void removeResource(HANDLE resource, Data State::* data, HANDLE Data::* resourceMember,
HRESULT(DeviceState::* pfnSetResourceFunc)(const Data*));
template <typename Data>
bool setData(const Data& data, Data& currentData, HRESULT(APIENTRY* origSetData)(HANDLE, const Data*));
bool setShader(HANDLE shader, HANDLE& currentShader, HRESULT(APIENTRY* origSetShaderFunc)(HANDLE, HANDLE));
template <typename SetShaderConstData, typename ShaderConstArray, typename Register>
HRESULT setShaderConst(const SetShaderConstData* data, const Register* registers,
ShaderConstArray& shaderConstArray,
HRESULT(APIENTRY* origSetShaderConstFunc)(HANDLE, const SetShaderConstData*, const Register*));
void setDepthStencil(const D3DDDIARG_SETDEPTHSTENCIL& depthStencil);
void setPixelShader(HANDLE shader);
void setRenderState(const D3DDDIARG_RENDERSTATE& renderState);
void setRenderTarget(const D3DDDIARG_SETRENDERTARGET& renderTarget);
void setScissorRect(const RECT& rect);
void setStreamSource(const D3DDDIARG_SETSTREAMSOURCE& streamSource);
void setStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM& streamSourceUm, const void* umBuffer);
bool setTexture(UINT stage, HANDLE texture);
void setTextureStageState(const D3DDDIARG_TEXTURESTAGESTATE& tss);
void setVertexShaderDecl(HANDLE decl);
void setVertexShaderFunc(HANDLE shader);
bool setViewport(const D3DDDIARG_VIEWPORTINFO& viewport);
void setWInfo(const D3DDDIARG_WINFO& wInfo);
bool setZRange(const D3DDDIARG_ZRANGE& zRange);
void updateRenderStates();
void updateRenderTarget();
void updateShaders();
void updateTextureColorKey(UINT stage);
void updateTextureStages();
void updateVertexFixupData(UINT width, UINT height, float sx, float sy);
void updateVertexFixupShaderConst();
Device& m_device;
State m_app;
State m_current;
std::array<ShaderConstF, 32> m_pixelShaderConst;
std::array<ShaderConstB, 16> m_pixelShaderConstB;
std::array<ShaderConstI, 16> m_pixelShaderConstI;
std::array<ShaderConstF, 256> m_vertexShaderConst;
std::array<ShaderConstB, 16> m_vertexShaderConstB;
std::array<ShaderConstI, 16> m_vertexShaderConstI;
std::map<HANDLE, VertexDecl> m_vertexShaderDecls;
VertexDecl* m_vertexDecl;
UINT m_vertexFixupConfig;
VertexFixupData m_vertexFixupData;
UINT m_changedStates;
UINT m_maxChangedTextureStage;
UINT m_texCoordIndexes;
BitSet<D3DDDIRS_ZENABLE, D3DDDIRS_BLENDOPALPHA> m_changedRenderStates;
std::array<BitSet<D3DDDITSS_TEXTUREMAP, D3DDDITSS_TEXTURECOLORKEYVAL>, 8> m_changedTextureStageStates;
std::map<UINT, std::unique_ptr<void, ResourceDeleter>> m_vsVertexFixups;
std::array<Resource*, 8> m_textureResource;
std::map<HANDLE, PixelShader> m_pixelShaders;
PixelShader* m_pixelShader;
bool m_isLocked;
bool m_spriteMode;
};
}