diff --git a/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp b/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp index eb639d84..df20dc72 100644 --- a/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp +++ b/LEGO1/lego/legoomni/src/common/legotextureinfo.cpp @@ -56,16 +56,87 @@ LegoTextureInfo* LegoTextureInfo::Create(const char* p_name, LegoTexture* p_text strcpy(textureInfo->m_name, p_name); } - LPDIRECTDRAW pDirectDraw = VideoManager()->GetDirect3D()->DirectDraw(); - LegoImage* image = p_texture->GetImage(); - DDSURFACEDESC desc; memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); desc.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY; + desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat); + + LPDIRECTDRAW pDirectDraw = VideoManager()->GetDirect3D()->DirectDraw(); + + // Attempt to load HD texture + std::string hdPath = std::string(MxOmni::GetHD()) + "/textures/" + std::string(p_name) + ".bmp"; + SDL_Surface* hdSurface = SDL_LoadBMP(hdPath.c_str()); + if (hdSurface) { + const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(hdSurface->format); + desc.dwWidth = hdSurface->w; + desc.dwHeight = hdSurface->h; + desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; + desc.ddpfPixelFormat.dwRGBBitCount = details->bits_per_pixel == 8 ? 24 : details->bits_per_pixel; + desc.ddpfPixelFormat.dwRBitMask = details->Rmask; + desc.ddpfPixelFormat.dwGBitMask = details->Gmask; + desc.ddpfPixelFormat.dwBBitMask = details->Bmask; + desc.ddpfPixelFormat.dwRGBAlphaBitMask = details->Amask; + + if (pDirectDraw->CreateSurface(&desc, &textureInfo->m_surface, NULL) != DD_OK) { + SDL_DestroySurface(hdSurface); + return NULL; + } + + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + + if (textureInfo->m_surface->Lock(NULL, &desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY, NULL) != DD_OK) { + SDL_DestroySurface(hdSurface); + return NULL; + } + + MxU8* dst = (MxU8*) desc.lpSurface; + Uint8* srcPixels = (Uint8*) hdSurface->pixels; + + if (details->bits_per_pixel == 8) { + SDL_Palette* palette = SDL_GetSurfacePalette(hdSurface); + if (palette) { + for (int y = 0; y < hdSurface->h; ++y) { + Uint8* srcRow = srcPixels + y * hdSurface->pitch; + Uint8* dstRow = dst + y * desc.lPitch; + for (int x = 0; x < hdSurface->w; ++x) { + SDL_Color color = palette->colors[srcRow[x]]; + dstRow[x * 3 + 0] = color.r; + dstRow[x * 3 + 1] = color.g; + dstRow[x * 3 + 2] = color.b; + } + } + } + else { + textureInfo->m_surface->Unlock(desc.lpSurface); + SDL_DestroySurface(hdSurface); + return NULL; + } + } + else { + memcpy(dst, srcPixels, hdSurface->pitch * hdSurface->h); + } + + textureInfo->m_surface->Unlock(desc.lpSurface); + textureInfo->m_palette = NULL; + + if (((TglImpl::RendererImpl*) VideoManager()->GetRenderer()) + ->CreateTextureFromSurface(textureInfo->m_surface, &textureInfo->m_texture) != D3DRM_OK) { + SDL_DestroySurface(hdSurface); + return NULL; + } + + textureInfo->m_texture->SetAppData((LPD3DRM_APPDATA) textureInfo); + SDL_DestroySurface(hdSurface); + return textureInfo; + } + + LegoImage* image = p_texture->GetImage(); + desc.dwWidth = image->GetWidth(); desc.dwHeight = image->GetHeight(); - desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY; desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat); desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8; desc.ddpfPixelFormat.dwRGBBitCount = 8; diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index b36cbd2a..2902c4fe 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -827,6 +827,7 @@ LPDIRECTDRAWSURFACE MxDisplaySurface::VTable0x44( ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; ddsd.dwWidth = p_bitmap->GetBmiWidth(); ddsd.dwHeight = p_bitmap->GetBmiHeightAbs(); + ddsd.ddpfPixelFormat = m_surfaceDesc.ddpfPixelFormat; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; *p_ret = 0; ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; diff --git a/miniwin/include/miniwin/ddraw.h b/miniwin/include/miniwin/ddraw.h index 0250c099..912a1b9f 100644 --- a/miniwin/include/miniwin/ddraw.h +++ b/miniwin/include/miniwin/ddraw.h @@ -143,9 +143,12 @@ enum class DDBltFlags : uint32_t { }; ENABLE_BITMASK_OPERATORS(DDBltFlags) +#define DDPF_ALPHAPIXELS DDPixelFormatFlags::ALPHAPIXELS #define DDPF_PALETTEINDEXED8 DDPixelFormatFlags::PALETTEINDEXED8 #define DDPF_RGB DDPixelFormatFlags::RGB +#define DDPF_ALPHAPIXELS DDPixelFormatFlags::ALPHAPIXELS enum class DDPixelFormatFlags : uint32_t { + ALPHAPIXELS = 1 << 0, // dwRGBAlphaBitMask is valid PALETTEINDEXED8 = 1 << 5, // The texture uses an 8 bit palette RGB = 1 << 6, // dwRGBBitCount, dwRBitMask, dwGBitMask, and dwBBitMask is valid }; diff --git a/miniwin/src/ddraw/ddraw.cpp b/miniwin/src/ddraw/ddraw.cpp index e6603f17..9849b0f9 100644 --- a/miniwin/src/ddraw/ddraw.cpp +++ b/miniwin/src/ddraw/ddraw.cpp @@ -106,13 +106,27 @@ HRESULT DirectDrawImpl::CreateSurface( #endif if ((lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) == DDSD_PIXELFORMAT) { if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) == DDPF_RGB) { - switch (lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount) { - case 8: - format = SDL_PIXELFORMAT_INDEX8; - break; - case 16: - format = SDL_PIXELFORMAT_RGB565; - break; + int bpp = lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount; + Uint32 rMask = lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask; + Uint32 gMask = lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask; + Uint32 bMask = lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask; + Uint32 aMask = (lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) == DDPF_ALPHAPIXELS + ? lpDDSurfaceDesc->ddpfPixelFormat.dwRGBAlphaBitMask + : 0; + + if (rMask == 0 && gMask == 0 && bMask == 0) { + if (bpp == 16) { + format = SDL_PIXELFORMAT_RGB565; + } + else if (bpp == 8) { + format = SDL_PIXELFORMAT_INDEX8; + } + } + else { + format = SDL_GetPixelFormatForMasks(bpp, rMask, gMask, bMask, aMask); + if (format == SDL_PIXELFORMAT_UNKNOWN) { + return DDERR_INVALIDPIXELFORMAT; + } } } } @@ -168,7 +182,7 @@ HRESULT DirectDrawImpl::EnumDisplayModes( ddsd.dwWidth = modes[i]->w; ddsd.dwHeight = modes[i]->h; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); - ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; + ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; ddsd.ddpfPixelFormat.dwRGBBitCount = details->bits_per_pixel; if (details->bits_per_pixel == 8) { ddsd.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8; @@ -271,7 +285,7 @@ HRESULT DirectDrawImpl::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) lpDDSurfaceDesc->dwWidth = mode->w; lpDDSurfaceDesc->dwHeight = mode->h; lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = details->bits_per_pixel; - lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB; + lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; if (details->bits_per_pixel == 8) { lpDDSurfaceDesc->ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8; } diff --git a/miniwin/src/ddraw/ddsurface.cpp b/miniwin/src/ddraw/ddsurface.cpp index 056912fd..9e710596 100644 --- a/miniwin/src/ddraw/ddsurface.cpp +++ b/miniwin/src/ddraw/ddsurface.cpp @@ -145,7 +145,7 @@ HRESULT DirectDrawSurfaceImpl::GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) HRESULT DirectDrawSurfaceImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) { memset(lpDDPixelFormat, 0, sizeof(*lpDDPixelFormat)); - lpDDPixelFormat->dwFlags = DDPF_RGB; + lpDDPixelFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(m_surface->format); if (details->bits_per_pixel == 8) { lpDDPixelFormat->dwFlags |= DDPF_PALETTEINDEXED8; diff --git a/miniwin/src/ddraw/framebuffer.cpp b/miniwin/src/ddraw/framebuffer.cpp index 13caa434..d3d8a3b8 100644 --- a/miniwin/src/ddraw/framebuffer.cpp +++ b/miniwin/src/ddraw/framebuffer.cpp @@ -143,7 +143,7 @@ HRESULT FrameBufferImpl::GetPalette(LPDIRECTDRAWPALETTE* lplpDDPalette) HRESULT FrameBufferImpl::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) { memset(lpDDPixelFormat, 0, sizeof(*lpDDPixelFormat)); - lpDDPixelFormat->dwFlags = DDPF_RGB; + lpDDPixelFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; const SDL_PixelFormatDetails* details = SDL_GetPixelFormatDetails(m_transferBuffer->m_surface->format); if (details->bits_per_pixel == 8) { lpDDPixelFormat->dwFlags |= DDPF_PALETTEINDEXED8;