diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index 9b7d321e..bf184541 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -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()) { diff --git a/miniwin/CMakeLists.txt b/miniwin/CMakeLists.txt index 9c8d2793..1071afcf 100644 --- a/miniwin/CMakeLists.txt +++ b/miniwin/CMakeLists.txt @@ -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) diff --git a/miniwin/include/miniwin/d3drm.h b/miniwin/include/miniwin/d3drm.h index 28260a41..35528ff5 100644 --- a/miniwin/include/miniwin/d3drm.h +++ b/miniwin/include/miniwin/d3drm.h @@ -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; diff --git a/miniwin/include/miniwin/ddraw.h b/miniwin/include/miniwin/ddraw.h index 55a95f8f..773a2595 100644 --- a/miniwin/include/miniwin/ddraw.h +++ b/miniwin/include/miniwin/ddraw.h @@ -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; diff --git a/miniwin/src/d3drm/backends/opengl1/renderer.cpp b/miniwin/src/d3drm/backends/opengl1/renderer.cpp index 36ba5fa1..7facbb96 100644 --- a/miniwin/src/d3drm/backends/opengl1/renderer.cpp +++ b/miniwin/src/d3drm/backends/opengl1/renderer.cpp @@ -141,7 +141,6 @@ void OpenGL1Renderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* t Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture) { auto texture = static_cast(iTexture); - auto surface = static_cast(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; } diff --git a/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp b/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp index 7ec0ff35..cb824437 100644 --- a/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp +++ b/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp @@ -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(iTexture); - auto surface = static_cast(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; diff --git a/miniwin/src/d3drm/backends/software/renderer.cpp b/miniwin/src/d3drm/backends/software/renderer.cpp index 8882098e..be4e0938 100644 --- a/miniwin/src/d3drm/backends/software/renderer.cpp +++ b/miniwin/src/d3drm/backends/software/renderer.cpp @@ -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(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(finalColor); - break; - case 2: - *reinterpret_cast(pixelAddr) = static_cast(finalColor); - break; - case 4: - *reinterpret_cast(pixelAddr) = finalColor; - break; - } + *reinterpret_cast(pixelAddr) = finalColor; } } } @@ -517,7 +481,6 @@ void Direct3DRMSoftwareRenderer::AddTextureDestroyCallback(Uint32 id, IDirect3DR Uint32 Direct3DRMSoftwareRenderer::GetTextureId(IDirect3DRMTexture* iTexture) { auto texture = static_cast(iTexture); - auto surface = static_cast(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; } diff --git a/miniwin/src/d3drm/d3drm.cpp b/miniwin/src/d3drm/d3drm.cpp index d6e67d39..35f6d449 100644 --- a/miniwin/src/d3drm/d3drm.cpp +++ b/miniwin/src/d3drm/d3drm.cpp @@ -160,14 +160,18 @@ HRESULT Direct3DRMImpl::CreateDeviceFromSurface( HRESULT Direct3DRMImpl::CreateTexture(D3DRMIMAGE* image, IDirect3DRMTexture2** outTexture) { - *outTexture = static_cast(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(new Direct3DRMTextureImpl(surface)); + *outTexture = dynamic_cast(surface); + if (!*outTexture) { + return DDERR_GENERIC; + } + surface->AddRef(); return DD_OK; } diff --git a/miniwin/src/d3drm/d3drmtexture.cpp b/miniwin/src/d3drm/d3drmtexture.cpp index c0a2ad59..98c25782 100644 --- a/miniwin/src/d3drm/d3drmtexture.cpp +++ b/miniwin/src/d3drm/d3drmtexture.cpp @@ -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(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; +} diff --git a/miniwin/src/d3drm/d3drmviewport.cpp b/miniwin/src/d3drm/d3drmviewport.cpp index c87866a7..89590a8d 100644 --- a/miniwin/src/d3drm/d3drmviewport.cpp +++ b/miniwin/src/d3drm/d3drmviewport.cpp @@ -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; } diff --git a/miniwin/src/ddraw/ddraw.cpp b/miniwin/src/ddraw/ddraw.cpp index 6789c5c4..94b6ffbf 100644 --- a/miniwin/src/ddraw/ddraw.cpp +++ b/miniwin/src/ddraw/ddraw.cpp @@ -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 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(new DummySurfaceImpl); + return DD_OK; + } + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) == DDSCAPS_PRIMARYSURFACE) { + DDFrameBuffer = new FrameBufferImpl(); + *lplpDDSurface = static_cast(DDFrameBuffer); + return DD_OK; + } + if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) == DDSCAPS_3DDEVICE) { + DDFrameBuffer->AddRef(); + *lplpDDSurface = static_cast(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(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(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(new DirectDrawSurfaceImpl(width, height, format)); + + if (isTexture) { + *lplpDDSurface = static_cast(new Direct3DRMTextureImpl(width, height, format)); + } + else { + *lplpDDSurface = static_cast(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; diff --git a/miniwin/src/ddraw/ddsurface.cpp b/miniwin/src/ddraw/ddsurface.cpp index f218bd75..8c68b1d8 100644 --- a/miniwin/src/ddraw/ddsurface.cpp +++ b/miniwin/src/ddraw/ddsurface.cpp @@ -5,26 +5,17 @@ #include -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(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(lpDDSrcSurface); - if (!srcSurface || !srcSurface->m_surface) { + auto* other = dynamic_cast(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(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; } diff --git a/miniwin/src/ddraw/framebuffer.cpp b/miniwin/src/ddraw/framebuffer.cpp new file mode 100644 index 00000000..877de883 --- /dev/null +++ b/miniwin/src/ddraw/framebuffer.cpp @@ -0,0 +1,226 @@ +#include "ddpalette_impl.h" +#include "ddraw_impl.h" +#include "dummysurface_impl.h" +#include "framebuffer_impl.h" +#include "miniwin.h" + +#include + +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(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(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(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(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); +} diff --git a/miniwin/src/internal/d3drm_impl.h b/miniwin/src/internal/d3drm_impl.h index c4426f1e..5c83506f 100644 --- a/miniwin/src/internal/d3drm_impl.h +++ b/miniwin/src/internal/d3drm_impl.h @@ -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; diff --git a/miniwin/src/internal/d3drmrenderer_software.h b/miniwin/src/internal/d3drmrenderer_software.h index 28347bc7..3bb982c4 100644 --- a/miniwin/src/internal/d3drmrenderer_software.h +++ b/miniwin/src/internal/d3drmrenderer_software.h @@ -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; diff --git a/miniwin/src/internal/d3drmtexture_impl.h b/miniwin/src/internal/d3drmtexture_impl.h index e81c3884..fabc4a71 100644 --- a/miniwin/src/internal/d3drmtexture_impl.h +++ b/miniwin/src/internal/d3drmtexture_impl.h @@ -1,13 +1,47 @@ #pragma once #include "d3drmobject_impl.h" +#include "miniwin/ddraw.h" -struct Direct3DRMTextureImpl : public Direct3DRMObjectBaseImpl { - Direct3DRMTextureImpl(D3DRMIMAGE* image); - Direct3DRMTextureImpl(IDirectDrawSurface* surface); +#include + +struct Direct3DRMTextureImpl : public Direct3DRMObjectBaseImpl, 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; }; diff --git a/miniwin/src/internal/ddraw_impl.h b/miniwin/src/internal/ddraw_impl.h index 00256835..22f498d7 100644 --- a/miniwin/src/internal/ddraw_impl.h +++ b/miniwin/src/internal/ddraw_impl.h @@ -1,14 +1,14 @@ #pragma once #include "d3drmrenderer.h" +#include "framebuffer_impl.h" #include "miniwin/d3d.h" #include "miniwin/ddraw.h" #include 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; diff --git a/miniwin/src/internal/ddsurface_impl.h b/miniwin/src/internal/ddsurface_impl.h index 3a149b91..ba58c994 100644 --- a/miniwin/src/internal/ddsurface_impl.h +++ b/miniwin/src/internal/ddsurface_impl.h @@ -4,42 +4,36 @@ #include 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; }; diff --git a/miniwin/src/internal/dummysurface_impl.h b/miniwin/src/internal/dummysurface_impl.h new file mode 100644 index 00000000..9502adcb --- /dev/null +++ b/miniwin/src/internal/dummysurface_impl.h @@ -0,0 +1,103 @@ +#pragma once + +#include +#include + +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; + } +}; diff --git a/miniwin/src/internal/framebuffer_impl.h b/miniwin/src/internal/framebuffer_impl.h new file mode 100644 index 00000000..414796e1 --- /dev/null +++ b/miniwin/src/internal/framebuffer_impl.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include + +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; +};