Initial commit
This commit is contained in:
419
engines/bagel/hodjnpodj/hnplibs/dibapi.cpp
Normal file
419
engines/bagel/hodjnpodj/hnplibs/dibapi.cpp
Normal file
@@ -0,0 +1,419 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "graphics/palette.h"
|
||||
#include "bagel/hodjnpodj/hnplibs/dibapi.h"
|
||||
#include "bagel/hodjnpodj/hnplibs/stdafx.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace HodjNPodj {
|
||||
|
||||
static BITMAPINFOHEADER getDIBInfoHeader(HDIB hDib) {
|
||||
BITMAPINFOHEADER h;
|
||||
h.biSize = 40;
|
||||
h.biWidth = hDib->w;
|
||||
h.biHeight = hDib->h;
|
||||
h.biPlanes = 1;
|
||||
h.biBitCount = 8;
|
||||
h.biCompression = BI_RGB;
|
||||
h.biSizeImage = 0;
|
||||
h.biXPelsPerMeter = 0;
|
||||
h.biYPelsPerMeter = 0;
|
||||
h.biClrUsed = !hDib->hasPalette() ? 0 :
|
||||
hDib->grabPalette()->size();
|
||||
h.biClrImportant = 0;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static BITMAPINFO *getDIBInfo(HDIB hDib) {
|
||||
BITMAPINFO *h = (BITMAPINFO *)malloc(
|
||||
sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
|
||||
|
||||
h->bmiHeader = getDIBInfoHeader(hDib);
|
||||
|
||||
const Graphics::Palette *pal = hDib->grabPalette();
|
||||
for (uint i = 0; i < h->bmiHeader.biClrUsed; ++i) {
|
||||
auto &col = h->bmiColors[i];
|
||||
pal->get(i, col.rgbRed, col.rgbGreen, col.rgbBlue);
|
||||
col.rgbReserved = 0;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* PaintDIB()
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* HDC hDC - DC to do output to
|
||||
*
|
||||
* LPRECT lpDCRect - rectangle on DC to do output to
|
||||
*
|
||||
* HDIB hDIB - handle to global memory with a DIB spec
|
||||
* in it followed by the DIB bits
|
||||
*
|
||||
* LPRECT lpDIBRect - rectangle of DIB to output into lpDCRect
|
||||
*
|
||||
* CPalette* pPal - pointer to CPalette containing DIB's palette
|
||||
*
|
||||
* Return Value:
|
||||
*
|
||||
* bool - true if DIB was drawn, false otherwise
|
||||
*
|
||||
* Description:
|
||||
* Painting routine for a DIB. Calls StretchDIBits() or
|
||||
* SetDIBitsToDevice() to paint the DIB. The DIB is
|
||||
* output to the specified DC, at the coordinates given
|
||||
* in lpDCRect. The area of the DIB to be output is
|
||||
* given by lpDIBRect.
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
bool PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB,
|
||||
LPRECT lpDIBRect, CPalette *pPal) {
|
||||
bool bSuccess = false; // Success/fail flag
|
||||
HPALETTE hPal = nullptr; // Our DIB's palette
|
||||
HPALETTE hOldPal = nullptr; // Previous palette
|
||||
HPALETTE hOldPal2 = nullptr; // Previous palette
|
||||
HBITMAP hBitmap, hBitmapOld;
|
||||
HDC hdcMem; // memory device context
|
||||
int nDevCaps;
|
||||
|
||||
// Check for valid DIB handle
|
||||
if (hDIB == nullptr)
|
||||
return false;
|
||||
|
||||
// Get the palette, then select it into DC
|
||||
if (pPal != nullptr) {
|
||||
hPal = (HPALETTE)pPal->m_hObject;
|
||||
|
||||
// Select as foreground and realize it
|
||||
hOldPal = SelectPalette(hDC, hPal, false);
|
||||
RealizePalette(hDC);
|
||||
}
|
||||
|
||||
nDevCaps = GetDeviceCaps(hDC, RASTERCAPS);
|
||||
if (!(nDevCaps & RC_STRETCHDIB)) {
|
||||
hBitmap = DIBtoBitmap(hDC, nullptr, hDIB);
|
||||
if (hBitmap) {
|
||||
hdcMem = CreateCompatibleDC(hDC);
|
||||
if (hdcMem) {
|
||||
hOldPal2 = SelectPalette(hdcMem, hPal, false);
|
||||
RealizePalette(hdcMem);
|
||||
hBitmapOld = SelectBitmap(hdcMem, hBitmap);
|
||||
if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&
|
||||
(RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
|
||||
bSuccess = BitBlt(hDC, lpDCRect->left, lpDCRect->top,
|
||||
RECTWIDTH(lpDIBRect),
|
||||
RECTHEIGHT(lpDIBRect),
|
||||
hdcMem, lpDIBRect->left, lpDIBRect->top, SRCCOPY);
|
||||
else if (nDevCaps & RC_STRETCHBLT)
|
||||
bSuccess = StretchBlt(hDC, lpDCRect->left, lpDCRect->top, RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect),
|
||||
hdcMem, lpDIBRect->left, lpDIBRect->top, RECTWIDTH(lpDIBRect), RECTHEIGHT(lpDIBRect),
|
||||
SRCCOPY);
|
||||
else
|
||||
bSuccess = false;
|
||||
SelectBitmap(hdcMem, hBitmapOld);
|
||||
SelectPalette(hdcMem, hOldPal2, false);
|
||||
DeleteDC(hdcMem);
|
||||
}
|
||||
}
|
||||
|
||||
if (hBitmap != nullptr)
|
||||
DeleteBitmap(hBitmap);
|
||||
if (pPal != nullptr)
|
||||
SelectPalette(hDC, hOldPal, false);
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
error("TODO: Populate binfo and enable below if this is ever needed");
|
||||
#if 0
|
||||
BITMAPINFO bInfo;
|
||||
|
||||
// Lock down the DIB, and get a pointer to it
|
||||
Graphics::ManagedSurface *surf = (Graphics::ManagedSurface *)hDIB;
|
||||
void *lpDIBBits = surf->getPixels();
|
||||
|
||||
// Make sure to use the stretching mode best for color pictures
|
||||
SetStretchBltMode(hDC, COLORONCOLOR);
|
||||
|
||||
bSuccess = StretchDIBits(hDC, // hDC
|
||||
lpDCRect->left, // DestX
|
||||
lpDCRect->top, // DestY
|
||||
RECTWIDTH(lpDCRect), // nDestWidth
|
||||
RECTHEIGHT(lpDCRect), // nDestHeight
|
||||
lpDIBRect->left, // SrcX
|
||||
lpDIBRect->top, // SrcY
|
||||
RECTWIDTH(lpDIBRect), // wSrcWidth
|
||||
RECTHEIGHT(lpDIBRect), // wSrcHeight
|
||||
lpDIBBits, // lpBits
|
||||
&bInfo, // lpBitsInfo
|
||||
DIB_RGB_COLORS, // wUsage
|
||||
SRCCOPY); // dwROP
|
||||
|
||||
if (pPal != nullptr)
|
||||
SelectPalette(hDC, hOldPal, false);
|
||||
|
||||
return bSuccess;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CreateDIBPalette(HDIB hDIB, CPalette *pPal) {
|
||||
uint16 wNumColors;
|
||||
bool bResult = false;
|
||||
|
||||
// If handle to DIB is invalid, return false
|
||||
if (hDIB == nullptr)
|
||||
return false;
|
||||
|
||||
// Get the number of colors in the DIB
|
||||
wNumColors = DIBNumColors(hDIB);
|
||||
|
||||
if (wNumColors != 0) {
|
||||
const Graphics::Palette *pal = hDIB->grabPalette();
|
||||
bResult = pPal->SetPaletteEntries(*pal);
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
CPalette *DuplicatePalette(CPalette *pOrigPal) {
|
||||
CPalette *pPal;
|
||||
LPLOGPALETTE lpPal; // pointer to a logical palette
|
||||
HANDLE hLogPal; // handle to a logical palette
|
||||
uint16 wNumColors; // number of colors in color table
|
||||
bool bResult;
|
||||
|
||||
wNumColors = pOrigPal->GetPaletteEntries(0, 0, nullptr);
|
||||
if (wNumColors == 0)
|
||||
return nullptr;
|
||||
|
||||
/* allocate memory block for logical palette */
|
||||
hLogPal = GlobalAlloc(GPTR, sizeof(LOGPALETTE)
|
||||
+ sizeof(PALETTEENTRY)
|
||||
* wNumColors);
|
||||
assert(hLogPal);
|
||||
|
||||
lpPal = (LPLOGPALETTE) GlobalLock((HGLOBAL)hLogPal);
|
||||
|
||||
/* set version and number of palette entries */
|
||||
lpPal->palVersion = PALVERSION;
|
||||
lpPal->palNumEntries = (uint16)wNumColors;
|
||||
|
||||
(*pOrigPal).GetPaletteEntries(0, wNumColors - 1, &lpPal->palPalEntry[0]);
|
||||
|
||||
/* create the palette and get handle to it */
|
||||
|
||||
pPal = new CPalette();
|
||||
bResult = pPal->CreatePalette(lpPal);
|
||||
if (!bResult) {
|
||||
delete pPal;
|
||||
pPal = nullptr;
|
||||
}
|
||||
|
||||
GlobalUnlock((HGLOBAL)hLogPal);
|
||||
GlobalFree((HGLOBAL)hLogPal);
|
||||
|
||||
return pPal;
|
||||
}
|
||||
|
||||
char *FindDIBBits(HDIB hDIB) {
|
||||
return (char *)hDIB->getPixels();
|
||||
}
|
||||
|
||||
uint32 DIBWidth(HDIB hDIB) {
|
||||
return hDIB->w;
|
||||
}
|
||||
|
||||
uint32 DIBHeight(HDIB hDIB) {
|
||||
return hDIB->h;
|
||||
}
|
||||
|
||||
uint16 PaletteSize(HDIB hDIB) {
|
||||
const Graphics::Palette *pal = hDIB->grabPalette();
|
||||
return pal->size() * 3;
|
||||
}
|
||||
|
||||
uint16 DIBNumColors(HDIB lpDIB) {
|
||||
const Graphics::Palette *pal = lpDIB->grabPalette();
|
||||
return pal->size();
|
||||
}
|
||||
|
||||
CBitmap *ConvertDIB(CDC *pDC, HDIB hDIB, CPalette *pPal) {
|
||||
HPALETTE hPal = nullptr; // Our DIB's palette
|
||||
HPALETTE hOldPal = nullptr; // Previous palette
|
||||
HDC hDC;
|
||||
HBITMAP hBitmap = nullptr;
|
||||
CBitmap *pBitmap = nullptr;
|
||||
|
||||
hDC = (*pDC).m_hDC;
|
||||
|
||||
// Get the palette, then select it into DC
|
||||
if (pPal != nullptr) {
|
||||
hPal = (HPALETTE)pPal->m_hObject;
|
||||
|
||||
// Select as foreground and realize it
|
||||
hOldPal = SelectPalette(hDC, hPal, false);
|
||||
RealizePalette(hDC);
|
||||
}
|
||||
|
||||
// Convert the bit buffer to a bitmap
|
||||
hBitmap = DIBtoBitmap(hDC, nullptr, hDIB);
|
||||
|
||||
if (hBitmap != nullptr) {
|
||||
pBitmap = new CBitmap();
|
||||
if (pBitmap != nullptr)
|
||||
(*pBitmap).Attach(hBitmap);
|
||||
}
|
||||
|
||||
/* Reselect old palette */
|
||||
if (pPal != nullptr)
|
||||
SelectPalette(hDC, hOldPal, false);
|
||||
|
||||
return pBitmap;
|
||||
}
|
||||
|
||||
HBITMAP DIBtoBitmap(HDC hDC, HPALETTE hPalette, HDIB hDib) {
|
||||
BITMAPINFO *info = getDIBInfo(hDib);
|
||||
void *lpbihBits = FindDIBBits(hDib);
|
||||
HBITMAP hBitmap = CreateDIBitmap(hDC,
|
||||
&info->bmiHeader,
|
||||
CBM_INIT,
|
||||
lpbihBits,
|
||||
info,
|
||||
DIB_RGB_COLORS);
|
||||
assert(hBitmap);
|
||||
|
||||
free(info);
|
||||
return hBitmap;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// Function: InitBitmapInfoHeader
|
||||
//
|
||||
// Purpose: Does a "standard" initialization of a BITMAPINFOHEADER,
|
||||
// given the Width, Height, and Bits per Pixel for the
|
||||
// DIB.
|
||||
//
|
||||
// By standard, I mean that all the relevant fields are set
|
||||
// to the specified values. biSizeImage is computed, the
|
||||
// biCompression field is set to "no compression," and all
|
||||
// other fields are 0.
|
||||
//
|
||||
// Note that DIBs only allow BitsPixel values of 1, 4, 8, or
|
||||
// 24. This routine makes sure that one of these values is
|
||||
// used (whichever is most appropriate for the specified
|
||||
// nBPP).
|
||||
//
|
||||
// Parms: lpBmInfoHdr == Far pointer to a BITMAPINFOHEADER structure
|
||||
// to be filled in.
|
||||
// dwWidth == Width of DIB (not in Win 3.0 & 3.1, high
|
||||
// word MUST be 0).
|
||||
// dwHeight == Height of DIB (not in Win 3.0 & 3.1, high
|
||||
// word MUST be 0).
|
||||
// nBPP == Bits per Pixel for the DIB.
|
||||
//
|
||||
// History: Date Reason
|
||||
// 11/07/91 Created
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
void WINAPI InitBitmapInfoHeader(LPBITMAPINFOHEADER lpBmInfoHdr,
|
||||
uint32 dwWidth,
|
||||
uint32 dwHeight,
|
||||
int nBPP) {
|
||||
memset(lpBmInfoHdr, 0, sizeof(BITMAPINFOHEADER));
|
||||
|
||||
lpBmInfoHdr->biSize = sizeof(BITMAPINFOHEADER);
|
||||
lpBmInfoHdr->biWidth = dwWidth;
|
||||
lpBmInfoHdr->biHeight = dwHeight;
|
||||
lpBmInfoHdr->biPlanes = 1;
|
||||
|
||||
if (nBPP <= 1)
|
||||
nBPP = 1;
|
||||
else if (nBPP <= 4)
|
||||
nBPP = 4;
|
||||
else if (nBPP <= 8)
|
||||
nBPP = 8;
|
||||
else
|
||||
nBPP = 24;
|
||||
|
||||
lpBmInfoHdr->biBitCount = nBPP;
|
||||
lpBmInfoHdr->biSizeImage = WIDTHBYTES(dwWidth * nBPP) * dwHeight;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//// Clipboard support
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
//
|
||||
// Function: CopyHandle (from SDK DibView sample clipbrd.c)
|
||||
//
|
||||
// Purpose: Makes a copy of the given global memory block. Returns
|
||||
// a handle to the new memory block (nullptr on error).
|
||||
//
|
||||
// Routine stolen verbatim out of ShowDIB.
|
||||
//
|
||||
// Parms: h == Handle to global memory to duplicate.
|
||||
//
|
||||
// Returns: Handle to new global memory block.
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
HANDLE WINAPI CopyHandle(HANDLE h) {
|
||||
byte *lpCopy;
|
||||
byte *lp;
|
||||
HANDLE hCopy;
|
||||
uint32 dwLen;
|
||||
|
||||
if (h == nullptr)
|
||||
return nullptr;
|
||||
|
||||
dwLen = GlobalSize((HGLOBAL)h);
|
||||
|
||||
if ((hCopy = (HANDLE) GlobalAlloc(GHND, dwLen)) != nullptr) {
|
||||
lpCopy = (byte *) GlobalLock((HGLOBAL)hCopy);
|
||||
lp = (byte *) GlobalLock((HGLOBAL)h);
|
||||
|
||||
while (dwLen--)
|
||||
*lpCopy++ = *lp++;
|
||||
|
||||
GlobalUnlock((HGLOBAL)hCopy);
|
||||
GlobalUnlock((HGLOBAL)h);
|
||||
}
|
||||
|
||||
return hCopy;
|
||||
}
|
||||
|
||||
|
||||
void WINAPI ShowMemoryInfo(const char *chMessage, const char *chTitle) {
|
||||
// No implementation
|
||||
}
|
||||
|
||||
} // namespace HodjNPodj
|
||||
} // namespace Bagel
|
||||
Reference in New Issue
Block a user