325 lines
12 KiB
C
325 lines
12 KiB
C
|
/**************************************************************************
|
||
|
|
||
|
DRAWDIBI.H - internal DrawDib include file
|
||
|
|
||
|
**************************************************************************/
|
||
|
|
||
|
// This stuff is not going to work for win64
|
||
|
#pragma warning(disable:4312)
|
||
|
|
||
|
#ifndef _WIN32
|
||
|
#define VFWAPI FAR PASCAL _loadds
|
||
|
#define VFWAPIV FAR CDECL _loadds
|
||
|
#endif
|
||
|
|
||
|
//#define MEASURE_PERFORMANCE
|
||
|
|
||
|
#if defined(MEASURE_PERFORMANCE) && defined(_WIN32) && defined(DEBUG)
|
||
|
|
||
|
#include <nt.h>
|
||
|
#include <ntrtl.h>
|
||
|
#include <nturtl.h>
|
||
|
#endif
|
||
|
|
||
|
/**************************************************************************
|
||
|
includes
|
||
|
**************************************************************************/
|
||
|
|
||
|
#include <win32.h> // for Win32 and Win16
|
||
|
#include <memory.h> // for _fmemcmp
|
||
|
#include <vfw.h>
|
||
|
|
||
|
#include "dither.h"
|
||
|
#include "stretch.h"
|
||
|
#include "lockbm.h"
|
||
|
#include "setdi.h"
|
||
|
#include "dciman.h"
|
||
|
|
||
|
/**************************************************************************
|
||
|
**************************************************************************/
|
||
|
|
||
|
#define DDF_OURFLAGS 0xFFFFC000l /* internal flags */
|
||
|
#define DDF_MEMORYDC 0x00008000l /* drawing to a memory DC */
|
||
|
#define DDF_WANTKEY 0x00004000l /* wait for a key frame */
|
||
|
#define DDF_STRETCH 0x00010000l /* we need to stretch */
|
||
|
#define DDF_DITHER 0x00020000l /* we need to dither */
|
||
|
#define DDF_BITMAP 0x00040000l /* Display driver isn't very good */
|
||
|
#define DDF_X 0x00080000l /* */
|
||
|
#define DDF_IDENTITYPAL 0x00100000l /* 1:1 palette mapping */
|
||
|
#define DDF_CANBITMAPX 0x00200000l /* can decompress to bitmap */
|
||
|
#define DDF_CANSCREENX 0x00400000l /* we can decompress/draw to screen */
|
||
|
#define DDF_Y 0x00800000l /* */
|
||
|
#define DDF_DIRTY 0x01000000l /* decompress buffer is dirty (not valid) */
|
||
|
#define DDF_HUGEBITMAP 0x02000000l /* decompressing to a HUGE bitmap */
|
||
|
#define DDF_XLATSOURCE 0x04000000l /* need to xlat source cord. */
|
||
|
#define DDF_CLIPPED 0x08000000l /* currently clipped */
|
||
|
#define DDF_NEWPALETTE 0x10000000l /* palette needs mapped */
|
||
|
#define DDF_CLIPCHECK 0x20000000l /* we care about clipping */
|
||
|
#define DDF_CANDRAWX 0x40000000l /* we can draw direct to screen */
|
||
|
#define DDF_CANSETPAL 0x80000000l /* codec supports ICM_SETPALETTE */
|
||
|
|
||
|
#define DDF_USERFLAGS 0x00003FFFl /* the user/called gives these, see .h */
|
||
|
|
||
|
/* these flags change what DrawDibBegin does */
|
||
|
#define DDF_BEGINFLAGS (DDF_JUSTDRAWIT | DDF_BUFFER | DDF_ANIMATE | DDF_FULLSCREEN | DDF_HALFTONE)
|
||
|
|
||
|
/**************************************************************************
|
||
|
|
||
|
flags, a little more info for people who are not me
|
||
|
|
||
|
DDF_OURFLAGS these are internal state flags, not passed in by
|
||
|
the user.
|
||
|
|
||
|
DDF_STRETCH the current draw requires us to stretch, if GDI
|
||
|
is stretching this bit is clear.
|
||
|
|
||
|
DDF_DITHER the current draw requires a format conversion
|
||
|
note a 16->24 32->24 conversion is also called
|
||
|
a dither, again if GDI is taking care of it this
|
||
|
bit is clear.
|
||
|
|
||
|
DDF_BITMAP the display driver isn't very good and we are converting
|
||
|
DIB to BMPs before drawing
|
||
|
|
||
|
DDF_CANBITMAPX we can decompress to bitmaps.
|
||
|
|
||
|
DDF_BITMAPX we are decompressing directly into a bitmap
|
||
|
|
||
|
DDF_IDENTITYPAL the palette is a identity palette.
|
||
|
|
||
|
DDF_CANSCREENX we can decompress to screen with the current draw
|
||
|
params.
|
||
|
|
||
|
DDF_SCREENX we are currently decompressing to the screen.
|
||
|
|
||
|
DDF_DIRTY the decompress buffer is dirty, ie does not
|
||
|
match what *should* be on the screen.
|
||
|
|
||
|
DDF_HUGEBITMAP we are decompressing into a huge bitmap, and
|
||
|
then calling FlatToHuge...
|
||
|
|
||
|
DDF_XLATSOURCE the source cordinates need remapping after
|
||
|
decompression, (basicly the decompressor is
|
||
|
doing a stretch...)
|
||
|
|
||
|
DDF_UPDATE the buffer is valid but needs drawn to the screen.
|
||
|
this will get set when DDF_DONTDRAW is passed, and
|
||
|
we are decompressing to memory
|
||
|
|
||
|
another way to put it is, if DDF_UPDATE is set
|
||
|
the screen is out of sync with our internal
|
||
|
buffer (the internal buffer is more correct)
|
||
|
|
||
|
DDF_CLIPPED we are clipped
|
||
|
|
||
|
DDF_NEWPALETTE we need to build new palette map
|
||
|
|
||
|
DDF_CLIPCHECK please check for clipping changes.
|
||
|
DDF_W
|
||
|
DDF_Q
|
||
|
|
||
|
DDF_USERFLAGS these flags are defined in the API, the user will pass
|
||
|
these to us.
|
||
|
|
||
|
DDF_BEGINFLAGS these flags will effect what DrawDibBegin() does
|
||
|
|
||
|
**************************************************************************/
|
||
|
|
||
|
/**************************************************************************
|
||
|
**************************************************************************/
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
#define DPF0( x ) { \
|
||
|
int fSave = fDebug; \
|
||
|
fDebug = 1; \
|
||
|
ddprintf x ; \
|
||
|
fDebug = fSave; \
|
||
|
}
|
||
|
#define DPF2( x ) if (fDebug >= 2 ){ \
|
||
|
ddprintf x ; \
|
||
|
}
|
||
|
#define DPF( x ) ddprintf x
|
||
|
#define DEBUG_RETAIL
|
||
|
#else
|
||
|
#define DPF2(x)
|
||
|
#define DPF0(x)
|
||
|
#define DPF(x)
|
||
|
#endif
|
||
|
|
||
|
#ifdef DEBUG_RETAIL
|
||
|
#define MODNAME "DRAWDIB"
|
||
|
|
||
|
extern void FAR cdecl ddprintf(LPSTR szFormat, ...);
|
||
|
|
||
|
#define RPF( x ) ddprintf x
|
||
|
#else
|
||
|
#define RPF(X)
|
||
|
#endif
|
||
|
|
||
|
/**************************************************************************
|
||
|
* The biXXXXX elements are grouped at the end to minimise the chance of
|
||
|
* overwriting non bitmap data (i.e. pointers). IF the code was totally
|
||
|
* clean this would be irrelevant, however it does increase robustness.
|
||
|
**************************************************************************/
|
||
|
|
||
|
typedef struct {
|
||
|
UINT wSize; /* MANDATORY: this MUST be the first field */
|
||
|
ULONG ulFlags;
|
||
|
UINT wError;
|
||
|
|
||
|
#define DECOMPRESS_NONE 0
|
||
|
#define DECOMPRESS_BITMAP 1
|
||
|
#define DECOMPRESS_SCREEN 2
|
||
|
#define DECOMPRESS_BUFFER 3
|
||
|
int iDecompress;
|
||
|
|
||
|
int dxSrc;
|
||
|
int dySrc;
|
||
|
int dxDst;
|
||
|
int dyDst;
|
||
|
|
||
|
HPALETTE hpal;
|
||
|
HPALETTE hpalCopy;
|
||
|
HPALETTE hpalDraw;
|
||
|
HPALETTE hpalDrawLast; /* hpalDraw for last DrawDibBegin */
|
||
|
int ClrUsed; /* number of colors used! */
|
||
|
int iAnimateStart; /* colors we can change */
|
||
|
int iAnimateLen;
|
||
|
int iAnimateEnd;
|
||
|
|
||
|
int iPuntFrame; /* how many frames we blew off */
|
||
|
|
||
|
/*
|
||
|
* set to DIB_RGB_COLORS, DIB_PAL_COLORS, or if on Win32 and 1:1 palette
|
||
|
* DIB_PAL_INDICES (see DrawdibCheckPalette())
|
||
|
*
|
||
|
*/
|
||
|
UINT uiPalUse;
|
||
|
|
||
|
DITHERPROC DitherProc;
|
||
|
|
||
|
LPBYTE pbBuffer; /* decompress buffer */
|
||
|
LPBYTE pbStretch; /* stretched bits. */
|
||
|
|
||
|
//
|
||
|
// note we alias the stretch buffer for bitmaps too.
|
||
|
//
|
||
|
#define biBitmap biStretch
|
||
|
#define pbBitmap pbStretch
|
||
|
|
||
|
SETDI sd; /* for SetBitmap */
|
||
|
HBITMAP hbmDraw; /* for drawing DIBs on the VGA!!! */
|
||
|
HDC hdcDraw;
|
||
|
HDC hdcLast; /* hdc last call to DrawDibBegin */
|
||
|
LPVOID lpDIBSection; /* pointer to dib section bits */
|
||
|
|
||
|
LPBYTE pbDither; /* bits we will dither to */
|
||
|
LPVOID lpDitherTable; /* for dithering */
|
||
|
|
||
|
HIC hic; /* decompressor */
|
||
|
|
||
|
#ifdef DEBUG_RETAIL
|
||
|
DRAWDIBTIME ddtime;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
LPBITMAPINFOHEADER lpbi; /* source dib format */
|
||
|
RGBQUAD (FAR *lpargbqIn)[256];/* source dib colors */
|
||
|
BITMAPINFOHEADER biBuffer; /* decompress format */
|
||
|
RGBQUAD argbq[256]; /* drawdib colors */
|
||
|
BITMAPINFOHEADER biStretch; /* stretched DIB */
|
||
|
DWORD smag[3]; /* room for masks */
|
||
|
BITMAPINFOHEADER biDraw; /* DIB we will draw */
|
||
|
WORD aw[512]; /* either index's or RGBQs */
|
||
|
BYTE ab[256]; /* pallete mapping (!!!needed?) */
|
||
|
|
||
|
#ifndef _WIN32
|
||
|
HTASK htask;
|
||
|
#endif
|
||
|
|
||
|
} DRAWDIB_STRUCT, *PDD;
|
||
|
|
||
|
/**************************************************************************
|
||
|
**************************************************************************/
|
||
|
|
||
|
extern DRAWDIB_STRUCT gdd;
|
||
|
extern WORD gwScreenBitDepth;
|
||
|
#ifndef _WIN32
|
||
|
extern BOOL gf286;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/**************************************************************************
|
||
|
**************************************************************************/
|
||
|
|
||
|
// flags for <wFlags> parameter of DisplayDib()
|
||
|
#define DISPLAYDIB_NOPALETTE 0x0010 // don't set palette
|
||
|
#define DISPLAYDIB_NOCENTER 0x0020 // don't center image
|
||
|
#define DISPLAYDIB_NOWAIT 0x0040 // don't wait before returning
|
||
|
#define DISPLAYDIB_NOIMAGE 0x0080 // don't draw image
|
||
|
#define DISPLAYDIB_ZOOM2 0x0100 // stretch by 2
|
||
|
#define DISPLAYDIB_DONTLOCKTASK 0x0200 // don't lock current task
|
||
|
#define DISPLAYDIB_TEST 0x0400 // testing the command
|
||
|
#define DISPLAYDIB_BEGIN 0x8000 // start of multiple calls
|
||
|
#define DISPLAYDIB_END 0x4000 // end of multiple calls
|
||
|
|
||
|
#define DISPLAYDIB_MODE_DEFAULT 0x0000
|
||
|
|
||
|
UINT (FAR PASCAL *DisplayDib)(LPBITMAPINFOHEADER lpbi, LPSTR lpBits, UINT wFlags);
|
||
|
UINT (FAR PASCAL *DisplayDibEx)(LPBITMAPINFOHEADER lpbi, int x, int y, LPSTR lpBits, UINT wFlags);
|
||
|
|
||
|
/**************************************************************************
|
||
|
**************************************************************************/
|
||
|
|
||
|
#ifdef DEBUG_RETAIL
|
||
|
#define TIMEINC() pdd->ddtime.timeCount++
|
||
|
#define TIMESTART(time) pdd->ddtime.time -= timeGetTime()
|
||
|
#define TIMEEND(time) pdd->ddtime.time += timeGetTime()
|
||
|
#else
|
||
|
#define TIMEINC()
|
||
|
#define TIMESTART(time)
|
||
|
#define TIMEEND(time)
|
||
|
#endif
|
||
|
|
||
|
/**************************************************************************
|
||
|
**************************************************************************/
|
||
|
|
||
|
#define WIDTHBYTES(i) ((unsigned)((i+31)&(~31))/8) /* ULONG aligned ! */
|
||
|
#define DIBWIDTHBYTES(bi) (UINT)WIDTHBYTES((int)(bi).biWidth * (int)(bi).biBitCount)
|
||
|
#define DIBSIZEIMAGE(bi) ((DWORD)(UINT)(bi).biHeight * (DWORD)(UINT)DIBWIDTHBYTES(bi))
|
||
|
|
||
|
#define PUSHBI(bi) (int)(bi).biWidth, (int)(bi).biHeight, (int)(bi).biBitCount
|
||
|
|
||
|
/**************************************************************************
|
||
|
**************************************************************************/
|
||
|
|
||
|
|
||
|
#if defined(MEASURE_PERFORMANCE) && defined(_WIN32) && defined(DEBUG)
|
||
|
|
||
|
static LARGE_INTEGER PC1; /* current counter value */
|
||
|
static LARGE_INTEGER PC2; /* current counter value */
|
||
|
static LARGE_INTEGER PC3; /* current counter value */
|
||
|
|
||
|
#define abs(x) ((x) < 0 ? -(x) : (x))
|
||
|
|
||
|
static VOID StartCounting(VOID)
|
||
|
{
|
||
|
QueryPerformanceCounter(&PC1);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
static VOID EndCounting(LPSTR szId)
|
||
|
{
|
||
|
QueryPerformanceCounter(&PC2);
|
||
|
PC3.QuadPart = PC2.QuadPart - PC1.QuadPart;
|
||
|
DPF(("%s: %d ticks", szId, PC3.LowPart));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
|
||
|
#define StartCounting()
|
||
|
#define EndCounting(x)
|
||
|
|
||
|
#endif
|