2020-09-30 17:12:29 +02:00

281 lines
7.4 KiB
C

#include <windows.h>
#include <win32.h> //This is needed for both win16/32 versions
#include "ddsucks.h"
#include "drawdibi.h"
#ifdef WIN32
#include "mmddk.h"
#endif
//#ifdef DEBUG
//static void cdecl dprintf(LPSTR szFormat, ...);
//#define DPF(x) dprintf x
//#else
//#define DPF(x)
//#endif
/**************************************************************************
**************************************************************************/
/* CreateExplicitPalette()
*/
static HPALETTE CreateExplicitPalette()
{
int i;
struct {
UINT palVersion;
UINT palNumEntries;
PALETTEENTRY palPalEntry[256];
} pal;
pal.palVersion = 0x300;
pal.palNumEntries = 256;
for (i = 0; i < 256; i++)
{
pal.palPalEntry[i].peRed = (BYTE)i;
pal.palPalEntry[i].peGreen = 0;
pal.palPalEntry[i].peBlue = 0;
pal.palPalEntry[i].peFlags = PC_EXPLICIT;
}
return CreatePalette((LPLOGPALETTE)&pal);
}
/***************************************************************************
*
* DoesDisplayDriverSuck(void)
*
* times the display driver and determines if it "sucks" drawing 8bpp DIBs to
* the screen.
*
* it "sucks" if it can BitBlt() bitmaps *much* faster than it can
* StretchDIBits() them.
*
***************************************************************************/
#define TEST_SIZE_X 160 // !!!magic numbers....
#define TEST_SIZE_Y 120
#define TEST_COUNT 10
static BOOL NEAR PASCAL DoesDisplayDriverSuck(int bits)
{
int i;
HDC hdc;
HDC hdcMem;
HBITMAP hbm;
HBITMAP hbmT;
HPALETTE hpal=NULL;
HPALETTE hpalT;
LPBITMAPINFOHEADER lpbi;
LPVOID lpBits;
LPWORD lpw;
DWORD time;
DWORD timeDib;
DWORD timeBlt;
DWORD timeDibBlt;
extern DWORD FAR PASCAL timeGetTime(void);
hdc = GetDC(NULL);
if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
{
hpal = CreateExplicitPalette();
hpalT = SelectPalette(hdc, hpal, FALSE);
RealizePalette(hdc);
}
hdcMem = CreateCompatibleDC(hdc);
hbm = CreateCompatibleBitmap(hdc, TEST_SIZE_X, TEST_SIZE_Y);
hbmT = SelectObject(hdcMem, hbm);
lpbi = (LPVOID)GlobalLock(GlobalAlloc(GHND, sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD) + (DWORD)TEST_SIZE_X*TEST_SIZE_Y));
lpbi->biSize = sizeof(BITMAPINFOHEADER);
lpbi->biWidth = TEST_SIZE_X;
lpbi->biHeight = TEST_SIZE_Y;
lpbi->biPlanes = 1;
lpbi->biBitCount = bits;
lpbi->biCompression = BI_RGB;
lpbi->biSizeImage = (DWORD)TEST_SIZE_X*TEST_SIZE_Y;
lpbi->biXPelsPerMeter = 0;
lpbi->biYPelsPerMeter = 0;
lpbi->biClrUsed = 256;
lpbi->biClrImportant = 0;
lpw = (LPWORD)(lpbi+1);
lpBits = (LPBYTE)(lpbi+1) + 256*sizeof(RGBQUAD);
for (i=0; i<256; i++)
lpw[i] = i;
//
// grab the screen as the blit test
//
BitBlt(hdcMem, 0, 0, TEST_SIZE_X, TEST_SIZE_Y, hdc, 0, 0, SRCCOPY);
GetDIBits(hdc, hbm, 0, TEST_SIZE_Y,
lpBits, (LPBITMAPINFO)lpbi, DIB_PAL_COLORS);
#ifdef DEBUG
//
// blt the bitmap back to the screen N times
// and time it!
//
time = timeGetTime();
for (i=0; i<TEST_COUNT; i++)
BitBlt(hdc, 0, 0, TEST_SIZE_X, TEST_SIZE_Y, hdcMem, 0, 0, SRCCOPY);
timeBlt = timeGetTime() - time;
#endif
//
// draw the DIB directly to the screen
//
time = timeGetTime();
for (i=0; i<TEST_COUNT; i++)
StretchDIBits(hdc, 0, 0, TEST_SIZE_X, TEST_SIZE_Y,
0, 0, TEST_SIZE_X, TEST_SIZE_Y,
lpBits, (LPBITMAPINFO)lpbi, DIB_PAL_COLORS, SRCCOPY);
timeDib = timeGetTime() - time;
//
// convert the DIB to a BITMAP then draw
//
time = timeGetTime();
for (i=0; i<TEST_COUNT; i++)
{
SetDIBits(hdc,hbm,0,TEST_SIZE_Y,lpBits,(LPBITMAPINFO)lpbi,DIB_PAL_COLORS);
BitBlt(hdc, 0, 0, TEST_SIZE_X, TEST_SIZE_Y, hdcMem, 0, 0, SRCCOPY);
}
timeDibBlt = timeGetTime() - time;
//
// print the results.
//
DPF(("DIB BLT PERFORMANCE (%d bit):", bits));
DPF((" BitBlt: %ldms", timeBlt));
DPF((" StretchDIBits: %ldms", timeDib));
DPF((" SetDIBits + BitBlt: %ldms", timeDibBlt));
if (hpal)
{
SelectPalette(hdc, hpalT, FALSE);
DeleteObject(hpal);
}
SelectObject(hdcMem, hbmT);
DeleteObject(hbm);
DeleteObject(hdcMem);
ReleaseDC(NULL, hdc);
GlobalFree((HGLOBAL)HIWORD((DWORD)lpbi));
return timeDib > timeDibBlt;
}
/***************************************************************************
*
* DoesDisplaySuck(void)
*
* times the display driver and determines if it "sucks" drawing 8bpp DIBs to
* the screen.
*
* it "sucks" if it can BitBlt() bitmaps *much* faster than it can
* StretchDIBits() them.
*
***************************************************************************/
BOOL FAR PASCAL DoesDisplaySuck(void)
{
char achDisplay[80];
char ach[80];
static BOOL fDisplayDriverSucks = -1;
static TCHAR szDisplayDriverSucks[] = TEXT("DisplayDriverBad");
#ifdef WIN16
static TCHAR szDisplayDrv[] = TEXT("display.drv");
#else
static TCHAR szDisplayDrv[] = TEXT("display.dll");
#endif
static TCHAR szSystemIni[] = TEXT("system.ini");
static TCHAR szMCIAVI[] = MCIAVI_SECTION;
static TCHAR szBoot[] = TEXT("boot");
static TCHAR szNull[] = TEXT("");
if (fDisplayDriverSucks != -1)
return fDisplayDriverSucks;
GetPrivateProfileString(szBoot, szDisplayDrv, szNull, achDisplay,
sizeof(achDisplay), szSystemIni);
GetProfileString(szMCIAVI, szDisplayDrv, szNull, ach, sizeof(ach));
if (lstrcmpi(ach, achDisplay) != 0) {
WriteProfileString(szMCIAVI, szDisplayDrv, achDisplay);
fDisplayDriverSucks = -1;
}
else {
fDisplayDriverSucks = GetProfileInt(szMCIAVI, szDisplayDriverSucks, -1);
}
if (fDisplayDriverSucks == -1) {
#ifdef DEBUG
DoesDisplayDriverSuck(4);
#endif
fDisplayDriverSucks = DoesDisplayDriverSuck(8);
wsprintf(ach, "%d", fDisplayDriverSucks);
WriteProfileString(szMCIAVI, szDisplayDriverSucks, ach);
if (fDisplayDriverSucks)
{
DPF(("*****************************************************"));
DPF(("** **"));
DPF(("** WARNING YOUR DISPLAY DRIVER SUCKS DOING DIBS **"));
DPF(("** TRYING TO DEAL WITH IT. **"));
DPF(("** **"));
DPF(("*****************************************************"));
}
}
return fDisplayDriverSucks;
}
#if 0
#ifdef DEBUG
static void cdecl dprintf(LPSTR szFormat, ...)
{
char ach[128];
#ifdef WIN32
va_list va;
va_start(szFormat, va);
wvsprintfA (ach,szFormat,va);
va_end(va);
OutputDebugStringA("DDSUCKS: ");
OutputDebugStringA(ach);
OutputDebugStringA("\r\n");
#else
wvsprintfA (ach,szFormat,(LPSTR)(&szFormat+1));
OutputDebugStringA("DDSUCKS: ");
OutputDebugStringA(ach);
OutputDebugStringA("\r\n");
#endif
}
#endif
#endif