Files
Hellfire/Storm/SOURCE/ddraw/DirectDrawPaletteWrapper.cpp
T
Justin Marshall 101266ab72 Initial commit.
2026-04-27 10:35:40 -07:00

288 lines
8.5 KiB
C++

#include "DirectDrawWrapper.h"
/*******************
**IUnknown methods**
********************/
// Retrieves pointers to the supported interfaces on an object.
HRESULT __stdcall IDirectDrawPaletteWrapper::QueryInterface(REFIID riid, LPVOID FAR * ppvObj)
{
debugMessage(1, "IDirectDrawPaletteWrapper::QueryInterface", "Partially Implemented");
// Provide the directdraw interface for all versions up to 7
if(riid == IID_IDirectDrawPalette)
{
// Set pointer to this interface
ppvObj = (LPVOID *)this;
// Increment reference count
AddRef();
// Return success
return S_OK;
}
// Interface not supported
return E_NOINTERFACE;
}
// Increments the reference count for an interface on an object.
ULONG __stdcall IDirectDrawPaletteWrapper::AddRef()
{
debugMessage(1, "IDirectDrawPaletteWrapper::AddRef", "Partially Implemented");
// Increment reference count
ReferenceCount++;
// Return current reference count
return ReferenceCount;
}
// Decrements the reference count for an interface on an object.
ULONG __stdcall IDirectDrawPaletteWrapper::Release()
{
debugMessage(1, "IDirectDrawPaletteWrapper::Release", "Partially Implemented");
// Decrement reference count
ReferenceCount--;
// If reference count reaches 0 then free object
if(ReferenceCount == 0)
{
// Free objects
if(rawPalette != NULL) delete rawPalette;
if(rgbPalette != NULL) delete rgbPalette;
}
// Return new reference count
return ReferenceCount;
}
/*****************************
**IDirectDrawPalette methods**
******************************/
// Retrieves the capabilities of the palette object.
HRESULT __stdcall IDirectDrawPaletteWrapper::GetCaps(LPDWORD lpdwCaps)
{
debugMessage(1, "IDirectDrawPaletteWrapper::GetCaps", "Partially Implemented");
// lpdwCaps cannot be null
if(lpdwCaps == NULL) return DDERR_INVALIDPARAMS;
// set return data to current palette caps
*lpdwCaps = paletteCaps;
return DD_OK;
}
// Retrieves palette values from a DirectDrawPalette object.
HRESULT __stdcall IDirectDrawPaletteWrapper::GetEntries(DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries)
{
// lpEntries cannot be null and dwFlags must be 0
if(lpEntries == NULL) return DDERR_INVALIDPARAMS;
// Copy raw palette entries to lpEntries(size dwNumEntries) starting at dwBase
memcpy(lpEntries, &(rawPalette[dwBase]), sizeof(PALETTEENTRY) * min(dwNumEntries, entryCount - dwBase));
/*
// NOTE: Debugging disabled for performance
debugMessage(2, "IDirectDrawPaletteWrapper::GetEntries", "Retrieved Palette Entries");
char message[2048] = "\0";
sprintf_s(message, 2048, "dwBase: %d, dwNumEntries: %d", dwBase, dwNumEntries);
debugMessage(2, "IDirectDrawPaletteWrapper::GetEntries", message);
*/
// dwNumEntries is the number of palette entries that can fit in the array that lpEntries
// specifies. The colors of the palette entries are returned in sequence, from the value
// of the dwStartingEntry parameter through the value of the dwCount parameter minus 1.
// (These parameters are set by IDirectDrawPalette::SetEntries.)
return DD_OK;
}
// Initializes the DirectDrawPalette object.
HRESULT __stdcall IDirectDrawPaletteWrapper::Initialize(LPDIRECTDRAW lpDDW, DWORD dwFlags, LPPALETTEENTRY lpDDColorTable)
{
debugMessage(1, "IDirectDrawPaletteWrapper::Initialize", "Partially Implemented");
// This method always returns already initialized
return DDERR_ALREADYINITIALIZED;
}
// Changes entries in a DirectDrawPalette object immediately.
HRESULT __stdcall IDirectDrawPaletteWrapper::SetEntries(DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries)
{
// lpEntries cannot be null and dwFlags must be 0
if(lpEntries == NULL) return DDERR_INVALIDPARAMS;
// Copy raw palette entries from dwStartingEntry and of count dwCount
memcpy(&(rawPalette[dwStartingEntry]), lpEntries, sizeof(PALETTEENTRY) * min(dwCount, entryCount - dwStartingEntry));
// Translate new raw pallete entries to RGB(make sure not to go off the end of the memory)
for(int i = dwStartingEntry; i < min(dwStartingEntry + dwCount, entryCount - dwStartingEntry); i++)
{
// Translate the raw palette to ARGB
if(hasAlpha)
{
// Include peFlags as 8bit alpha
rgbPalette[i] = rawPalette[i].peFlags << 24;
rgbPalette[i] |= rawPalette[i].peRed << 16;
rgbPalette[i] |= rawPalette[i].peGreen << 8;
rgbPalette[i] |= rawPalette[i].peBlue;
}
else
{
// Alpha is always 255
rgbPalette[i] = 0xFF000000;
rgbPalette[i] |= rawPalette[i].peRed << 16;
rgbPalette[i] |= rawPalette[i].peGreen << 8;
rgbPalette[i] |= rawPalette[i].peBlue;
}
}
/*
// NOTE: Debugging disabled for performance
debugMessage(2, "IDirectDrawPaletteWrapper::SetEntries", "Set Palette Entries");
char message[2048] = "\0";
sprintf_s(message, 2048, "dwStartingEntry: %d, dwCount: %d", dwStartingEntry, dwCount);
debugMessage(2, "IDirectDrawPaletteWrapper::SetEntries", message); */
return DD_OK;
}
// Default constructor
IDirectDrawPaletteWrapper::IDirectDrawPaletteWrapper()
{
// Init vars
rgbPalette = NULL;
rawPalette = NULL;
ReferenceCount = 0;
paletteCaps = 0;
entryCount = 0;
hasAlpha = false;
// Create with flags
AddRef();
debugMessage(2, "IDirectDrawPaletteWrapper::IDirectDrawPaletteWrapper", "Created");
}
// Default destructor
IDirectDrawPaletteWrapper::~IDirectDrawPaletteWrapper()
{
// Free used memory
if(rgbPalette != NULL)
{
delete rgbPalette;
rgbPalette = NULL;
}
if(rawPalette != NULL)
{
delete rawPalette;
rawPalette = NULL;
}
// Clean up
Release();
debugMessage(2, "IDirectDrawPaletteWrapper::~IDirectDrawPaletteWrapper", "Destroyed");
}
// Initialize wrapper function
HRESULT IDirectDrawPaletteWrapper::WrapperInitialize(DWORD dwFlags, LPPALETTEENTRY lpDDColorArray, LPDIRECTDRAWPALETTE FAR *lplpDDPalette)
{
// Save palette caps
paletteCaps = dwFlags;
// Default to 256 entries
entryCount = 256;
// Create palette of requested bit size
if(dwFlags & DDPCAPS_1BIT)
{
entryCount = 2;
}
else if(dwFlags & DDPCAPS_2BIT)
{
entryCount = 4;
}
else if(dwFlags & DDPCAPS_4BIT)
{
entryCount = 16;
}
else if(dwFlags & DDPCAPS_8BIT || dwFlags & DDPCAPS_ALLOW256)
{
entryCount = 256;
}
// Allocate raw ddraw palette
rawPalette = new PALETTEENTRY[entryCount];
// Memory failed to allocate, return out of memory
if(rawPalette == NULL)
{
debugMessage(0, "IDirectDrawPaletteWrapper::WrapperInitialize", "Failed to allocate raw palette memory");
return DDERR_OUTOFMEMORY;
}
// Copy inital palette into raw palette
memcpy(rawPalette, lpDDColorArray, sizeof(PALETTEENTRY) * entryCount);
// Check flags for alpha
if(dwFlags & DDPCAPS_ALPHA)
{
hasAlpha = true;
}
else
{
hasAlpha = false;
}
// Allocate rgb palette
rgbPalette = new UINT32[entryCount];
// Memory failed to allocate, return out of memory
if(rgbPalette == NULL)
{
debugMessage(0, "IDirectDrawPaletteWrapper::WrapperInitialize", "Failed to allocate RGB palette memory");
return DDERR_OUTOFMEMORY;
}
// For all entries
for(int i = 0; i < entryCount; i++)
{
// Translate the raw palette to ARGB
if(hasAlpha)
{
// Include peFlags as 8bit alpha
rgbPalette[i] = rawPalette[i].peFlags << 24;
rgbPalette[i] |= rawPalette[i].peRed << 16;
rgbPalette[i] |= rawPalette[i].peGreen << 8;
rgbPalette[i] |= rawPalette[i].peBlue;
}
else
{
// Alpha is always 255
rgbPalette[i] = 0xFF000000;
rgbPalette[i] |= rawPalette[i].peRed << 16;
rgbPalette[i] |= rawPalette[i].peGreen << 8;
rgbPalette[i] |= rawPalette[i].peBlue;
}
}
char message[2048] = "\0";
sprintf_s(message, 2048, "Initialized");
if(dwFlags & DDPCAPS_1BIT) strcat_s(message, 2048, ", DDPCAPS_1BIT");
if(dwFlags & DDPCAPS_2BIT) strcat_s(message, 2048, ", DDPCAPS_2BIT");
if(dwFlags & DDPCAPS_4BIT) strcat_s(message, 2048, ", DDPCAPS_4BIT");
if(dwFlags & DDPCAPS_8BIT) strcat_s(message, 2048, ", DDPCAPS_8BIT");
if(dwFlags & DDPCAPS_8BITENTRIES) strcat_s(message, 2048, ", DDPCAPS_8BITENTRIES");
if(dwFlags & DDPCAPS_ALPHA) strcat_s(message, 2048, ", DDPCAPS_ALPHA");
if(dwFlags & DDPCAPS_ALLOW256) strcat_s(message, 2048, ", DDPCAPS_ALLOW256");
if(dwFlags & DDPCAPS_INITIALIZE) strcat_s(message, 2048, ", DDPCAPS_INITIALIZE");
if(dwFlags & DDPCAPS_PRIMARYSURFACE) strcat_s(message, 2048, ", DDPCAPS_PRIMARYSURFACE");
if(dwFlags & DDPCAPS_PRIMARYSURFACELEFT) strcat_s(message, 2048, ", DDPCAPS_PRIMARYSURFACELEFT");
if(dwFlags & DDPCAPS_VSYNC) strcat_s(message, 2048, ", DDPCAPS_VSYNC");
debugMessage(2, "IDirectDrawPaletteWrapper::WrapperInitialize", message);
// Success
return DD_OK;
}