#include #define _INC_VFW #define VFWAPI FAR PASCAL _loadds #include "dva.h" #include "lockbm.h" /**************************************************************************** ***************************************************************************/ extern BOOL vga_get_surface(HDC, int, DVASURFACEINFO FAR *); extern BOOL ati_get_surface(HDC, int, DVASURFACEINFO FAR *); extern BOOL dib_get_surface(HDC, int, DVASURFACEINFO FAR *); extern BOOL thun_get_surface(HDC,int, DVASURFACEINFO FAR *); extern BOOL vlb_get_surface(HDC, int, DVASURFACEINFO FAR *); #define GetDS() SELECTOROF((LPVOID)&ScreenSel) static short ScreenSel; static BOOL InitSurface(DVASURFACEINFO FAR *pdva); static BOOL TestSurface(DVASURFACEINFO FAR *pdva); static void SetSelLimit(UINT sel, DWORD limit); /**************************************************************************** ***************************************************************************/ void FAR PASCAL DVAInit() { } /**************************************************************************** ***************************************************************************/ void FAR PASCAL DVATerm() { // // free screen alias // if (ScreenSel) { SetSelLimit(ScreenSel, 0); FreeSelector(ScreenSel); ScreenSel = 0; } } /**************************************************************************** ***************************************************************************/ BOOL FAR PASCAL _loadds DVAGetSurface(HDC hdc, int nSurface, DVASURFACEINFO FAR *pdva) { int i; i = Escape(hdc, DVAGETSURFACE,sizeof(int),(LPCSTR)&nSurface,(LPVOID)pdva); // // should this be a function table? list? // if (i <= 0 && !dib_get_surface(hdc, nSurface, pdva) && !ati_get_surface(hdc, nSurface, pdva) && #ifdef DEBUG !vlb_get_surface(hdc, nSurface, pdva) && !thun_get_surface(hdc, nSurface, pdva) && #endif !vga_get_surface(hdc, nSurface, pdva)) return FALSE; return InitSurface(pdva); } #if 0 /**************************************************************************** ***************************************************************************/ HDVA FAR PASCAL DVAOpenSurface(HDC hdc, int nSurface) { PDVA pdva; pdva = (PDVA)GlobalAllocPtr(GHND|GMEM_SHARE, sizeof(DVASURFACEINFO)); if (pdva == NULL) return NULL; if (!DVAGetSurface(hdc, nSurface, pdva) || !pdva->OpenSurface(pdva->lpSurface)) { GlobalFreePtr(pdva); return NULL; } return pdva; } /**************************************************************************** ***************************************************************************/ void FAR PASCAL DVACloseSurface(HDVA pdva) { if (pdva == NULL) return; pdva->CloseSurface(pdva->lpSurface); GlobalFreePtr(pdva); } #endif /**************************************************************************** ***************************************************************************/ BOOL CALLBACK default_open_surface(LPVOID pv) { return TRUE; } /**************************************************************************** ***************************************************************************/ void CALLBACK default_close_surface(LPVOID pv) { } /**************************************************************************** ***************************************************************************/ BOOL CALLBACK default_begin_access(LPVOID pv, int x, int y, int dx, int dy) { return TRUE; } /**************************************************************************** ***************************************************************************/ void CALLBACK default_end_access(LPVOID pv) { } /**************************************************************************** ***************************************************************************/ UINT CALLBACK default_show_surface(LPVOID pv, HWND hwnd, LPRECT src, LPRECT dst) { return 1; } /**************************************************************************** ***************************************************************************/ static BOOL InitSurface(DVASURFACEINFO FAR *pdva) { LPBITMAPINFOHEADER lpbi; if (pdva->Version != 0x0100) return FALSE; lpbi = &pdva->BitmapInfo; if (lpbi->biSize != sizeof(BITMAPINFOHEADER)) return FALSE; if (lpbi->biPlanes != 1) return FALSE; // // make the pointer a 16:16 pointer // if (pdva->offSurface >= 0x10000 && !(pdva->Flags & DVAF_1632_ACCESS)) { if (ScreenSel == NULL) ScreenSel = AllocSelector(GetDS()); if (pdva->selSurface != 0) pdva->offSurface += GetSelectorBase(pdva->selSurface); SetSelectorBase(ScreenSel,pdva->offSurface); SetSelLimit(ScreenSel,lpbi->biSizeImage-1); pdva->offSurface = 0; pdva->selSurface = ScreenSel; } // // fill in defaults. // if (pdva->OpenSurface == NULL) pdva->OpenSurface = default_open_surface; if (pdva->CloseSurface == NULL) pdva->CloseSurface = default_close_surface; if (pdva->ShowSurface == NULL) pdva->ShowSurface = default_show_surface; if (pdva->BeginAccess == NULL) { pdva->BeginAccess = default_begin_access; pdva->EndAccess = default_end_access; } // // only test RGB surfaces. // if (lpbi->biCompression == 0 || lpbi->biCompression == BI_BITFIELDS || lpbi->biCompression == BI_1632) { if (!TestSurface(pdva)) return FALSE; } // // set BI_1632 if needed // if (pdva->Flags & DVAF_1632_ACCESS) { lpbi->biCompression = BI_1632; } return TRUE; } /**************************************************************************** ***************************************************************************/ #pragma optimize("", off) static void SetSelLimit(UINT sel, DWORD limit) { if (limit >= 1024*1024l) limit = ((limit+4096) & ~4095) - 1; _asm { mov ax,0008h ; DPMI set limit mov bx,sel mov dx,word ptr limit[0] mov cx,word ptr limit[2] int 31h } } #pragma optimize("", on) /**************************************************************************** ***************************************************************************/ #define ASM66 _asm _emit 0x66 _asm #define DB _asm _emit #pragma optimize("", off) static BYTE ReadByte(PDVA pdva, LPVOID lpBits, DWORD dw) { BYTE b=42; DVABeginAccess(pdva, 0, 0, 1024, 1024); _asm { ASM66 xor bx,bx les bx,lpBits ASM66 add bx,word ptr dw mov ax,es ASM66 lsl ax,ax ASM66 cmp bx,ax ja exit DB 26h ;mov al,es:[ebx] DB 67h DB 8Ah DB 03h mov b,al exit: } DVAEndAccess(pdva); return b; } #pragma optimize("", on) ///////////////////////////////////////////////////////////////////////////// // // SetPixel // // some cards cant't seam to do SetPixel right it is amazing they work at all // ///////////////////////////////////////////////////////////////////////////// static void SetPixelX(HDC hdc, int x, int y, COLORREF rgb) { RECT rc; rc.left = x; rc.top = y; rc.right = x+1; rc.bottom = y+1; SetBkColor(hdc, rgb); ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL); } #define SetPixel SetPixelX /**************************************************************************** ***************************************************************************/ static BOOL TestSurface(DVASURFACEINFO FAR *pdva) { HDC hdc; int x,y,h,w,wb; COLORREF rgb,rgb0,rgb1,rgb2,rgb3,rgb4; DWORD dw; BYTE b0,b1; UINT uType=0; LPBITMAPINFOHEADER lpbi; LPVOID lpBits; HCURSOR hcur; if (!pdva->OpenSurface(pdva->lpSurface)) return FALSE; lpbi = DVAGetSurfaceFmt(pdva); lpBits = DVAGetSurfacePtr(pdva); h = abs((int)lpbi->biHeight); w = (int)lpbi->biWidth; wb = (w * ((UINT)lpbi->biBitCount/8) + 3) & ~3; dw = (DWORD)(UINT)(h-1) * (DWORD)(UINT)wb; if ((int)lpbi->biHeight < 0) y = 0; else y = h-1; #ifdef XDEBUG x = (int)lpbi->biWidth - 5; ((LPBYTE)lpBits) += x * (UINT)lpbi->biBitCount/8; #else x = 0; #endif hcur = SetCursor(NULL); hdc = GetDC(NULL); rgb = GetPixel(hdc, x, h-1-y); SetPixel(hdc, x, h-1-y, RGB(0,0,0)); GetPixel(hdc, x, h-1-y); b0 = ReadByte(pdva, lpBits, dw); SetPixel(hdc, x, h-1-y, RGB(255,255,255)); GetPixel(hdc, x, h-1-y); b1 = ReadByte(pdva, lpBits, dw); SetPixel(hdc, x, h-1-y,rgb); if (b0 != 0x00 || b1 == 0x00) goto done; rgb0 = GetPixel(hdc, x+0, y); rgb1 = GetPixel(hdc, x+1, y); rgb2 = GetPixel(hdc, x+2, y); rgb3 = GetPixel(hdc, x+3, y); rgb4 = GetPixel(hdc, x+4, y); TestSurfaceType(hdc, x, y); DVABeginAccess(pdva, x, y, 5, 1); uType = GetSurfaceType(lpBits); DVAEndAccess(pdva); SetPixel(hdc, x+0, y,rgb0); SetPixel(hdc, x+1, y,rgb1); SetPixel(hdc, x+2, y,rgb2); SetPixel(hdc, x+3, y,rgb3); SetPixel(hdc, x+4, y,rgb4); done: ReleaseDC(NULL, hdc); SetCursor(hcur); pdva->CloseSurface(pdva->lpSurface); switch (uType) { case BM_8BIT: break; case BM_16555: ((LPDWORD)(lpbi+1))[0] = 0x007C00; ((LPDWORD)(lpbi+1))[1] = 0x0003E0; ((LPDWORD)(lpbi+1))[2] = 0x00001F; break; case BM_24BGR: case BM_32BGR: ((LPDWORD)(lpbi+1))[0] = 0xFF0000; ((LPDWORD)(lpbi+1))[1] = 0x00FF00; ((LPDWORD)(lpbi+1))[2] = 0x0000FF; break; case BM_16565: lpbi->biCompression = BI_BITFIELDS; ((LPDWORD)(lpbi+1))[0] = 0x00F800; ((LPDWORD)(lpbi+1))[1] = 0x0007E0; ((LPDWORD)(lpbi+1))[2] = 0x00001F; break; case BM_24RGB: case BM_32RGB: lpbi->biCompression = BI_BITFIELDS; ((LPDWORD)(lpbi+1))[0] = 0x0000FF; ((LPDWORD)(lpbi+1))[1] = 0x00FF00; ((LPDWORD)(lpbi+1))[2] = 0xFF0000; break; } return uType != 0; }