From c63d725b641eade5cc0be158ea933a5ead68ed36 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Fri, 4 Jul 2025 00:20:31 +0200 Subject: [PATCH] Port WipeDown and Window to use DDBLT_COLORFILL (#506) --- .../src/common/mxtransitionmanager.cpp | 116 ++++-------------- .../src/d3drm/backends/citro3d/renderer.cpp | 85 +++++++------ .../src/d3drm/backends/directx9/actual.cpp | 73 +++++------ miniwin/src/d3drm/backends/directx9/actual.h | 2 +- .../src/d3drm/backends/directx9/renderer.cpp | 4 +- miniwin/src/d3drm/backends/opengl1/actual.cpp | 33 +++-- miniwin/src/d3drm/backends/opengl1/actual.h | 3 +- .../src/d3drm/backends/opengl1/renderer.cpp | 9 +- .../src/d3drm/backends/opengles2/renderer.cpp | 43 ++++--- .../src/d3drm/backends/sdl3gpu/renderer.cpp | 44 ++++--- .../src/d3drm/backends/software/renderer.cpp | 25 +++- miniwin/src/ddraw/framebuffer.cpp | 20 ++- miniwin/src/internal/d3drmrenderer.h | 2 +- miniwin/src/internal/d3drmrenderer_citro3d.h | 2 +- miniwin/src/internal/d3drmrenderer_directx9.h | 2 +- miniwin/src/internal/d3drmrenderer_opengl1.h | 2 +- .../src/internal/d3drmrenderer_opengles2.h | 2 +- miniwin/src/internal/d3drmrenderer_sdl3gpu.h | 2 +- miniwin/src/internal/d3drmrenderer_software.h | 2 +- 19 files changed, 248 insertions(+), 223 deletions(-) diff --git a/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp b/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp index 8c2c994d..6fd211c6 100644 --- a/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp @@ -400,47 +400,18 @@ void MxTransitionManager::WipeDownTransition() return; } - DDSURFACEDESC ddsd; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); + RECT fillRect = g_fullScreenRect; + // For each of the 240 animation ticks, blank out two scanlines + // starting at the top of the screen. + fillRect.bottom = 2 * (m_animationTimer + 1); - HRESULT res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - if (res == DDERR_SURFACELOST) { - m_ddSurface->Restore(); - res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - } + DDBLTFX bltFx = {}; + bltFx.dwSize = sizeof(bltFx); + bltFx.dwFillColor = 0xFF000000; - if (res == DD_OK) { - SubmitCopyRect(&ddsd); + m_ddSurface->Blt(&fillRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx); - // For each of the 240 animation ticks, blank out two scanlines - // starting at the top of the screen. - MxU8* line = (MxU8*) ddsd.lpSurface + 2 * ddsd.lPitch * m_animationTimer; - - if (ddsd.ddpfPixelFormat.dwRGBBitCount == 32) { - MxU32* pixels = (MxU32*) line; - int pixelsPerLine = ddsd.lPitch / 4; - for (int i = 0; i < pixelsPerLine; i++) { - pixels[i] = 0xFF000000; - } - line += ddsd.lPitch; - pixels = (MxU32*) line; - for (int i = 0; i < pixelsPerLine; i++) { - pixels[i] = 0xFF000000; - } - } - else { - memset(line, 0, ddsd.lPitch); - - line += ddsd.lPitch; - memset(line, 0, ddsd.lPitch); - } - - SetupCopyRect(&ddsd); - m_ddSurface->Unlock(ddsd.lpSurface); - - m_animationTimer++; - } + m_animationTimer++; } // FUNCTION: LEGO1 0x1004c270 @@ -452,65 +423,28 @@ void MxTransitionManager::WindowsTransition() return; } - DDSURFACEDESC ddsd; - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); + DDBLTFX bltFx = {}; + bltFx.dwSize = sizeof(bltFx); + bltFx.dwFillColor = 0xFF000000; - HRESULT res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - if (res == DDERR_SURFACELOST) { - m_ddSurface->Restore(); - res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - } + int top = m_animationTimer; + int bottom = 480 - m_animationTimer - 1; + int left = m_animationTimer; + int right = 639 - m_animationTimer; - if (res == DD_OK) { - SubmitCopyRect(&ddsd); + RECT topRect = {0, top, 640, top + 1}; + m_ddSurface->Blt(&topRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx); - MxU8* line = (MxU8*) ddsd.lpSurface + m_animationTimer * ddsd.lPitch; + RECT bottomRect = {0, bottom, 640, bottom + 1}; + m_ddSurface->Blt(&bottomRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx); - MxS32 bytesPerPixel = ddsd.ddpfPixelFormat.dwRGBBitCount / 8; + RECT leftRect = {left, top + 1, left + 1, bottom}; + m_ddSurface->Blt(&leftRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx); - if (bytesPerPixel == 4) { - MxU32* pixels = (MxU32*) line; - for (int i = 0; i < 640; i++) { - pixels[i] = 0xFF000000; - } + RECT rightRect = {right, top + 1, right + 1, bottom}; + m_ddSurface->Blt(&rightRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx); - for (MxS32 i = m_animationTimer + 1; i < 480 - m_animationTimer - 1; i++) { - line += ddsd.lPitch; - pixels = (MxU32*) line; - pixels[m_animationTimer] = 0xFF000000; - pixels[639 - m_animationTimer] = 0xFF000000; - } - - if (m_animationTimer < 240 - 1) { - line += ddsd.lPitch; - pixels = (MxU32*) line; - for (int i = 0; i < 640; i++) { - pixels[i] = 0xFF000000; - } - } - } - else { - memset(line, 0, 640 * bytesPerPixel); - - for (MxS32 i = m_animationTimer + 1; i < 480 - m_animationTimer - 1; i++) { - line += ddsd.lPitch; - - memset(line + m_animationTimer * bytesPerPixel, 0, bytesPerPixel); - memset(line + (639 - m_animationTimer) * bytesPerPixel, 0, bytesPerPixel); - } - - if (m_animationTimer < 240 - 1) { - line += ddsd.lPitch; - memset(line, 0, 640 * bytesPerPixel); - } - } - - SetupCopyRect(&ddsd); - m_ddSurface->Unlock(ddsd.lpSurface); - - m_animationTimer++; - } + m_animationTimer++; } // FUNCTION: LEGO1 0x1004c3e0 diff --git a/miniwin/src/d3drm/backends/citro3d/renderer.cpp b/miniwin/src/d3drm/backends/citro3d/renderer.cpp index f076cf70..f71f9255 100644 --- a/miniwin/src/d3drm/backends/citro3d/renderer.cpp +++ b/miniwin/src/d3drm/backends/citro3d/renderer.cpp @@ -443,6 +443,32 @@ void ConvertMatrix(const D3DRMMATRIX4D in, C3D_Mtx* out) } } +void SetMaterialAppearance( + const FColor& color, + float shininess, + int uLoc_meshColor, + int uLoc_shininess, + C3D_Tex* textures +) +{ + C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_meshColor, color.r, color.g, color.b, color.a); + C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_shininess, shininess, 0.0f, 0.0f, 0.0f); + + C3D_TexEnv* env = C3D_GetTexEnv(0); + C3D_TexEnvInit(env); + + if (textures) { + C3D_TexBind(0, textures); + C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); + C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); + } + else { + C3D_TexBind(0, nullptr); + C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); + C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); + } +} + void Citro3DRenderer::SubmitDraw( DWORD meshId, const D3DRMMATRIX4D& modelViewMatrix, @@ -462,32 +488,17 @@ void Citro3DRenderer::SubmitDraw( BufInfo_Init(bufInfo); BufInfo_Add(bufInfo, mesh.vbo, sizeof(D3DRMVERTEX), 3, 0x210); - C3D_FVUnifSet( - GPU_VERTEX_SHADER, + SetMaterialAppearance( + {appearance.color.r / 255.0f, + appearance.color.g / 255.0f, + appearance.color.b / 255.0f, + appearance.color.a / 255.0f}, + appearance.shininess, uLoc_meshColor, - appearance.color.r / 255.0f, - appearance.color.g / 255.0f, - appearance.color.b / 255.0f, - appearance.color.a / 255.0f + uLoc_shininess, + appearance.textureId != NO_TEXTURE_ID ? &m_textures[appearance.textureId].c3dTex : nullptr ); - C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_shininess, appearance.shininess / 255.0f, 0.0f, 0.0f, 0.0f); - - if (appearance.textureId != NO_TEXTURE_ID) { - C3D_TexBind(0, &m_textures[appearance.textureId].c3dTex); - C3D_TexEnv* env = C3D_GetTexEnv(0); - C3D_TexEnvInit(env); - C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); - C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); - } - else { - C3D_TexBind(0, nullptr); - C3D_TexEnv* env = C3D_GetTexEnv(0); - C3D_TexEnvInit(env); - C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); - C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); - } - C3D_DrawArrays(GPU_TRIANGLES, 0, mesh.vertexCount); } @@ -519,7 +530,7 @@ void Citro3DRenderer::Flip() g_rendering = false; } -void Citro3DRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void Citro3DRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) { C3D_AlphaBlend(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); StartFrame(); @@ -545,16 +556,9 @@ void Citro3DRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, con C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightClr + 1, 0.0f, 0.0f, 0.0f, 0.0f); C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightClr + 2, 1.0f, 1.0f, 1.0f, 1.0f); // Ambient - C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_shininess, 0.0f, 0.0f, 0.0f, 0.0f); - C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_meshColor, 1.0f, 1.0f, 1.0f, 1.0f); + C3DTextureCacheEntry* texture = (textureId != NO_TEXTURE_ID) ? &m_textures[textureId] : nullptr; - C3DTextureCacheEntry& texture = m_textures[textureId]; - - C3D_TexBind(0, &texture.c3dTex); - C3D_TexEnv* env = C3D_GetTexEnv(0); - C3D_TexEnvInit(env); - C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); - C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); + SetMaterialAppearance(color, 0.0f, uLoc_meshColor, uLoc_shininess, texture ? &texture->c3dTex : nullptr); float scale = m_viewportTransform.scale; @@ -563,10 +567,17 @@ void Citro3DRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, con float x2 = x1 + static_cast(dstRect.w); float y2 = y1 + static_cast(dstRect.h); - float u0 = (srcRect.x * scale) / texture.width; - float u1 = ((srcRect.x + srcRect.w) * scale) / texture.width; - float v0 = (srcRect.y * scale) / texture.height; - float v1 = ((srcRect.y + srcRect.h) * scale) / texture.height; + float u0 = 0.0f; + float u1 = 0.0f; + float v0 = 0.0f; + float v1 = 0.0f; + + if (texture) { + u0 = (srcRect.x * scale) / texture->width; + u1 = ((srcRect.x + srcRect.w) * scale) / texture->width; + v0 = (srcRect.y * scale) / texture->height; + v1 = ((srcRect.y + srcRect.h) * scale) / texture->height; + } C3D_ImmDrawBegin(GPU_TRIANGLES); diff --git a/miniwin/src/d3drm/backends/directx9/actual.cpp b/miniwin/src/d3drm/backends/directx9/actual.cpp index 33dc2864..4ccea210 100644 --- a/miniwin/src/d3drm/backends/directx9/actual.cpp +++ b/miniwin/src/d3drm/backends/directx9/actual.cpp @@ -297,44 +297,23 @@ D3DMATRIX ToD3DMATRIX(const Matrix4x4& in) return out; } -void Actual_SubmitDraw( - const D3D9MeshCacheEntry* mesh, - const Matrix4x4* modelViewMatrix, - const Matrix4x4* worldMatrix, - const Matrix4x4* viewMatrix, - const Matrix3x3* normalMatrix, - const Appearance* appearance, - IDirect3DTexture9* texture -) +void SetMaterialAndTexture(const FColor& color, float shininess, IDirect3DTexture9* texture) { - D3DMATRIX proj = ToD3DMATRIX(g_projection); - g_device->SetTransform(D3DTS_PROJECTION, &proj); - D3DMATRIX view = ToD3DMATRIX(*viewMatrix); - g_device->SetTransform(D3DTS_VIEW, &view); - D3DMATRIX world = ToD3DMATRIX(*worldMatrix); - g_device->SetTransform(D3DTS_WORLD, &world); - D3DMATERIAL9 mat = {}; - mat.Diffuse.r = appearance->color.r / 255.0f; - mat.Diffuse.g = appearance->color.g / 255.0f; - mat.Diffuse.b = appearance->color.b / 255.0f; - mat.Diffuse.a = appearance->color.a / 255.0f; + mat.Diffuse.r = color.r / 255.0f; + mat.Diffuse.g = color.g / 255.0f; + mat.Diffuse.b = color.b / 255.0f; + mat.Diffuse.a = color.a / 255.0f; mat.Ambient = mat.Diffuse; - if (appearance->shininess != 0) { + if (shininess != 0) { g_device->SetRenderState(D3DRS_SPECULARENABLE, TRUE); - mat.Specular.r = 1.0f; - mat.Specular.g = 1.0f; - mat.Specular.b = 1.0f; - mat.Specular.a = 1.0f; - mat.Power = appearance->shininess; + mat.Specular = {1.0f, 1.0f, 1.0f, 1.0f}; + mat.Power = shininess; } else { g_device->SetRenderState(D3DRS_SPECULARENABLE, FALSE); - mat.Specular.r = 0.0f; - mat.Specular.g = 0.0f; - mat.Specular.b = 0.0f; - mat.Specular.a = 0.0f; + mat.Specular = {0.0f, 0.0f, 0.0f, 0.0f}; mat.Power = 0.0f; } @@ -352,6 +331,33 @@ void Actual_SubmitDraw( else { g_device->SetTexture(0, nullptr); } +} + +void Actual_SubmitDraw( + const D3D9MeshCacheEntry* mesh, + const Matrix4x4* modelViewMatrix, + const Matrix4x4* worldMatrix, + const Matrix4x4* viewMatrix, + const Matrix3x3* normalMatrix, + const Appearance* appearance, + IDirect3DTexture9* texture +) +{ + D3DMATRIX proj = ToD3DMATRIX(g_projection); + g_device->SetTransform(D3DTS_PROJECTION, &proj); + D3DMATRIX view = ToD3DMATRIX(*viewMatrix); + g_device->SetTransform(D3DTS_VIEW, &view); + D3DMATRIX world = ToD3DMATRIX(*worldMatrix); + g_device->SetTransform(D3DTS_WORLD, &world); + + SetMaterialAndTexture( + {appearance->color.r / 255.0f, + appearance->color.g / 255.0f, + appearance->color.b / 255.0f, + appearance->color.a / 255.0f}, + appearance->shininess, + texture + ); g_device->SetRenderState(D3DRS_SHADEMODE, mesh->flat ? D3DSHADE_FLAT : D3DSHADE_GOURAUD); @@ -367,7 +373,7 @@ uint32_t Actual_Flip() return g_device->Present(nullptr, nullptr, nullptr, nullptr); } -void Actual_Draw2DImage(IDirect3DTexture9* texture, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void Actual_Draw2DImage(IDirect3DTexture9* texture, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) { StartScene(); @@ -405,10 +411,7 @@ void Actual_Draw2DImage(IDirect3DTexture9* texture, const SDL_Rect& srcRect, con g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - g_device->SetTexture(0, texture); - g_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - g_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - g_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + SetMaterialAndTexture(color, 0, texture); D3DSURFACE_DESC texDesc; texture->GetLevelDesc(0, &texDesc); diff --git a/miniwin/src/d3drm/backends/directx9/actual.h b/miniwin/src/d3drm/backends/directx9/actual.h index e3369ec9..bf09cb00 100644 --- a/miniwin/src/d3drm/backends/directx9/actual.h +++ b/miniwin/src/d3drm/backends/directx9/actual.h @@ -78,5 +78,5 @@ void Actual_SubmitDraw( void Actual_Resize(int width, int height, const ViewportTransform& viewportTransform); void Actual_Clear(float r, float g, float b); uint32_t Actual_Flip(); -void Actual_Draw2DImage(IDirect3DTexture9* texture, const SDL_Rect& srcRect, const SDL_Rect& dstRect); +void Actual_Draw2DImage(IDirect3DTexture9* texture, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color); uint32_t Actual_Download(SDL_Surface* target); diff --git a/miniwin/src/d3drm/backends/directx9/renderer.cpp b/miniwin/src/d3drm/backends/directx9/renderer.cpp index 2701528b..5c8a2354 100644 --- a/miniwin/src/d3drm/backends/directx9/renderer.cpp +++ b/miniwin/src/d3drm/backends/directx9/renderer.cpp @@ -273,9 +273,9 @@ void DirectX9Renderer::Flip() Actual_Flip(); } -void DirectX9Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void DirectX9Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) { - Actual_Draw2DImage(m_textures[textureId].dxTexture, srcRect, dstRect); + Actual_Draw2DImage(m_textures[textureId].dxTexture, srcRect, dstRect, color); } void DirectX9Renderer::SetDither(bool dither) diff --git a/miniwin/src/d3drm/backends/opengl1/actual.cpp b/miniwin/src/d3drm/backends/opengl1/actual.cpp index d75eb04e..b1a464d5 100644 --- a/miniwin/src/d3drm/backends/opengl1/actual.cpp +++ b/miniwin/src/d3drm/backends/opengl1/actual.cpp @@ -285,9 +285,10 @@ void GL11_Clear(float r, float g, float b) } void GL11_Draw2DImage( - GLTextureCacheEntry& cache, + const GLTextureCacheEntry* cache, const SDL_Rect& srcRect, const SDL_Rect& dstRect, + const FColor& color, float left, float right, float bottom, @@ -296,6 +297,7 @@ void GL11_Draw2DImage( { glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); + glShadeModel(GL_FLAT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -306,17 +308,28 @@ void GL11_Draw2DImage( glLoadIdentity(); glDisable(GL_LIGHTING); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glColor4f(color.r, color.g, color.b, color.a); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, cache.glTextureId); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + float u1 = 0; + float v1 = 0; + float u2 = 0; + float v2 = 0; - float u1 = srcRect.x / cache.width; - float v1 = srcRect.y / cache.height; - float u2 = (srcRect.x + srcRect.w) / cache.width; - float v2 = (srcRect.y + srcRect.h) / cache.height; + if (cache) { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, cache->glTextureId); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + u1 = srcRect.x / cache->width; + v1 = srcRect.y / cache->height; + u2 = (srcRect.x + srcRect.w) / cache->width; + v2 = (srcRect.y + srcRect.h) / cache->height; + } + else { + glDisable(GL_TEXTURE_2D); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } float x1 = (float) dstRect.x; float y1 = (float) dstRect.y; diff --git a/miniwin/src/d3drm/backends/opengl1/actual.h b/miniwin/src/d3drm/backends/opengl1/actual.h index 7a6a4432..9460119c 100644 --- a/miniwin/src/d3drm/backends/opengl1/actual.h +++ b/miniwin/src/d3drm/backends/opengl1/actual.h @@ -79,9 +79,10 @@ void GL11_SubmitDraw( void GL11_Resize(int width, int height); void GL11_Clear(float r, float g, float b); void GL11_Draw2DImage( - GLTextureCacheEntry& cache, + const GLTextureCacheEntry* cache, const SDL_Rect& srcRect, const SDL_Rect& dstRect, + const FColor& color, float left, float right, float bottom, diff --git a/miniwin/src/d3drm/backends/opengl1/renderer.cpp b/miniwin/src/d3drm/backends/opengl1/renderer.cpp index 4c6aacf9..8c43d14a 100644 --- a/miniwin/src/d3drm/backends/opengl1/renderer.cpp +++ b/miniwin/src/d3drm/backends/opengl1/renderer.cpp @@ -372,7 +372,7 @@ void OpenGL1Renderer::Flip() } } -void OpenGL1Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void OpenGL1Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) { m_dirty = true; @@ -381,7 +381,12 @@ void OpenGL1Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, con float top = -m_viewportTransform.offsetY / m_viewportTransform.scale; float bottom = (m_height - m_viewportTransform.offsetY) / m_viewportTransform.scale; - GL11_Draw2DImage(m_textures[textureId], srcRect, dstRect, left, right, bottom, top); + const GLTextureCacheEntry* texture = nullptr; + if (textureId != NO_TEXTURE_ID) { + texture = &m_textures[textureId]; + } + + GL11_Draw2DImage(texture, srcRect, dstRect, color, left, right, bottom, top); } void OpenGL1Renderer::SetDither(bool dither) diff --git a/miniwin/src/d3drm/backends/opengles2/renderer.cpp b/miniwin/src/d3drm/backends/opengles2/renderer.cpp index 28466bea..850e8b6e 100644 --- a/miniwin/src/d3drm/backends/opengles2/renderer.cpp +++ b/miniwin/src/d3drm/backends/opengles2/renderer.cpp @@ -598,7 +598,7 @@ void OpenGLES2Renderer::Flip() } } -void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) { m_dirty = true; @@ -607,25 +607,37 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c glUseProgram(m_shaderProgram); - float color[] = {1.0f, 1.0f, 1.0f, 1.0f}; + float ambient[] = {1.0f, 1.0f, 1.0f, 1.0f}; float blank[] = {0.0f, 0.0f, 0.0f, 0.0f}; - glUniform4fv(u_lightLocs[0][0], 1, color); + glUniform4fv(u_lightLocs[0][0], 1, ambient); glUniform4fv(u_lightLocs[0][1], 1, blank); glUniform4fv(u_lightLocs[0][2], 1, blank); glUniform1i(m_lightCountLoc, 1); - glUniform4f(m_colorLoc, 1.0f, 1.0f, 1.0f, 1.0f); + glUniform4f(m_colorLoc, color.r, color.g, color.b, color.a); glUniform1f(m_shinLoc, 0.0f); - const GLES2TextureCacheEntry& texture = m_textures[textureId]; - float scaleX = static_cast(dstRect.w) / srcRect.w; - float scaleY = static_cast(dstRect.h) / srcRect.h; - SDL_Rect expandedDstRect = { - static_cast(std::round(dstRect.x - srcRect.x * scaleX)), - static_cast(std::round(dstRect.y - srcRect.y * scaleY)), - static_cast(std::round(texture.width * scaleX)), - static_cast(std::round(texture.height * scaleY)) - }; + SDL_Rect expandedDstRect; + if (textureId != NO_TEXTURE_ID) { + const GLES2TextureCacheEntry& texture = m_textures[textureId]; + float scaleX = static_cast(dstRect.w) / srcRect.w; + float scaleY = static_cast(dstRect.h) / srcRect.h; + expandedDstRect = { + static_cast(std::round(dstRect.x - srcRect.x * scaleX)), + static_cast(std::round(dstRect.y - srcRect.y * scaleY)), + static_cast(std::round(texture.width * scaleX)), + static_cast(std::round(texture.height * scaleY)) + }; + + glActiveTexture(GL_TEXTURE0); + glUniform1i(m_useTextureLoc, 1); + glBindTexture(GL_TEXTURE_2D, texture.glTextureId); + glUniform1i(m_textureLoc, 0); + } + else { + expandedDstRect = dstRect; + glUniform1i(m_useTextureLoc, 0); + } D3DRMMATRIX4D modelView, projection; Create2DTransformMatrix( @@ -645,11 +657,6 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glActiveTexture(GL_TEXTURE0); - glUniform1i(m_useTextureLoc, 1); - glBindTexture(GL_TEXTURE_2D, texture.glTextureId); - glUniform1i(m_textureLoc, 0); - glEnable(GL_SCISSOR_TEST); glScissor( static_cast(std::round(dstRect.x * m_viewportTransform.scale + m_viewportTransform.offsetX)), diff --git a/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp b/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp index 69b326b6..c6324f03 100644 --- a/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp +++ b/miniwin/src/d3drm/backends/sdl3gpu/renderer.cpp @@ -884,24 +884,37 @@ void Direct3DRMSDL3GPURenderer::Flip() m_cmdbuf = nullptr; } -void Direct3DRMSDL3GPURenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void Direct3DRMSDL3GPURenderer::Draw2DImage( + Uint32 textureId, + const SDL_Rect& srcRect, + const SDL_Rect& dstRect, + FColor color +) { if (!m_renderPass) { StartRenderPass(0, 0, 0, false); } SDL_BindGPUGraphicsPipeline(m_renderPass, m_uiPipeline); - const SDL3TextureCache& tex = m_textures[textureId]; - - auto surface = static_cast(tex.texture->m_surface); - float scaleX = static_cast(dstRect.w) / srcRect.w; - float scaleY = static_cast(dstRect.h) / srcRect.h; - SDL_Rect expandedDstRect = { - static_cast(std::round(dstRect.x - srcRect.x * scaleX)), - static_cast(std::round(dstRect.y - srcRect.y * scaleY)), - static_cast(std::round(static_cast(surface->m_surface->w) * scaleX)), - static_cast(std::round(static_cast(surface->m_surface->h) * scaleY)), - }; + SDL_GPUTexture* tex; + SDL_Rect expandedDstRect; + if (textureId == NO_TEXTURE_ID) { + expandedDstRect = dstRect; + tex = m_dummyTexture; + } + else { + SDL3TextureCache& cache = m_textures[textureId]; + tex = cache.gpuTexture; + auto surface = static_cast(cache.texture->m_surface); + float scaleX = static_cast(dstRect.w) / srcRect.w; + float scaleY = static_cast(dstRect.h) / srcRect.h; + expandedDstRect = { + static_cast(std::round(dstRect.x - srcRect.x * scaleX)), + static_cast(std::round(dstRect.y - srcRect.y * scaleY)), + static_cast(std::round(static_cast(surface->m_surface->w) * scaleX)), + static_cast(std::round(static_cast(surface->m_surface->h) * scaleY)), + }; + } Create2DTransformMatrix( expandedDstRect, @@ -916,11 +929,14 @@ void Direct3DRMSDL3GPURenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& sr SceneLight fullBright = {{1, 1, 1, 1}, {0, 0, 0}, 0, {0, 0, 0}, 0}; memcpy(&m_fragmentShadingData.lights, &fullBright, sizeof(SceneLight)); m_fragmentShadingData.lightCount = 1; - m_fragmentShadingData.color = {0xff, 0xff, 0xff, 0xff}; + m_fragmentShadingData.color.r = static_cast(color.r * 255); + m_fragmentShadingData.color.g = static_cast(color.g * 255); + m_fragmentShadingData.color.b = static_cast(color.b * 255); + m_fragmentShadingData.color.a = static_cast(color.a * 255); m_fragmentShadingData.shininess = 0.0f; m_fragmentShadingData.useTexture = 1; - SDL_GPUTextureSamplerBinding samplerBinding = {tex.gpuTexture, m_uiSampler}; + SDL_GPUTextureSamplerBinding samplerBinding = {tex, m_uiSampler}; SDL_BindGPUFragmentSamplers(m_renderPass, 0, &samplerBinding, 1); SDL_PushGPUVertexUniformData(m_cmdbuf, 0, &m_uniforms, sizeof(m_uniforms)); SDL_PushGPUFragmentUniformData(m_cmdbuf, 0, &m_fragmentShadingData, sizeof(m_fragmentShadingData)); diff --git a/miniwin/src/d3drm/backends/software/renderer.cpp b/miniwin/src/d3drm/backends/software/renderer.cpp index b4fab671..2ae8697e 100644 --- a/miniwin/src/d3drm/backends/software/renderer.cpp +++ b/miniwin/src/d3drm/backends/software/renderer.cpp @@ -774,16 +774,35 @@ void Direct3DRMSoftwareRenderer::Flip() SDL_RenderPresent(m_renderer); } -void Direct3DRMSoftwareRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) +void Direct3DRMSoftwareRenderer::Draw2DImage( + Uint32 textureId, + const SDL_Rect& srcRect, + const SDL_Rect& dstRect, + FColor color +) { - SDL_Surface* surface = m_textures[textureId].cached; - SDL_UnlockSurface(surface); SDL_Rect centeredRect = { static_cast(dstRect.x * m_viewportTransform.scale + m_viewportTransform.offsetX), static_cast(dstRect.y * m_viewportTransform.scale + m_viewportTransform.offsetY), static_cast(dstRect.w * m_viewportTransform.scale), static_cast(dstRect.h * m_viewportTransform.scale), }; + + if (textureId == NO_TEXTURE_ID) { + Uint32 sdlColor = SDL_MapRGBA( + m_format, + m_palette, + static_cast(color.r * 255), + static_cast(color.g * 255), + static_cast(color.b * 255), + static_cast(color.a * 255) + ); + SDL_FillSurfaceRect(m_renderedImage, ¢eredRect, sdlColor); + return; + } + + SDL_Surface* surface = m_textures[textureId].cached; + SDL_UnlockSurface(surface); SDL_BlitSurfaceScaled(surface, &srcRect, m_renderedImage, ¢eredRect, SDL_SCALEMODE_LINEAR); SDL_LockSurface(surface); } diff --git a/miniwin/src/ddraw/framebuffer.cpp b/miniwin/src/ddraw/framebuffer.cpp index 9f4224fd..20490b42 100644 --- a/miniwin/src/ddraw/framebuffer.cpp +++ b/miniwin/src/ddraw/framebuffer.cpp @@ -48,16 +48,32 @@ HRESULT FrameBufferImpl::Blt( if (!DDRenderer) { return DDERR_GENERIC; } + if (dynamic_cast(lpDDSrcSurface) == this) { return Flip(nullptr, DDFLIP_WAIT); } + if ((dwFlags & DDBLT_COLORFILL) == DDBLT_COLORFILL) { + Uint8 a = (lpDDBltFx->dwFillColor >> 24) & 0xFF; Uint8 r = (lpDDBltFx->dwFillColor >> 16) & 0xFF; Uint8 g = (lpDDBltFx->dwFillColor >> 8) & 0xFF; Uint8 b = lpDDBltFx->dwFillColor & 0xFF; - DDRenderer->Clear(r / 255.0f, g / 255.0f, b / 255.0f); + + float fa = a / 255.0f; + float fr = r / 255.0f; + float fg = g / 255.0f; + float fb = b / 255.0f; + + if (lpDestRect) { + SDL_Rect dstRect = ConvertRect(lpDestRect); + DDRenderer->Draw2DImage(NO_TEXTURE_ID, SDL_Rect{}, dstRect, {fr, fg, fb, fa}); + } + else { + DDRenderer->Clear(fr, fg, fb); + } return DD_OK; } + auto surface = static_cast(lpDDSrcSurface); if (!surface) { return DDERR_GENERIC; @@ -67,7 +83,7 @@ HRESULT FrameBufferImpl::Blt( lpSrcRect ? ConvertRect(lpSrcRect) : SDL_Rect{0, 0, surface->m_surface->w, surface->m_surface->h}; SDL_Rect dstRect = lpDestRect ? ConvertRect(lpDestRect) : SDL_Rect{0, 0, (int) m_virtualWidth, (int) m_virtualHeight}; - DDRenderer->Draw2DImage(textureId, srcRect, dstRect); + DDRenderer->Draw2DImage(textureId, srcRect, dstRect, {1.0f, 1.0f, 1.0f, 1.0f}); return DD_OK; } diff --git a/miniwin/src/internal/d3drmrenderer.h b/miniwin/src/internal/d3drmrenderer.h index a871bb26..d6464eb7 100644 --- a/miniwin/src/internal/d3drmrenderer.h +++ b/miniwin/src/internal/d3drmrenderer.h @@ -51,7 +51,7 @@ public: virtual void Resize(int width, int height, const ViewportTransform& viewportTransform) = 0; virtual void Clear(float r, float g, float b) = 0; virtual void Flip() = 0; - virtual void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) = 0; + virtual void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) = 0; virtual void Download(SDL_Surface* target) = 0; virtual void SetDither(bool dither) = 0; diff --git a/miniwin/src/internal/d3drmrenderer_citro3d.h b/miniwin/src/internal/d3drmrenderer_citro3d.h index af91b3dc..34863497 100644 --- a/miniwin/src/internal/d3drmrenderer_citro3d.h +++ b/miniwin/src/internal/d3drmrenderer_citro3d.h @@ -48,7 +48,7 @@ public: void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override; diff --git a/miniwin/src/internal/d3drmrenderer_directx9.h b/miniwin/src/internal/d3drmrenderer_directx9.h index 18ac126f..d1b0a581 100644 --- a/miniwin/src/internal/d3drmrenderer_directx9.h +++ b/miniwin/src/internal/d3drmrenderer_directx9.h @@ -34,7 +34,7 @@ public: void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override; diff --git a/miniwin/src/internal/d3drmrenderer_opengl1.h b/miniwin/src/internal/d3drmrenderer_opengl1.h index 656a964b..bd0fa003 100644 --- a/miniwin/src/internal/d3drmrenderer_opengl1.h +++ b/miniwin/src/internal/d3drmrenderer_opengl1.h @@ -34,7 +34,7 @@ public: void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override; diff --git a/miniwin/src/internal/d3drmrenderer_opengles2.h b/miniwin/src/internal/d3drmrenderer_opengles2.h index 0aaec63d..7dbb1f4b 100644 --- a/miniwin/src/internal/d3drmrenderer_opengles2.h +++ b/miniwin/src/internal/d3drmrenderer_opengles2.h @@ -55,7 +55,7 @@ public: void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override; diff --git a/miniwin/src/internal/d3drmrenderer_sdl3gpu.h b/miniwin/src/internal/d3drmrenderer_sdl3gpu.h index cf68a8c4..b3afd674 100644 --- a/miniwin/src/internal/d3drmrenderer_sdl3gpu.h +++ b/miniwin/src/internal/d3drmrenderer_sdl3gpu.h @@ -65,7 +65,7 @@ public: void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override; diff --git a/miniwin/src/internal/d3drmrenderer_software.h b/miniwin/src/internal/d3drmrenderer_software.h index 91abac32..8b8c0dde 100644 --- a/miniwin/src/internal/d3drmrenderer_software.h +++ b/miniwin/src/internal/d3drmrenderer_software.h @@ -47,7 +47,7 @@ public: void Resize(int width, int height, const ViewportTransform& viewportTransform) override; void Clear(float r, float g, float b) override; void Flip() override; - void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) override; + void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override; void Download(SDL_Surface* target) override; void SetDither(bool dither) override;