You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
5.9 KiB

#include "miniwin/ddraw.h"
#include <SDL.h>
#include "DiabloUI/diabloui.h"
#include "devilution.h"
#include "stubs.h"
namespace dvl {
SDL_Window *window;
SDL_Renderer *renderer;
/** Currently active palette */
SDL_Palette *palette;
SDL_Texture *texture;
/** 32-bit in-memory backbuffer surface */
SDL_Surface *surface;
/** 8-bit surface wrapper around #gpBuffer */
SDL_Surface *pal_surface;
ULONG StubDraw::Release()
{
DUMMY();
SDL_FreeSurface(pal_surface);
SDL_FreePalette(palette);
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
return 0;
};
HRESULT StubDraw::CreatePalette(DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette,
IUnknown *pUnkOuter)
{
DUMMY();
*lplpDDPalette = new StubPalette();
palette = SDL_AllocPalette(256);
if (palette == NULL) {
SDL_Log("SDL_AllocPalette: %s\n", SDL_GetError());
return (HRESULT)0x80000002L; //DDERR_OUTOFMEMORY
}
return DVL_DS_OK;
}
HRESULT StubDraw::CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE *lplpDDSurface,
IUnknown *pUnkOuter)
{
DUMMY();
if (!lpDDSurfaceDesc->dwWidth) {
SDL_GetRendererOutputSize(renderer, (int *)&lpDDSurfaceDesc->dwWidth, (int *)&lpDDSurfaceDesc->dwHeight);
lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = SDL_PIXELFORMAT_RGBA8888;
lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = 32;
surface = SDL_CreateRGBSurfaceWithFormat(0, lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, lpDDSurfaceDesc->ddpfPixelFormat.dwFlags);
if (surface == NULL) {
SDL_Log("SDL_CreateRGBSurface: %s\n", SDL_GetError());
return (HRESULT)0x80000002L; //DDERR_OUTOFMEMORY
}
lpDDSurfaceDesc->lpSurface = (BYTE *)surface->pixels;
*lplpDDSurface = new StubSurface(lpDDSurfaceDesc);
return DVL_DS_OK;
}
pal_surface = SDL_CreateRGBSurfaceWithFormat(0, lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight, lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, lpDDSurfaceDesc->ddpfPixelFormat.dwFlags);
if (pal_surface == NULL) {
SDL_Log("SDL_CreateRGBSurface: %s\n", SDL_GetError());
return (HRESULT)0x80000002L; //DDERR_OUTOFMEMORY
}
lpDDSurfaceDesc->lpSurface = (BYTE *)surface->pixels;
*lplpDDSurface = new StubSurface(lpDDSurfaceDesc);
gpBuffer = (BYTE *)pal_surface->pixels; // Hack should happen in dx.cpp, but gives error
if (SDL_SetSurfacePalette(pal_surface, palette) != 0) {
SDL_Log("SDL_SetSurfacePalette: %s\n", SDL_GetError());
return 1; //MAKE_HRESULT(130);//DVL_MAKE_HRESULT(130);
}
return DVL_DS_OK;
}
HRESULT StubDraw::SetCooperativeLevel(HWND hWnd, DWORD dwFlags)
{
DUMMY();
return DVL_DS_OK;
}
HRESULT StubDraw::SetDisplayMode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP)
{
DUMMY();
width = dwWidth;
height = dwHeight;
return DVL_DS_OK;
}
HRESULT StubDraw::WaitForVerticalBlank(DWORD dwFlags, HANDLE hEvent)
{
DUMMY_ONCE();
return DVL_DS_OK;
}
StubSurface::StubSurface(LPDDSURFACEDESC lpDDSurfaceDesc)
{
}
StubSurface::~StubSurface()
{
}
ULONG StubSurface::Release()
{
DUMMY();
return 0;
};
HRESULT StubSurface::BltFast(DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans)
{
DUMMY_ONCE();
assert(lpDDSrcSurface == lpDDSBackBuf); // is src pal_surface
int w = lpSrcRect->right - lpSrcRect->left + 1;
int h = lpSrcRect->bottom - lpSrcRect->top + 1;
SDL_Rect src_rect = { lpSrcRect->left, lpSrcRect->top, w, h };
SDL_Rect dst_rect = { (int)dwX, (int)dwY, w, h };
// Convert from 8-bit to 32-bit
if (SDL_BlitSurface(pal_surface, &src_rect, surface, &dst_rect) != 0) {
SDL_Log("SDL_BlitSurface: %s\n", SDL_GetError());
return DVL_E_FAIL;
}
return DVL_S_OK;
}
HRESULT StubSurface::GetCaps(LPDDSCAPS lpDDSCaps)
{
DUMMY();
return DVL_S_OK;
}
HRESULT StubSurface::GetDC(HDC *lphDC)
{
DUMMY_ONCE();
return DVL_S_OK;
}
HRESULT StubSurface::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat)
{
lpDDPixelFormat->dwFlags = SDL_PIXELFORMAT_INDEX8;
lpDDPixelFormat->dwRGBBitCount = 8;
return DVL_S_OK;
}
HRESULT StubSurface::IsLost()
{
DUMMY_ONCE();
return DVL_S_OK;
}
HRESULT StubSurface::Lock(LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
{
DUMMY_ONCE();
lpDDSurfaceDesc->lpSurface = (BYTE *)pal_surface->pixels;
return DVL_S_OK;
}
HRESULT StubSurface::ReleaseDC(HDC hDC)
{
DUMMY_ONCE();
return DVL_S_OK;
}
HRESULT StubSurface::Restore()
{
UNIMPLEMENTED();
return DVL_S_OK;
}
HRESULT StubSurface::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette)
{
DUMMY();
return DVL_S_OK;
}
HRESULT StubSurface::Unlock(LPVOID lpSurfaceData)
{
DUMMY_ONCE();
assert(!SDL_MUSTLOCK(surface));
if (SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch) != 0) { //pitch is 2560
SDL_Log("SDL_UpdateTexture: %s\n", SDL_GetError());
}
// Clear the entire screen to our selected color.
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
if (SDL_RenderCopy(renderer, texture, NULL, NULL) != 0) {
SDL_Log("SDL_RenderCopy: %s\n", SDL_GetError());
}
SDL_RenderPresent(renderer);
return DVL_S_OK;
}
ULONG StubPalette::Release()
{
DUMMY();
return 0;
};
HRESULT StubPalette::GetCaps(LPDWORD lpdwCaps)
{
UNIMPLEMENTED();
return DVL_S_OK;
}
HRESULT StubPalette::GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries)
{
for (int i = 0; i < dwNumEntries; i++) {
lpEntries[i].peFlags = 0;
lpEntries[i].peRed = system_palette[i].peRed;
lpEntries[i].peGreen = system_palette[i].peGreen;
lpEntries[i].peBlue = system_palette[i].peBlue;
}
return DVL_S_OK;
}
HRESULT StubPalette::SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries)
{
for (int i = 0; i < dwCount; i++) {
system_palette[i].peFlags = 0;
system_palette[i].peRed = lpEntries[i].peRed;
system_palette[i].peGreen = lpEntries[i].peGreen;
system_palette[i].peBlue = lpEntries[i].peBlue;
}
palette_update();
return DVL_S_OK;
}
} // namespace dvl