Move 2D rendering to GPU: part 1

This commit is contained in:
Anders Jenbo 2025-06-15 18:47:19 +02:00
parent e6a005fd33
commit 2ed68c8c26
20 changed files with 746 additions and 365 deletions

View File

@ -61,11 +61,6 @@ void MxDisplaySurface::ClearScreen()
backBuffers = m_videoParam.GetBackBuffers() + 1;
}
MxS32 width = m_videoParam.GetRect().GetWidth();
MxS32 height = m_videoParam.GetRect().GetHeight();
RECT rc = {0, 0, width, height};
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
if (m_ddSurface2->GetSurfaceDesc(&desc) != DD_OK) {
@ -77,9 +72,9 @@ void MxDisplaySurface::ClearScreen()
ddBltFx.dwFillColor = 0;
for (MxS32 i = 0; i < backBuffers; i++) {
if (m_ddSurface2->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddBltFx) == DDERR_SURFACELOST) {
if (m_ddSurface2->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddBltFx) == DDERR_SURFACELOST) {
m_ddSurface2->Restore();
m_ddSurface2->Blt(&rc, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddBltFx);
m_ddSurface2->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddBltFx);
}
if (m_videoParam.Flags().GetFlipSurfaces()) {

View File

@ -6,9 +6,10 @@ add_library(miniwin STATIC EXCLUDE_FROM_ALL
src/windows/windows.cpp
# DDraw
src/ddraw/ddraw.cpp
src/ddraw/ddpalette.cpp
src/ddraw/ddraw.cpp
src/ddraw/ddsurface.cpp
src/ddraw/framebuffer.cpp
# D3DRM
src/d3drm/d3drm.cpp
@ -21,9 +22,9 @@ add_library(miniwin STATIC EXCLUDE_FROM_ALL
src/internal/meshutils.cpp
# D3DRM backends
src/d3drm/backends/software/renderer.cpp
src/d3drm/backends/sdl3gpu/renderer.cpp
src/d3drm/backends/sdl3gpu/shaders/generated/ShaderIndex.cpp
src/d3drm/backends/software/renderer.cpp
)
find_package(OpenGL)

View File

@ -347,7 +347,7 @@ struct IDirect3DRM : virtual public IUnknown {
IDirect3DRMDevice2** outDevice
) = 0;
virtual HRESULT CreateTexture(D3DRMIMAGE* image, IDirect3DRMTexture2** outTexture) = 0;
virtual HRESULT CreateTextureFromSurface(LPDIRECTDRAWSURFACE surface, IDirect3DRMTexture2** outTexture) = 0;
virtual HRESULT CreateTextureFromSurface(IDirectDrawSurface* surface, IDirect3DRMTexture2** outTexture) = 0;
virtual HRESULT CreateMesh(IDirect3DRMMesh** outMesh) = 0;
virtual HRESULT CreateMaterial(D3DVAL power, IDirect3DRMMaterial** outMaterial) = 0;
virtual HRESULT CreateLightRGB(D3DRMLIGHTTYPE type, D3DVAL r, D3DVAL g, D3DVAL b, IDirect3DRMLight** outLight) = 0;

View File

@ -311,10 +311,10 @@ typedef IDirectDrawClipper* LPDIRECTDRAWCLIPPER;
typedef struct IDirectDrawSurface* LPDIRECTDRAWSURFACE;
struct IDirectDrawSurface : virtual public IUnknown {
virtual HRESULT AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface) = 0;
virtual HRESULT AddAttachedSurface(IDirectDrawSurface* lpDDSAttachedSurface) = 0;
virtual HRESULT Blt(
LPRECT lpDestRect,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFlags dwFlags,
LPDDBLTFX lpDDBltFx
@ -322,21 +322,21 @@ struct IDirectDrawSurface : virtual public IUnknown {
virtual HRESULT BltFast(
DWORD dwX,
DWORD dwY,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFastFlags dwTrans
) = 0;
virtual HRESULT Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) = 0;
virtual HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) = 0;
virtual HRESULT Flip(IDirectDrawSurface* lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) = 0;
virtual HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, IDirectDrawSurface** lplpDDAttachedSurface) = 0;
virtual HRESULT GetDC(HDC* lphDC) = 0;
virtual HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) = 0;
virtual HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) = 0;
virtual HRESULT GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) = 0;
virtual HRESULT GetSurfaceDesc(DDSURFACEDESC* lpDDSurfaceDesc) = 0;
virtual HRESULT IsLost() = 0;
virtual HRESULT Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) = 0;
virtual HRESULT Lock(LPRECT lpDestRect, DDSURFACEDESC* lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) = 0;
virtual HRESULT ReleaseDC(HDC hDC) = 0;
virtual HRESULT Restore() = 0;
virtual HRESULT SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) = 0;
virtual HRESULT SetClipper(IDirectDrawClipper* lpDDClipper) = 0;
virtual HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) = 0;
virtual HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) = 0;
virtual HRESULT Unlock(LPVOID lpSurfaceData) = 0;
@ -345,9 +345,9 @@ struct IDirectDrawSurface : virtual public IUnknown {
struct IDirectDrawSurface3 : public IDirectDrawSurface {};
typedef IDirectDrawSurface3* LPDIRECTDRAWSURFACE3;
typedef HRESULT (*LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID);
typedef HRESULT (*LPDDENUMMODESCALLBACK)(DDSURFACEDESC*, LPVOID);
struct IDirectDraw : virtual public IUnknown {
virtual HRESULT CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) = 0;
virtual HRESULT CreateClipper(DWORD dwFlags, IDirectDrawClipper** lplpDDClipper, IUnknown* pUnkOuter) = 0;
virtual HRESULT CreatePalette(
DDPixelCaps dwFlags,
LPPALETTEENTRY lpColorTable,
@ -355,19 +355,19 @@ struct IDirectDraw : virtual public IUnknown {
IUnknown* pUnkOuter
) = 0;
virtual HRESULT CreateSurface(
LPDDSURFACEDESC lpDDSurfaceDesc,
LPDIRECTDRAWSURFACE* lplpDDSurface,
DDSURFACEDESC* lpDDSurfaceDesc,
IDirectDrawSurface** lplpDDSurface,
IUnknown* pUnkOuter
) = 0;
virtual HRESULT EnumDisplayModes(
DWORD dwFlags,
LPDDSURFACEDESC lpDDSurfaceDesc,
DDSURFACEDESC* lpDDSurfaceDesc,
LPVOID lpContext,
LPDDENUMMODESCALLBACK lpEnumModesCallback
) = 0;
virtual HRESULT FlipToGDISurface() = 0;
virtual HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) = 0;
virtual HRESULT GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) = 0;
virtual HRESULT GetDisplayMode(DDSURFACEDESC* lpDDSurfaceDesc) = 0;
virtual HRESULT RestoreDisplayMode() = 0;
virtual HRESULT SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) = 0;
virtual HRESULT SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) = 0;

View File

@ -141,7 +141,6 @@ void OpenGL1Renderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* t
Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture)
{
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface);
for (Uint32 i = 0; i < m_textures.size(); ++i) {
auto& tex = m_textures[i];
@ -151,8 +150,7 @@ Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture)
glGenTextures(1, &tex.glTextureId);
glBindTexture(GL_TEXTURE_2D, tex.glTextureId);
SDL_Surface* surf =
SDL_ConvertSurface(surface->m_surface, SDL_PIXELFORMAT_ABGR8888); // Why are the colors backwarsd?
SDL_Surface* surf = SDL_ConvertSurface(texture->m_surface, SDL_PIXELFORMAT_ABGR8888);
if (!surf) {
return NO_TEXTURE_ID;
}
@ -171,8 +169,7 @@ Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture)
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
SDL_Surface* surf =
SDL_ConvertSurface(surface->m_surface, SDL_PIXELFORMAT_ABGR8888); // Why are the colors backwarsd?
SDL_Surface* surf = SDL_ConvertSurface(texture->m_surface, SDL_PIXELFORMAT_ABGR8888);
if (!surf) {
return NO_TEXTURE_ID;
}
@ -356,7 +353,7 @@ const char* OpenGL1Renderer::GetName()
HRESULT OpenGL1Renderer::BeginFrame(const D3DRMMATRIX4D& viewMatrix)
{
if (!DDBackBuffer) {
if (!DDFrameBuffer) {
return DDERR_GENERIC;
}
@ -538,11 +535,10 @@ void OpenGL1Renderer::SubmitDraw(
HRESULT OpenGL1Renderer::FinalizeFrame()
{
glDepthMask(GL_TRUE);
glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, m_renderedImage->pixels);
glReadPixels(0, 0, m_width, m_height, GL_BGRA, GL_UNSIGNED_BYTE, m_renderedImage->pixels);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Composite onto SDL backbuffer
SDL_BlitSurface(m_renderedImage, nullptr, DDBackBuffer, nullptr);
DDFrameBuffer->Upload(m_renderedImage->pixels, m_renderedImage->pitch);
return DD_OK;
}

View File

@ -141,7 +141,7 @@ static SDL_GPUGraphicsPipeline* InitializeGraphicsPipeline(SDL_GPUDevice* device
vertexInputState.num_vertex_attributes = SDL_arraysize(vertexAttrs);
SDL_GPUColorTargetDescription colorTargets = {};
colorTargets.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
colorTargets.format = SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM;
if (depthWrite) {
colorTargets.blend_state.enable_blend = false;
}
@ -209,7 +209,7 @@ Direct3DRMRenderer* Direct3DRMSDL3GPURenderer::Create(DWORD width, DWORD height)
SDL_GPUTextureCreateInfo textureInfo = {};
textureInfo.type = SDL_GPU_TEXTURETYPE_2D;
textureInfo.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
textureInfo.format = SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM;
textureInfo.usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
textureInfo.width = width;
textureInfo.height = height;
@ -310,7 +310,7 @@ Direct3DRMSDL3GPURenderer::Direct3DRMSDL3GPURenderer(
m_transparentPipeline(transparentPipeline), m_transferTexture(transferTexture), m_depthTexture(depthTexture),
m_sampler(sampler), m_uploadBuffer(uploadBuffer), m_downloadBuffer(downloadBuffer)
{
SDL_Surface* dummySurface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_ABGR8888);
SDL_Surface* dummySurface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_ARGB8888);
if (!dummySurface) {
SDL_LogError(LOG_CATEGORY_MINIWIN, "Failed to create surface: %s", SDL_GetError());
return;
@ -400,7 +400,7 @@ void Direct3DRMSDL3GPURenderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRM
SDL_GPUTexture* Direct3DRMSDL3GPURenderer::CreateTextureFromSurface(SDL_Surface* surface)
{
ScopedSurface surf{SDL_ConvertSurface(surface, SDL_PIXELFORMAT_ABGR8888)};
ScopedSurface surf{SDL_ConvertSurface(surface, SDL_PIXELFORMAT_ARGB8888)};
if (!surf.ptr) {
SDL_LogError(LOG_CATEGORY_MINIWIN, "SDL_ConvertSurface (%s)", SDL_GetError());
return nullptr;
@ -410,7 +410,7 @@ SDL_GPUTexture* Direct3DRMSDL3GPURenderer::CreateTextureFromSurface(SDL_Surface*
SDL_GPUTextureCreateInfo textureInfo = {};
textureInfo.type = SDL_GPU_TEXTURETYPE_2D;
textureInfo.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
textureInfo.format = SDL_GPU_TEXTUREFORMAT_B8G8R8A8_UNORM;
textureInfo.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER;
textureInfo.width = surf.ptr->w;
textureInfo.height = surf.ptr->h;
@ -464,15 +464,13 @@ SDL_GPUTexture* Direct3DRMSDL3GPURenderer::CreateTextureFromSurface(SDL_Surface*
Uint32 Direct3DRMSDL3GPURenderer::GetTextureId(IDirect3DRMTexture* iTexture)
{
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface);
SDL_Surface* surf = surface->m_surface;
for (Uint32 i = 0; i < m_textures.size(); ++i) {
auto& tex = m_textures[i];
if (tex.texture == texture) {
if (tex.version != texture->m_version) {
SDL_ReleaseGPUTexture(m_device, tex.gpuTexture);
tex.gpuTexture = CreateTextureFromSurface(surf);
tex.gpuTexture = CreateTextureFromSurface(texture->m_surface);
if (!tex.gpuTexture) {
return NO_TEXTURE_ID;
}
@ -482,7 +480,7 @@ Uint32 Direct3DRMSDL3GPURenderer::GetTextureId(IDirect3DRMTexture* iTexture)
}
}
SDL_GPUTexture* newTex = CreateTextureFromSurface(surf);
SDL_GPUTexture* newTex = CreateTextureFromSurface(texture->m_surface);
if (!newTex) {
return NO_TEXTURE_ID;
}
@ -705,7 +703,7 @@ SDL_GPUTransferBuffer* Direct3DRMSDL3GPURenderer::GetUploadBuffer(size_t size)
HRESULT Direct3DRMSDL3GPURenderer::BeginFrame(const D3DRMMATRIX4D& viewMatrix)
{
if (!DDBackBuffer) {
if (!DDFrameBuffer) {
return DDERR_GENERIC;
}
@ -807,10 +805,7 @@ HRESULT Direct3DRMSDL3GPURenderer::FinalizeFrame()
return DDERR_GENERIC;
}
SDL_Surface* renderedImage =
SDL_CreateSurfaceFrom(m_width, m_height, SDL_PIXELFORMAT_ABGR8888, downloadedData, m_width * 4);
SDL_BlitSurface(renderedImage, nullptr, DDBackBuffer, nullptr);
SDL_DestroySurface(renderedImage);
DDFrameBuffer->Upload(downloadedData, m_width * 4);
SDL_UnmapGPUTransferBuffer(m_device, m_downloadBuffer);
return DD_OK;

View File

@ -25,6 +25,7 @@
Direct3DRMSoftwareRenderer::Direct3DRMSoftwareRenderer(DWORD width, DWORD height) : m_width(width), m_height(height)
{
m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_ABGR8888);
m_zBuffer.resize(m_width * m_height);
}
@ -174,21 +175,8 @@ void Direct3DRMSoftwareRenderer::DrawTriangleClipped(const D3DRMVERTEX (&v)[3],
Uint32 Direct3DRMSoftwareRenderer::BlendPixel(Uint8* pixelAddr, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
Uint32 dstPixel;
switch (m_bytesPerPixel) {
case 1:
dstPixel = *pixelAddr;
break;
case 2:
dstPixel = *(Uint16*) pixelAddr;
break;
case 4:
dstPixel = *(Uint32*) pixelAddr;
break;
}
Uint8 dstR, dstG, dstB, dstA;
SDL_GetRGBA(dstPixel, m_format, m_palette, &dstR, &dstG, &dstB, &dstA);
SDL_GetRGBA(*(Uint32*) pixelAddr, m_format, m_palette, &dstR, &dstG, &dstB, &dstA);
float alpha = a / 255.0f;
float invAlpha = 1.0f - alpha;
@ -342,8 +330,8 @@ void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
}
}
Uint8* pixels = (Uint8*) DDBackBuffer->pixels;
int pitch = DDBackBuffer->pitch;
Uint8* pixels = (Uint8*) m_renderedImage->pixels;
int pitch = m_renderedImage->pitch;
VertexXY verts[3] = {
{p0.x, p0.y, p0.z, p0.w, c0, v0.texCoord.u, v0.texCoord.v},
@ -446,22 +434,8 @@ void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
int texY = static_cast<int>(v * texHeightScale);
Uint8* texelAddr = texels + texY * texturePitch + texX * m_bytesPerPixel;
Uint32 texelColor;
switch (m_bytesPerPixel) {
case 1:
texelColor = *texelAddr;
break;
case 2:
texelColor = *(Uint16*) texelAddr;
break;
case 4:
texelColor = *(Uint32*) texelAddr;
break;
}
Uint8 tr, tg, tb, ta;
SDL_GetRGBA(texelColor, m_format, m_palette, &tr, &tg, &tb, &ta);
SDL_GetRGBA(*(Uint32*) texelAddr, m_format, m_palette, &tr, &tg, &tb, &ta);
// Multiply vertex color by texel color
r = (r * tr + 127) / 255;
@ -475,17 +449,7 @@ void Direct3DRMSoftwareRenderer::DrawTriangleProjected(
finalColor = BlendPixel(pixelAddr, r, g, b, appearance.color.a);
}
switch (m_bytesPerPixel) {
case 1:
*pixelAddr = static_cast<Uint8>(finalColor);
break;
case 2:
*reinterpret_cast<Uint16*>(pixelAddr) = static_cast<Uint16>(finalColor);
break;
case 4:
*reinterpret_cast<Uint32*>(pixelAddr) = finalColor;
break;
}
*reinterpret_cast<Uint32*>(pixelAddr) = finalColor;
}
}
}
@ -517,7 +481,6 @@ void Direct3DRMSoftwareRenderer::AddTextureDestroyCallback(Uint32 id, IDirect3DR
Uint32 Direct3DRMSoftwareRenderer::GetTextureId(IDirect3DRMTexture* iTexture)
{
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
auto surface = static_cast<DirectDrawSurfaceImpl*>(texture->m_surface);
// Check if already mapped
for (Uint32 i = 0; i < m_textures.size(); ++i) {
@ -526,7 +489,7 @@ Uint32 Direct3DRMSoftwareRenderer::GetTextureId(IDirect3DRMTexture* iTexture)
if (texRef.version != texture->m_version) {
// Update animated textures
SDL_DestroySurface(texRef.cached);
texRef.cached = SDL_ConvertSurface(surface->m_surface, DDBackBuffer->format);
texRef.cached = SDL_ConvertSurface(texture->m_surface, HWBackBufferFormat);
SDL_LockSurface(texRef.cached);
texRef.version = texture->m_version;
}
@ -534,7 +497,7 @@ Uint32 Direct3DRMSoftwareRenderer::GetTextureId(IDirect3DRMTexture* iTexture)
}
}
SDL_Surface* convertedRender = SDL_ConvertSurface(surface->m_surface, DDBackBuffer->format);
SDL_Surface* convertedRender = SDL_ConvertSurface(texture->m_surface, HWBackBufferFormat);
SDL_LockSurface(convertedRender);
// Reuse freed slot
@ -655,14 +618,12 @@ const char* Direct3DRMSoftwareRenderer::GetName()
HRESULT Direct3DRMSoftwareRenderer::BeginFrame(const D3DRMMATRIX4D& viewMatrix)
{
if (!DDBackBuffer || !SDL_LockSurface(DDBackBuffer)) {
return DDERR_GENERIC;
}
ClearZBuffer();
Uint32 color = SDL_MapRGBA(SDL_GetPixelFormatDetails(m_renderedImage->format), nullptr, 0, 0, 0, 0);
SDL_FillSurfaceRect(m_renderedImage, nullptr, color);
memcpy(m_viewMatrix, viewMatrix, sizeof(D3DRMMATRIX4D));
m_format = SDL_GetPixelFormatDetails(DDBackBuffer->format);
m_palette = SDL_GetSurfacePalette(DDBackBuffer);
m_format = SDL_GetPixelFormatDetails(HWBackBufferFormat);
m_bytesPerPixel = m_format->bits_per_pixel / 8;
return DD_OK;
@ -708,7 +669,7 @@ void Direct3DRMSoftwareRenderer::SubmitDraw(
HRESULT Direct3DRMSoftwareRenderer::FinalizeFrame()
{
SDL_UnlockSurface(DDBackBuffer);
DDFrameBuffer->Upload(m_renderedImage->pixels, m_renderedImage->pitch);
return DD_OK;
}

View File

@ -160,14 +160,18 @@ HRESULT Direct3DRMImpl::CreateDeviceFromSurface(
HRESULT Direct3DRMImpl::CreateTexture(D3DRMIMAGE* image, IDirect3DRMTexture2** outTexture)
{
*outTexture = static_cast<IDirect3DRMTexture2*>(new Direct3DRMTextureImpl(image));
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT Direct3DRMImpl::CreateTextureFromSurface(LPDIRECTDRAWSURFACE surface, IDirect3DRMTexture2** outTexture)
HRESULT Direct3DRMImpl::CreateTextureFromSurface(IDirectDrawSurface* surface, IDirect3DRMTexture2** outTexture)
{
*outTexture = static_cast<IDirect3DRMTexture2*>(new Direct3DRMTextureImpl(surface));
*outTexture = dynamic_cast<IDirect3DRMTexture2*>(surface);
if (!*outTexture) {
return DDERR_GENERIC;
}
surface->AddRef();
return DD_OK;
}

View File

@ -1,13 +1,18 @@
#include "d3drmtexture_impl.h"
#include "ddpalette_impl.h"
#include "miniwin.h"
Direct3DRMTextureImpl::Direct3DRMTextureImpl(D3DRMIMAGE* image)
Direct3DRMTextureImpl::Direct3DRMTextureImpl(int width, int height, SDL_PixelFormat format)
{
MINIWIN_NOT_IMPLEMENTED();
m_surface = SDL_CreateSurface(width, height, format);
if (!m_surface) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create surface: %s", SDL_GetError());
}
}
Direct3DRMTextureImpl::Direct3DRMTextureImpl(IDirectDrawSurface* surface) : m_surface(surface)
Direct3DRMTextureImpl::~Direct3DRMTextureImpl()
{
SDL_DestroySurface(m_surface);
}
HRESULT Direct3DRMTextureImpl::QueryInterface(const GUID& riid, void** ppvObject)
@ -23,9 +28,169 @@ HRESULT Direct3DRMTextureImpl::QueryInterface(const GUID& riid, void** ppvObject
HRESULT Direct3DRMTextureImpl::Changed(BOOL pixels, BOOL palette)
{
if (!m_surface) {
return DDERR_GENERIC;
}
m_version++;
return DD_OK;
}
// IDirectDrawSurface interface
HRESULT Direct3DRMTextureImpl::AddAttachedSurface(IDirectDrawSurface* lpDDSAttachedSurface)
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Direct3DRMTextureImpl::Blt(
LPRECT lpDestRect,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFlags dwFlags,
LPDDBLTFX lpDDBltFx
)
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Direct3DRMTextureImpl::BltFast(
DWORD dwX,
DWORD dwY,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFastFlags dwTrans
)
{
if (dwX != 0 || dwY != 0) {
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
auto* other = dynamic_cast<Direct3DRMTextureImpl*>(lpDDSrcSurface);
if (!other) {
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
if (other->m_surface->format != m_surface->format) {
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
SDL_BlitSurface(other->m_surface, nullptr, m_surface, nullptr);
return DD_OK;
}
HRESULT Direct3DRMTextureImpl::Flip(IDirectDrawSurface* lpDDSurfaceTarget, DDFlipFlags dwFlags)
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Direct3DRMTextureImpl::GetAttachedSurface(LPDDSCAPS lpDDSCaps, IDirectDrawSurface** lplpDDAttachedSurface)
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Direct3DRMTextureImpl::GetDC(HDC* lphDC)
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Direct3DRMTextureImpl::GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette)
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Direct3DRMTextureImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat)
{
lpDDPixelFormat->dwFlags = DDPF_RGB;
const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(m_surface->format);
if (details->bits_per_pixel == 8) {
lpDDPixelFormat->dwFlags |= DDPF_PALETTEINDEXED8;
}
lpDDPixelFormat->dwRGBBitCount = details->bits_per_pixel;
lpDDPixelFormat->dwRBitMask = details->Rmask;
lpDDPixelFormat->dwGBitMask = details->Gmask;
lpDDPixelFormat->dwBBitMask = details->Bmask;
lpDDPixelFormat->dwRGBAlphaBitMask = details->Amask;
return DD_OK;
}
HRESULT Direct3DRMTextureImpl::GetSurfaceDesc(DDSURFACEDESC* lpDDSurfaceDesc)
{
lpDDSurfaceDesc->dwFlags = DDSD_PIXELFORMAT;
GetPixelFormat(&lpDDSurfaceDesc->ddpfPixelFormat);
lpDDSurfaceDesc->dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
lpDDSurfaceDesc->dwWidth = m_surface->w;
lpDDSurfaceDesc->dwHeight = m_surface->h;
return DD_OK;
}
HRESULT Direct3DRMTextureImpl::IsLost()
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Direct3DRMTextureImpl::Lock(
LPRECT lpDestRect,
DDSURFACEDESC* lpDDSurfaceDesc,
DDLockFlags dwFlags,
HANDLE hEvent
)
{
if (!SDL_LockSurface(m_surface)) {
return DDERR_GENERIC;
}
GetSurfaceDesc(lpDDSurfaceDesc);
lpDDSurfaceDesc->lpSurface = m_surface->pixels;
lpDDSurfaceDesc->lPitch = m_surface->pitch;
return DD_OK;
}
HRESULT Direct3DRMTextureImpl::ReleaseDC(HDC hDC)
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Direct3DRMTextureImpl::Restore()
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Direct3DRMTextureImpl::SetClipper(IDirectDrawClipper* lpDDClipper)
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Direct3DRMTextureImpl::SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey)
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Direct3DRMTextureImpl::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette)
{
if (m_surface->format != SDL_PIXELFORMAT_INDEX8) {
MINIWIN_NOT_IMPLEMENTED();
}
if (m_palette) {
m_palette->Release();
}
m_palette = lpDDPalette;
SDL_SetSurfacePalette(m_surface, ((DirectDrawPaletteImpl*) m_palette)->m_palette);
m_palette->AddRef();
return DD_OK;
}
HRESULT Direct3DRMTextureImpl::Unlock(LPVOID lpSurfaceData)
{
SDL_UnlockSurface(m_surface);
return DD_OK;
}

View File

@ -358,16 +358,15 @@ HRESULT Direct3DRMViewportImpl::ForceUpdate(int x, int y, int w, int h)
HRESULT Direct3DRMViewportImpl::Clear()
{
if (!DDBackBuffer) {
if (!DDRenderer) {
return DDERR_GENERIC;
}
uint8_t r = (m_backgroundColor >> 16) & 0xFF;
uint8_t g = (m_backgroundColor >> 8) & 0xFF;
uint8_t b = m_backgroundColor & 0xFF;
Uint32 color = SDL_MapRGB(SDL_GetPixelFormatDetails(DDBackBuffer->format), nullptr, r, g, b);
SDL_FillSurfaceRect(DDBackBuffer, nullptr, color);
SDL_SetRenderDrawColor(DDRenderer, r, g, b, 255);
SDL_RenderClear(DDRenderer);
return DD_OK;
}

View File

@ -6,6 +6,7 @@
#include "ddpalette_impl.h"
#include "ddraw_impl.h"
#include "ddsurface_impl.h"
#include "dummysurface_impl.h"
#include "miniwin.h"
#include "miniwin/d3d.h"
@ -16,8 +17,7 @@
#include <cstring>
SDL_Window* DDWindow;
SDL_Surface* DDBackBuffer;
SDL_Texture* HWBackBuffer;
FrameBufferImpl* DDFrameBuffer;
SDL_PixelFormat HWBackBufferFormat;
SDL_Renderer* DDRenderer;
@ -38,7 +38,7 @@ HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject)
}
// IDirectDraw interface
HRESULT DirectDrawImpl::CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter)
HRESULT DirectDrawImpl::CreateClipper(DWORD dwFlags, IDirectDrawClipper** lplpDDClipper, IUnknown* pUnkOuter)
{
*lplpDDClipper = new IDirectDrawClipper;
@ -61,17 +61,37 @@ HRESULT DirectDrawImpl::CreatePalette(
}
HRESULT DirectDrawImpl::CreateSurface(
LPDDSURFACEDESC lpDDSurfaceDesc,
LPDIRECTDRAWSURFACE* lplpDDSurface,
DDSURFACEDESC* lpDDSurfaceDesc,
IDirectDrawSurface** lplpDDSurface,
IUnknown* pUnkOuter
)
{
SDL_PixelFormat format;
#ifdef MINIWIN_PIXELFORMAT
format = MINIWIN_PIXELFORMAT;
#else
format = SDL_PIXELFORMAT_RGBA8888;
#endif
bool isTexture = false;
if ((lpDDSurfaceDesc->dwFlags & DDSD_CAPS) == DDSD_CAPS) {
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER) {
if ((lpDDSurfaceDesc->dwFlags & DDSD_ZBUFFERBITDEPTH) != DDSD_ZBUFFERBITDEPTH) {
return DDERR_INVALIDPARAMS;
}
SDL_Log("Todo: Set %dbit Z-Buffer", lpDDSurfaceDesc->dwZBufferBitDepth);
*lplpDDSurface = static_cast<IDirectDrawSurface*>(new DummySurfaceImpl);
return DD_OK;
}
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) == DDSCAPS_PRIMARYSURFACE) {
DDFrameBuffer = new FrameBufferImpl();
*lplpDDSurface = static_cast<IDirectDrawSurface*>(DDFrameBuffer);
return DD_OK;
}
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) == DDSCAPS_3DDEVICE) {
DDFrameBuffer->AddRef();
*lplpDDSurface = static_cast<IDirectDrawSurface*>(DDFrameBuffer);
return DD_OK;
}
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) == DDSCAPS_TEXTURE) {
isTexture = true;
}
}
SDL_PixelFormat format = HWBackBufferFormat;
if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) == DDSD_PIXELFORMAT) {
if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) == DDPF_RGB) {
switch (lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount) {
@ -84,44 +104,6 @@ HRESULT DirectDrawImpl::CreateSurface(
}
}
}
if ((lpDDSurfaceDesc->dwFlags & DDSD_CAPS) == DDSD_CAPS) {
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) == DDSCAPS_ZBUFFER) {
if ((lpDDSurfaceDesc->dwFlags & DDSD_ZBUFFERBITDEPTH) != DDSD_ZBUFFERBITDEPTH) {
return DDERR_INVALIDPARAMS;
}
SDL_Log("Todo: Set %dbit Z-Buffer", lpDDSurfaceDesc->dwZBufferBitDepth);
*lplpDDSurface = static_cast<IDirectDrawSurface*>(new DirectDrawSurfaceImpl);
return DD_OK;
}
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) == DDSCAPS_PRIMARYSURFACE) {
SDL_Surface* windowSurface = SDL_GetWindowSurface(DDWindow);
if (!windowSurface) {
return DDERR_GENERIC;
}
int width, height;
SDL_GetWindowSize(DDWindow, &width, &height);
bool implicitFlip = (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_FLIP) != DDSCAPS_FLIP;
auto frontBuffer = new DirectDrawSurfaceImpl(width, height, windowSurface->format);
frontBuffer->SetAutoFlip(implicitFlip);
*lplpDDSurface = static_cast<IDirectDrawSurface*>(frontBuffer);
return DD_OK;
}
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) == DDSCAPS_OFFSCREENPLAIN) {
MINIWIN_TRACE("DDSCAPS_OFFSCREENPLAIN"); // 2D surfaces?
}
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) == DDSCAPS_SYSTEMMEMORY) {
MINIWIN_TRACE("DDSCAPS_SYSTEMMEMORY"); // Software rendering?
}
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) == DDSCAPS_TEXTURE) {
MINIWIN_TRACE("DDSCAPS_TEXTURE"); // Texture for use in 3D
}
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) == DDSCAPS_3DDEVICE) {
MINIWIN_TRACE("DDSCAPS_3DDEVICE"); // back buffer
}
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) == DDSCAPS_VIDEOMEMORY) {
MINIWIN_TRACE("DDSCAPS_VIDEOMEMORY"); // front / back buffer
}
}
if ((lpDDSurfaceDesc->dwFlags & (DDSD_WIDTH | DDSD_HEIGHT)) != (DDSD_WIDTH | DDSD_HEIGHT)) {
return DDERR_INVALIDPARAMS;
@ -132,13 +114,20 @@ HRESULT DirectDrawImpl::CreateSurface(
if (width == 0 || height == 0) {
return DDERR_INVALIDPARAMS;
}
*lplpDDSurface = static_cast<IDirectDrawSurface*>(new DirectDrawSurfaceImpl(width, height, format));
if (isTexture) {
*lplpDDSurface = static_cast<IDirectDrawSurface*>(new Direct3DRMTextureImpl(width, height, format));
}
else {
*lplpDDSurface = static_cast<IDirectDrawSurface*>(new DirectDrawSurfaceImpl(width, height, format));
}
return DD_OK;
}
HRESULT DirectDrawImpl::EnumDisplayModes(
DWORD dwFlags,
LPDDSURFACEDESC lpDDSurfaceDesc,
DDSURFACEDESC* lpDDSurfaceDesc,
LPVOID lpContext,
LPDDENUMMODESCALLBACK lpEnumModesCallback
)
@ -158,11 +147,7 @@ HRESULT DirectDrawImpl::EnumDisplayModes(
HRESULT status = S_OK;
for (int i = 0; i < count_modes; i++) {
#ifdef MINIWIN_PIXELFORMAT
format = MINIWIN_PIXELFORMAT;
#else
format = modes[i]->format;
#endif
const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(format);
if (!details) {
@ -239,7 +224,7 @@ HRESULT DirectDrawImpl::EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx)
return S_OK;
}
HRESULT DirectDrawImpl::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc)
HRESULT DirectDrawImpl::GetDisplayMode(DDSURFACEDESC* lpDDSurfaceDesc)
{
SDL_DisplayID displayID = SDL_GetPrimaryDisplay();
if (!displayID) {
@ -251,14 +236,7 @@ HRESULT DirectDrawImpl::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc)
return DDERR_GENERIC;
}
SDL_PixelFormat format;
#ifdef MINIWIN_PIXELFORMAT
format = MINIWIN_PIXELFORMAT;
#else
format = mode->format;
#endif
const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(format);
const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(mode->format);
lpDDSurfaceDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
lpDDSurfaceDesc->dwWidth = mode->w;
@ -305,6 +283,10 @@ HRESULT DirectDrawImpl::SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags)
}
DDWindow = sdlWindow;
DDRenderer = SDL_CreateRenderer(DDWindow, NULL);
SDL_PropertiesID prop = SDL_GetRendererProperties(DDRenderer);
const SDL_PixelFormat* formats =
(SDL_PixelFormat*) SDL_GetPointerProperty(prop, SDL_PROP_RENDERER_TEXTURE_FORMATS_POINTER, NULL);
HWBackBufferFormat = formats[0];
SDL_SetRenderLogicalPresentation(DDRenderer, 640, 480, SDL_LOGICAL_PRESENTATION_LETTERBOX);
}
return DD_OK;

View File

@ -5,26 +5,17 @@
#include <assert.h>
DirectDrawSurfaceImpl::DirectDrawSurfaceImpl()
{
}
DirectDrawSurfaceImpl::DirectDrawSurfaceImpl(int width, int height, SDL_PixelFormat format)
{
m_surface = SDL_CreateSurface(width, height, format);
if (!m_surface) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create surface: %s", SDL_GetError());
m_texture = SDL_CreateTexture(DDRenderer, format, SDL_TEXTUREACCESS_STREAMING, width, height);
if (!m_texture) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create texture: %s", SDL_GetError());
}
}
DirectDrawSurfaceImpl::~DirectDrawSurfaceImpl()
{
if (m_surface) {
SDL_DestroySurface(m_surface);
}
if (m_palette) {
m_palette->Release();
}
SDL_DestroyTexture(m_texture);
}
// IUnknown interface
@ -40,120 +31,62 @@ HRESULT DirectDrawSurfaceImpl::QueryInterface(const GUID& riid, void** ppvObject
}
// IDirectDrawSurface interface
HRESULT DirectDrawSurfaceImpl::AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface)
HRESULT DirectDrawSurfaceImpl::AddAttachedSurface(IDirectDrawSurface* lpDDSAttachedSurface)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
void DirectDrawSurfaceImpl::SetAutoFlip(bool enabled)
{
m_autoFlip = enabled;
}
static SDL_Rect ConvertRect(const RECT* r)
{
return {r->left, r->top, r->right - r->left, r->bottom - r->top};
}
bool SetupHWBackBuffer()
{
HWBackBuffer = SDL_CreateTextureFromSurface(DDRenderer, DDBackBuffer);
if (!HWBackBuffer) {
return false;
}
SDL_PropertiesID props = SDL_GetTextureProperties(HWBackBuffer);
if (!props) {
SDL_DestroyTexture(HWBackBuffer);
HWBackBuffer = nullptr;
return false;
}
HWBackBufferFormat =
(SDL_PixelFormat) SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_FORMAT_NUMBER, SDL_PIXELFORMAT_UNKNOWN);
if (HWBackBufferFormat == SDL_PIXELFORMAT_UNKNOWN) {
SDL_DestroyTexture(HWBackBuffer);
HWBackBuffer = nullptr;
return false;
}
return true;
return {r->left, r->top, (r->right - r->left), (r->bottom - r->top)};
}
HRESULT DirectDrawSurfaceImpl::Blt(
LPRECT lpDestRect,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFlags dwFlags,
LPDDBLTFX lpDDBltFx
)
{
if ((dwFlags & DDBLT_COLORFILL) == DDBLT_COLORFILL) {
SDL_Rect rect = {0, 0, m_surface->w, m_surface->h};
const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(m_surface->format);
Uint8 r = (lpDDBltFx->dwFillColor >> 16) & 0xFF;
Uint8 g = (lpDDBltFx->dwFillColor >> 8) & 0xFF;
Uint8 b = lpDDBltFx->dwFillColor & 0xFF;
DirectDrawPaletteImpl* ddPal = static_cast<DirectDrawPaletteImpl*>(m_palette);
SDL_Palette* sdlPalette = ddPal ? ddPal->m_palette : nullptr;
Uint32 color = SDL_MapRGB(details, sdlPalette, r, g, b);
SDL_FillSurfaceRect(m_surface, &rect, color);
if (m_autoFlip) {
return Flip(nullptr, DDFLIP_WAIT);
}
return DD_OK;
}
auto srcSurface = static_cast<DirectDrawSurfaceImpl*>(lpDDSrcSurface);
if (!srcSurface || !srcSurface->m_surface) {
auto* other = dynamic_cast<DirectDrawSurfaceImpl*>(lpDDSrcSurface);
if (!other) {
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
if (m_autoFlip) {
DDBackBuffer = srcSurface->m_surface;
if (!HWBackBuffer && !SetupHWBackBuffer()) {
return DDERR_GENERIC;
}
return Flip(nullptr, DDFLIP_WAIT);
}
SDL_Rect srcRect;
SDL_Rect srcRect, dstRect;
if (lpSrcRect) {
srcRect = ConvertRect(lpSrcRect);
}
else {
srcRect = {0, 0, srcSurface->m_surface->w, srcSurface->m_surface->h};
}
SDL_Rect dstRect;
if (lpDestRect) {
dstRect = ConvertRect(lpDestRect);
}
else {
dstRect = {0, 0, m_surface->w, m_surface->h};
}
SDL_Surface* blitSource = srcSurface->m_surface;
if (srcSurface->m_surface->format != m_surface->format) {
blitSource = SDL_ConvertSurface(srcSurface->m_surface, m_surface->format);
if (!blitSource) {
return DDERR_GENERIC;
}
}
if (!SDL_BlitSurfaceScaled(blitSource, &srcRect, m_surface, &dstRect, SDL_SCALEMODE_NEAREST)) {
void* otherPixels;
int otherPitch;
if (!SDL_LockTexture(other->m_texture, lpSrcRect ? &srcRect : nullptr, &otherPixels, &otherPitch)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to lock other texture: %s", SDL_GetError());
return DDERR_GENERIC;
}
if (blitSource != srcSurface->m_surface) {
SDL_DestroySurface(blitSource);
void* pixels;
int pitch;
if (!SDL_LockTexture(m_texture, lpDestRect ? &dstRect : nullptr, &pixels, &pitch)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to lock destination texture: %s", SDL_GetError());
return DDERR_GENERIC;
}
memcpy(pixels, otherPixels, (lpDestRect ? dstRect.h : m_texture->h) * pitch);
SDL_UnlockTexture(other->m_texture);
SDL_UnlockTexture(m_texture);
return DD_OK;
}
HRESULT DirectDrawSurfaceImpl::BltFast(
DWORD dwX,
DWORD dwY,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFastFlags dwTrans
)
@ -167,30 +100,15 @@ HRESULT DirectDrawSurfaceImpl::BltFast(
return Blt(&destRect, lpDDSrcSurface, lpSrcRect, DDBLT_NONE, nullptr);
}
HRESULT DirectDrawSurfaceImpl::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags)
HRESULT DirectDrawSurfaceImpl::Flip(IDirectDrawSurface* lpDDSurfaceTargetOverride, DDFlipFlags dwFlags)
{
if (!DDBackBuffer || !DDRenderer) {
return DDERR_GENERIC;
}
SDL_Surface* copy = SDL_ConvertSurface(DDBackBuffer, HWBackBufferFormat);
SDL_UpdateTexture(HWBackBuffer, nullptr, copy->pixels, copy->pitch);
SDL_DestroySurface(copy);
SDL_RenderTexture(DDRenderer, HWBackBuffer, nullptr, nullptr);
SDL_RenderPresent(DDRenderer);
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT DirectDrawSurfaceImpl::GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface)
HRESULT DirectDrawSurfaceImpl::GetAttachedSurface(LPDDSCAPS lpDDSCaps, IDirectDrawSurface** lplpDDAttachedSurface)
{
if ((lpDDSCaps->dwCaps & DDSCAPS_BACKBUFFER) != DDSCAPS_BACKBUFFER) {
return DDERR_INVALIDPARAMS;
}
DDBackBuffer = m_surface;
if (!SetupHWBackBuffer()) {
return DDERR_GENERIC;
}
*lplpDDAttachedSurface = static_cast<IDirectDrawSurface*>(this);
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
@ -202,22 +120,14 @@ HRESULT DirectDrawSurfaceImpl::GetDC(HDC* lphDC)
HRESULT DirectDrawSurfaceImpl::GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette)
{
if (!m_palette) {
return DDERR_GENERIC;
}
m_palette->AddRef();
*lplpDDPalette = m_palette;
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT DirectDrawSurfaceImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat)
{
if (!m_surface) {
return DDERR_GENERIC;
}
memset(lpDDPixelFormat, 0, sizeof(*lpDDPixelFormat));
lpDDPixelFormat->dwFlags = DDPF_RGB;
const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(m_surface->format);
const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(HWBackBufferFormat);
if (details->bits_per_pixel == 8) {
lpDDPixelFormat->dwFlags |= DDPF_PALETTEINDEXED8;
}
@ -229,18 +139,13 @@ HRESULT DirectDrawSurfaceImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat)
return DD_OK;
}
HRESULT DirectDrawSurfaceImpl::GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc)
HRESULT DirectDrawSurfaceImpl::GetSurfaceDesc(DDSURFACEDESC* lpDDSurfaceDesc)
{
if (!m_surface) {
return DDERR_GENERIC;
}
lpDDSurfaceDesc->dwFlags = DDSD_PIXELFORMAT;
GetPixelFormat(&lpDDSurfaceDesc->ddpfPixelFormat);
if (m_surface) {
lpDDSurfaceDesc->dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
lpDDSurfaceDesc->dwWidth = m_surface->w;
lpDDSurfaceDesc->dwHeight = m_surface->h;
}
lpDDSurfaceDesc->dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
lpDDSurfaceDesc->dwWidth = m_texture->w;
lpDDSurfaceDesc->dwHeight = m_texture->h;
return DD_OK;
}
@ -251,23 +156,16 @@ HRESULT DirectDrawSurfaceImpl::IsLost()
HRESULT DirectDrawSurfaceImpl::Lock(
LPRECT lpDestRect,
LPDDSURFACEDESC lpDDSurfaceDesc,
DDSURFACEDESC* lpDDSurfaceDesc,
DDLockFlags dwFlags,
HANDLE hEvent
)
{
if (!m_surface) {
return DDERR_GENERIC;
}
if (!SDL_LockSurface(m_surface)) {
if (!SDL_LockTexture(m_texture, nullptr, &lpDDSurfaceDesc->lpSurface, &lpDDSurfaceDesc->lPitch)) {
return DDERR_GENERIC;
}
GetSurfaceDesc(lpDDSurfaceDesc);
lpDDSurfaceDesc->lpSurface = m_surface->pixels;
lpDDSurfaceDesc->lPitch = m_surface->pitch;
return DD_OK;
}
@ -279,48 +177,30 @@ HRESULT DirectDrawSurfaceImpl::ReleaseDC(HDC hDC)
HRESULT DirectDrawSurfaceImpl::Restore()
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT DirectDrawSurfaceImpl::SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper)
HRESULT DirectDrawSurfaceImpl::SetClipper(IDirectDrawClipper* lpDDClipper)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT DirectDrawSurfaceImpl::SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey)
{
if (lpDDColorKey->dwColorSpaceLowValue != lpDDColorKey->dwColorSpaceHighValue) {
MINIWIN_NOT_IMPLEMENTED();
}
if (SDL_SetSurfaceColorKey(m_surface, true, lpDDColorKey->dwColorSpaceLowValue) != 0) {
return DDERR_GENERIC;
}
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT DirectDrawSurfaceImpl::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette)
{
if (m_surface->format != SDL_PIXELFORMAT_INDEX8) {
MINIWIN_NOT_IMPLEMENTED();
}
if (m_palette) {
m_palette->Release();
}
m_palette = lpDDPalette;
SDL_SetSurfacePalette(m_surface, ((DirectDrawPaletteImpl*) m_palette)->m_palette);
m_palette->AddRef();
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT DirectDrawSurfaceImpl::Unlock(LPVOID lpSurfaceData)
{
if (!m_surface) {
return DDERR_GENERIC;
}
SDL_UnlockSurface(m_surface);
SDL_UnlockTexture(m_texture);
return DD_OK;
}

View File

@ -0,0 +1,226 @@
#include "ddpalette_impl.h"
#include "ddraw_impl.h"
#include "dummysurface_impl.h"
#include "framebuffer_impl.h"
#include "miniwin.h"
#include <assert.h>
FrameBufferImpl::FrameBufferImpl()
{
int width, height;
SDL_GetRenderOutputSize(DDRenderer, &width, &height);
m_backBuffer = SDL_CreateTexture(DDRenderer, HWBackBufferFormat, SDL_TEXTUREACCESS_TARGET, width, height);
m_uploadBuffer = SDL_CreateTexture(DDRenderer, HWBackBufferFormat, SDL_TEXTUREACCESS_STREAMING, width, height);
SDL_SetRenderTarget(DDRenderer, m_backBuffer);
if (!m_backBuffer) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create surface: %s", SDL_GetError());
}
}
FrameBufferImpl::~FrameBufferImpl()
{
SDL_DestroyTexture(m_backBuffer);
}
// IUnknown interface
HRESULT FrameBufferImpl::QueryInterface(const GUID& riid, void** ppvObject)
{
MINIWIN_NOT_IMPLEMENTED();
return E_NOINTERFACE;
}
// IDirectDrawSurface interface
HRESULT FrameBufferImpl::AddAttachedSurface(IDirectDrawSurface* lpDDSAttachedSurface)
{
if (dynamic_cast<DummySurfaceImpl*>(lpDDSAttachedSurface)) {
return DD_OK;
}
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
static SDL_FRect ConvertRect(const RECT* r)
{
return {(float) r->left, (float) r->top, (float) (r->right - r->left), (float) (r->bottom - r->top)};
}
HRESULT FrameBufferImpl::Blt(
LPRECT lpDestRect,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFlags dwFlags,
LPDDBLTFX lpDDBltFx
)
{
if (dynamic_cast<FrameBufferImpl*>(lpDDSrcSurface) == this) {
return Flip(nullptr, DDFLIP_WAIT);
}
if ((dwFlags & DDBLT_COLORFILL) == DDBLT_COLORFILL) {
if (lpDestRect != nullptr) {
MINIWIN_NOT_IMPLEMENTED();
}
Uint8 r = (lpDDBltFx->dwFillColor >> 16) & 0xFF;
Uint8 g = (lpDDBltFx->dwFillColor >> 8) & 0xFF;
Uint8 b = lpDDBltFx->dwFillColor & 0xFF;
SDL_SetRenderDrawColor(DDRenderer, r, g, b, 0xFF);
SDL_RenderClear(DDRenderer);
}
else {
auto srcSurface = dynamic_cast<DirectDrawSurfaceImpl*>(lpDDSrcSurface);
if (!srcSurface) {
return DDERR_GENERIC;
}
SDL_FRect srcRect, dstRect;
if (lpSrcRect) {
srcRect = ConvertRect(lpSrcRect);
}
if (lpDestRect) {
dstRect = ConvertRect(lpDestRect);
}
if (!SDL_RenderTexture(
DDRenderer,
srcSurface->m_texture,
lpSrcRect ? &srcRect : nullptr,
lpDestRect ? &dstRect : nullptr
)) {
return DDERR_GENERIC;
}
}
return DD_OK;
}
HRESULT FrameBufferImpl::BltFast(
DWORD dwX,
DWORD dwY,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFastFlags dwTrans
)
{
RECT destRect = {
(int) dwX,
(int) dwY,
(int) (lpSrcRect->right - lpSrcRect->left + dwX),
(int) (lpSrcRect->bottom - lpSrcRect->top + dwY)
};
return Blt(&destRect, lpDDSrcSurface, lpSrcRect, DDBLT_NONE, nullptr);
}
HRESULT FrameBufferImpl::Flip(IDirectDrawSurface* lpDDSurfaceTargetOverride, DDFlipFlags dwFlags)
{
SDL_SetRenderTarget(DDRenderer, nullptr);
SDL_RenderTexture(DDRenderer, m_backBuffer, nullptr, nullptr);
SDL_RenderPresent(DDRenderer);
SDL_SetRenderTarget(DDRenderer, m_backBuffer);
return DD_OK;
}
HRESULT FrameBufferImpl::GetAttachedSurface(LPDDSCAPS lpDDSCaps, IDirectDrawSurface** lplpDDAttachedSurface)
{
if ((lpDDSCaps->dwCaps & DDSCAPS_BACKBUFFER) != DDSCAPS_BACKBUFFER) {
return DDERR_INVALIDPARAMS;
}
this->AddRef();
*lplpDDAttachedSurface = static_cast<IDirectDrawSurface*>(this);
return DD_OK;
}
HRESULT FrameBufferImpl::GetDC(HDC* lphDC)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT FrameBufferImpl::GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT FrameBufferImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat)
{
lpDDPixelFormat->dwFlags = DDPF_RGB;
const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(HWBackBufferFormat);
if (details->bits_per_pixel == 8) {
lpDDPixelFormat->dwFlags |= DDPF_PALETTEINDEXED8;
}
lpDDPixelFormat->dwRGBBitCount = details->bits_per_pixel;
lpDDPixelFormat->dwRBitMask = details->Rmask;
lpDDPixelFormat->dwGBitMask = details->Gmask;
lpDDPixelFormat->dwBBitMask = details->Bmask;
lpDDPixelFormat->dwRGBAlphaBitMask = details->Amask;
return DD_OK;
}
HRESULT FrameBufferImpl::GetSurfaceDesc(DDSURFACEDESC* lpDDSurfaceDesc)
{
lpDDSurfaceDesc->dwFlags = DDSD_PIXELFORMAT;
GetPixelFormat(&lpDDSurfaceDesc->ddpfPixelFormat);
lpDDSurfaceDesc->dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
lpDDSurfaceDesc->dwWidth = m_backBuffer->w;
lpDDSurfaceDesc->dwHeight = m_backBuffer->h;
return DD_OK;
}
HRESULT FrameBufferImpl::IsLost()
{
return DD_OK;
}
HRESULT FrameBufferImpl::Lock(LPRECT lpDestRect, DDSURFACEDESC* lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent)
{
m_readBackBuffer = SDL_RenderReadPixels(DDRenderer, nullptr);
if (!SDL_LockSurface(m_readBackBuffer)) {
return DDERR_GENERIC;
}
GetSurfaceDesc(lpDDSurfaceDesc);
lpDDSurfaceDesc->lpSurface = m_readBackBuffer->pixels;
lpDDSurfaceDesc->lPitch = m_readBackBuffer->pitch;
return DD_OK;
}
HRESULT FrameBufferImpl::ReleaseDC(HDC hDC)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT FrameBufferImpl::Restore()
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT FrameBufferImpl::SetClipper(IDirectDrawClipper* lpDDClipper)
{
return DD_OK;
}
HRESULT FrameBufferImpl::SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT FrameBufferImpl::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette)
{
MINIWIN_NOT_IMPLEMENTED();
return DD_OK;
}
HRESULT FrameBufferImpl::Unlock(LPVOID lpSurfaceData)
{
SDL_UpdateTexture(m_uploadBuffer, nullptr, m_readBackBuffer->pixels, m_readBackBuffer->pitch);
SDL_DestroySurface(m_readBackBuffer);
SDL_RenderTexture(DDRenderer, m_uploadBuffer, nullptr, nullptr);
return DD_OK;
}
void FrameBufferImpl::Upload(void* pixels, int pitch)
{
SDL_UpdateTexture(m_uploadBuffer, nullptr, pixels, pitch);
SDL_RenderTexture(DDRenderer, m_uploadBuffer, nullptr, nullptr);
}

View File

@ -24,7 +24,7 @@ struct Direct3DRMImpl : virtual public IDirect3DRM2 {
IDirect3DRMDevice2** outDevice
) override;
HRESULT CreateTexture(D3DRMIMAGE* image, IDirect3DRMTexture2** outTexture) override;
HRESULT CreateTextureFromSurface(LPDIRECTDRAWSURFACE surface, IDirect3DRMTexture2** outTexture) override;
HRESULT CreateTextureFromSurface(IDirectDrawSurface* surface, IDirect3DRMTexture2** outTexture) override;
HRESULT CreateMesh(IDirect3DRMMesh** outMesh) override;
HRESULT CreateMaterial(D3DVAL power, IDirect3DRMMaterial** outMaterial) override;
HRESULT CreateLightRGB(D3DRMLIGHTTYPE type, D3DVAL r, D3DVAL g, D3DVAL b, IDirect3DRMLight** outLight) override;

View File

@ -62,6 +62,7 @@ class Direct3DRMSoftwareRenderer : public Direct3DRMRenderer {
DWORD m_width;
DWORD m_height;
SDL_Surface* m_renderedImage;
SDL_Palette* m_palette;
const SDL_PixelFormatDetails* m_format;
int m_bytesPerPixel;

View File

@ -1,13 +1,47 @@
#pragma once
#include "d3drmobject_impl.h"
#include "miniwin/ddraw.h"
struct Direct3DRMTextureImpl : public Direct3DRMObjectBaseImpl<IDirect3DRMTexture2> {
Direct3DRMTextureImpl(D3DRMIMAGE* image);
Direct3DRMTextureImpl(IDirectDrawSurface* surface);
#include <SDL3/SDL.h>
struct Direct3DRMTextureImpl : public Direct3DRMObjectBaseImpl<IDirect3DRMTexture2>, public IDirectDrawSurface3 {
Direct3DRMTextureImpl(int width, int height, SDL_PixelFormat format);
~Direct3DRMTextureImpl() override;
// IUnknown interface
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
// IDirect3DRMTexture2 interface
HRESULT Changed(BOOL pixels, BOOL palette) override;
// IDirectDrawSurface interface
HRESULT AddAttachedSurface(IDirectDrawSurface* lpDDSAttachedSurface) override;
HRESULT Blt(
LPRECT lpDestRect,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFlags dwFlags,
LPDDBLTFX lpDDBltFx
) override;
HRESULT BltFast(DWORD dwX, DWORD dwY, IDirectDrawSurface* lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans)
override;
HRESULT Flip(IDirectDrawSurface* lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) override;
HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, IDirectDrawSurface** lplpDDAttachedSurface) override;
HRESULT GetDC(HDC* lphDC) override;
HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) override;
HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) override;
HRESULT GetSurfaceDesc(DDSURFACEDESC* lpDDSurfaceDesc) override;
HRESULT IsLost() override;
HRESULT Lock(LPRECT lpDestRect, DDSURFACEDESC* lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override;
HRESULT ReleaseDC(HDC hDC) override;
HRESULT Restore() override;
HRESULT SetClipper(IDirectDrawClipper* lpDDClipper) override;
HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override;
HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override;
HRESULT Unlock(LPVOID lpSurfaceData) override;
IDirectDrawSurface* m_surface = nullptr;
SDL_Surface* m_surface = nullptr;
Uint8 m_version = 0;
private:
IDirectDrawPalette* m_palette = nullptr;
};

View File

@ -1,14 +1,14 @@
#pragma once
#include "d3drmrenderer.h"
#include "framebuffer_impl.h"
#include "miniwin/d3d.h"
#include "miniwin/ddraw.h"
#include <SDL3/SDL.h>
extern SDL_Window* DDWindow;
extern SDL_Surface* DDBackBuffer;
extern SDL_Texture* HWBackBuffer;
extern FrameBufferImpl* DDFrameBuffer;
extern SDL_PixelFormat HWBackBufferFormat;
extern SDL_Renderer* DDRenderer;
@ -16,7 +16,7 @@ struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 {
// IUnknown interface
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
// IDirectDraw interface
HRESULT CreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) override;
HRESULT CreateClipper(DWORD dwFlags, IDirectDrawClipper** lplpDDClipper, IUnknown* pUnkOuter) override;
HRESULT
CreatePalette(
DDPixelCaps dwFlags,
@ -24,17 +24,17 @@ struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 {
LPDIRECTDRAWPALETTE* lplpDDPalette,
IUnknown* pUnkOuter
) override;
HRESULT CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE* lplpDDSurface, IUnknown* pUnkOuter)
HRESULT CreateSurface(DDSURFACEDESC* lpDDSurfaceDesc, IDirectDrawSurface** lplpDDSurface, IUnknown* pUnkOuter)
override;
HRESULT EnumDisplayModes(
DWORD dwFlags,
LPDDSURFACEDESC lpDDSurfaceDesc,
DDSURFACEDESC* lpDDSurfaceDesc,
LPVOID lpContext,
LPDDENUMMODESCALLBACK lpEnumModesCallback
) override;
HRESULT FlipToGDISurface() override;
HRESULT GetCaps(LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) override;
HRESULT GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) override;
HRESULT GetDisplayMode(DDSURFACEDESC* lpDDSurfaceDesc) override;
HRESULT RestoreDisplayMode() override;
HRESULT SetCooperativeLevel(HWND hWnd, DDSCLFlags dwFlags) override;
HRESULT SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) override;

View File

@ -4,42 +4,36 @@
#include <miniwin/ddraw.h>
struct DirectDrawSurfaceImpl : public IDirectDrawSurface3 {
DirectDrawSurfaceImpl();
DirectDrawSurfaceImpl(int width, int height, SDL_PixelFormat format);
~DirectDrawSurfaceImpl() override;
// IUnknown interface
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
// IDirectDrawSurface interface
HRESULT AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface) override;
HRESULT AddAttachedSurface(IDirectDrawSurface* lpDDSAttachedSurface) override;
HRESULT Blt(
LPRECT lpDestRect,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFlags dwFlags,
LPDDBLTFX lpDDBltFx
) override;
HRESULT BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans)
HRESULT BltFast(DWORD dwX, DWORD dwY, IDirectDrawSurface* lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans)
override;
HRESULT Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) override;
HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) override;
HRESULT Flip(IDirectDrawSurface* lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) override;
HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, IDirectDrawSurface** lplpDDAttachedSurface) override;
HRESULT GetDC(HDC* lphDC) override;
HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) override;
HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) override;
HRESULT GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) override;
HRESULT GetSurfaceDesc(DDSURFACEDESC* lpDDSurfaceDesc) override;
HRESULT IsLost() override;
HRESULT Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override;
HRESULT Lock(LPRECT lpDestRect, DDSURFACEDESC* lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override;
HRESULT ReleaseDC(HDC hDC) override;
HRESULT Restore() override;
HRESULT SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) override;
HRESULT SetClipper(IDirectDrawClipper* lpDDClipper) override;
HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override;
HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override;
void SetAutoFlip(bool enabled);
HRESULT Unlock(LPVOID lpSurfaceData) override;
SDL_Surface* m_surface = nullptr;
private:
bool m_autoFlip = false;
IDirectDrawPalette* m_palette = nullptr;
SDL_Texture* m_texture;
};

View File

@ -0,0 +1,103 @@
#pragma once
#include <miniwin.h>
#include <miniwin/ddraw.h>
struct DummySurfaceImpl : public IDirectDrawSurface3 {
// IUnknown interface
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
// IDirectDrawSurface interface
HRESULT AddAttachedSurface(IDirectDrawSurface* lpDDSAttachedSurface) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Blt(
LPRECT lpDestRect,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFlags dwFlags,
LPDDBLTFX lpDDBltFx
) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT BltFast(DWORD dwX, DWORD dwY, IDirectDrawSurface* lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans)
override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Flip(IDirectDrawSurface* lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, IDirectDrawSurface** lplpDDAttachedSurface) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT GetDC(HDC* lphDC) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT GetSurfaceDesc(DDSURFACEDESC* lpDDSurfaceDesc) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT IsLost() override { return DD_OK; }
HRESULT Lock(LPRECT lpDestRect, DDSURFACEDESC* lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT ReleaseDC(HDC hDC) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Restore() override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT SetClipper(IDirectDrawClipper* lpDDClipper) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
HRESULT Unlock(LPVOID lpSurfaceData) override
{
MINIWIN_NOT_IMPLEMENTED();
return DDERR_GENERIC;
}
};

View File

@ -0,0 +1,45 @@
#pragma once
#include <SDL3/SDL.h>
#include <ddsurface_impl.h>
#include <miniwin/ddraw.h>
struct FrameBufferImpl : public IDirectDrawSurface3 {
FrameBufferImpl();
~FrameBufferImpl() override;
// IUnknown interface
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
// IDirectDrawSurface interface
HRESULT AddAttachedSurface(IDirectDrawSurface* lpDDSAttachedSurface) override;
HRESULT Blt(
LPRECT lpDestRect,
IDirectDrawSurface* lpDDSrcSurface,
LPRECT lpSrcRect,
DDBltFlags dwFlags,
LPDDBLTFX lpDDBltFx
) override;
HRESULT BltFast(DWORD dwX, DWORD dwY, IDirectDrawSurface* lpDDSrcSurface, LPRECT lpSrcRect, DDBltFastFlags dwTrans)
override;
HRESULT Flip(IDirectDrawSurface* lpDDSurfaceTargetOverride, DDFlipFlags dwFlags) override;
HRESULT GetAttachedSurface(LPDDSCAPS lpDDSCaps, IDirectDrawSurface** lplpDDAttachedSurface) override;
HRESULT GetDC(HDC* lphDC) override;
HRESULT GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) override;
HRESULT GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) override;
HRESULT GetSurfaceDesc(DDSURFACEDESC* lpDDSurfaceDesc) override;
HRESULT IsLost() override;
HRESULT Lock(LPRECT lpDestRect, DDSURFACEDESC* lpDDSurfaceDesc, DDLockFlags dwFlags, HANDLE hEvent) override;
HRESULT ReleaseDC(HDC hDC) override;
HRESULT Restore() override;
HRESULT SetClipper(IDirectDrawClipper* lpDDClipper) override;
HRESULT SetColorKey(DDColorKeyFlags dwFlags, LPDDCOLORKEY lpDDColorKey) override;
HRESULT SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) override;
HRESULT Unlock(LPVOID lpSurfaceData) override;
void Upload(void* pixels, int pitch);
private:
SDL_Surface* m_readBackBuffer;
SDL_Texture* m_backBuffer;
SDL_Texture* m_uploadBuffer;
};