/*----------------------------------------------------------------------------*\ | qa.c - A template for a Windows application | | | | Usage: | | To make a quick windows application, modify the following files | | QA.C - App source code | | MAKEFILE - App makefile (unix make, none of this dos crap) | | QA.H - App constants | | QA.DEF - App exported functions and module name | | QA.RC - App resources, DLG boxes, ... | | QA.ICO - App icon (2.x format) | | QA.IC3 - App icon (3.x format) | | | | History: | | 01/01/88 toddla Created | | | \*----------------------------------------------------------------------------*/ #include #include #include #include // for timeGetTime #include #include #include #include "ddtest.h" #include "dib.h" #include "ddsucks.h" #ifdef WIN32 #include #endif #include #define BI_CRAM mmioFOURCC('C','R','A','M') #define NFRAMES 100 #define XFRAMES 30 /* Macro to swap two values */ #define SWAP(x,y) ((x)^=(y)^=(x)^=(y)) /*----------------------------------------------------------------------------*\ | | | g e n e r a l c o n s t a n t s | | | \*----------------------------------------------------------------------------*/ #define MAXSTR 80 #ifndef WIN32 #define EXPORT FAR PASCAL _export // exported function #endif #define PRIVATE NEAR PASCAL // function local to this segment #define PUBLIC FAR PASCAL // function external to this segment typedef LONG (FAR PASCAL *LPWNDPROC)(HWND, UINT, UINT, LONG); // pointer to a window procedure #define DibPtr(lpbi) ((LPBYTE)(lpbi) + \ (int)((LPBITMAPINFOHEADER)(lpbi))->biSize + \ (int)((LPBITMAPINFOHEADER)(lpbi))->biClrUsed * sizeof(RGBQUAD) ) #define FPFIT(time,n) time/1000,time%1000, \ time ? (1000l * n / time) : 0, \ time ? (1000000l * n / time) % 1000: 0 /*----------------------------------------------------------------------------*\ | | | g l o b a l v a r i a b l e s | | | \*----------------------------------------------------------------------------*/ static TCHAR szAppName[]=TEXT("DDTest"); static HANDLE hInstApp; static HWND hwndApp; HANDLE hdibCurrent; LPBITMAPINFOHEADER lpbiCurrent; BITMAPINFOHEADER biCurrent; RECT rcCurrent = {0,0,0,0}; RECT rcDraw; RECT rcSource; HDRAWDIB hdd = NULL; UINT wDrawDibFlags = 0; TCHAR achFileName[128] = TEXT("TestDib8"); #ifdef WIN32 #define ProfBegin() #define ProfEnd() #else #define ProfBegin() ProfClear(); ProfSampRate(5,1); ProfStart(); #define ProfEnd() ProfStop(); ProfFlush(); #endif static HCURSOR hcurSave; #define StartWait() hcurSave = SetCursor(LoadCursor(NULL,IDC_WAIT)) #define EndWait() SetCursor(hcurSave) static UINT (FAR *displayFPS)[3][2]; /*----------------------------------------------------------------------------*\ | | | f u n c t i o n d e f i n i t i o n s | | | \*----------------------------------------------------------------------------*/ LONG _export AppWndProc (HWND hwnd, unsigned uiMessage, UINT wParam, LONG lParam); int ErrMsg (LPTSTR sz,...); BOOL fDialog(int id,HWND hwnd,FARPROC fpfn); void RandRect(PRECT prc, int dx, int dy); HANDLE CopyHandle(HANDLE h); HANDLE MakeDib(UINT bits); LONG NEAR PASCAL AppCommand(HWND hwnd, unsigned msg, UINT wParam, LONG lParam); void DrawDibTest(void); void TimeDrawDib(void); #ifndef QUERYDIBSUPPORT #define QUERYDIBSUPPORT 3073 #define QDI_SETDIBITS 0x0001 #define QDI_GETDIBITS 0x0002 #define QDI_DIBTOSCREEN 0x0004 #define QDI_STRETCHDIB 0x0008 #endif DWORD QueryDibSupport(LPBITMAPINFOHEADER lpbi) { HDC hdc; DWORD dw = 0; DPF(("QueryDibSupport")); hdc = GetDC(NULL); // // send the Escape to see if they support this DIB // if (!Escape(hdc, QUERYDIBSUPPORT, (int)lpbi->biSize, (LPVOID)lpbi, (LPVOID)&dw) > 0) dw = (DWORD)-1; ReleaseDC(NULL, hdc); return dw; } /*----------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------*/ static BOOL gfResource; static int iCompressor = -1; static int nCompressors; static HIC ahic[100]; void FreeDib() { DPF(("FreeDib")); if (gfResource) { UnlockResource(hdibCurrent); FreeResource(hdibCurrent); } else if (hdibCurrent) GlobalFree(hdibCurrent); hdibCurrent = NULL; gfResource = FALSE; } void InitDIB(HWND hwnd, HANDLE hdib, LPTSTR szFile) { HANDLE h; TCHAR ach[80]; int i; DWORD dw; if (hdib == NULL) { DPF(("InitDib; File %ls", szFile)); hdib = OpenDIB(szFile, 0); } else { DPF(("InitDib; hDib 0x%08X", hdib)); } if (hdib == NULL) { if (h = FindResource(hInstApp, szFile, RT_BITMAP)) { FreeDib(); hdib = LoadResource(hInstApp, h); hdibCurrent = hdib; lpbiCurrent = (LPVOID)LockResource(hdibCurrent); gfResource = TRUE; } if (hdib == NULL) { ErrMsg(TEXT("Unable to open %ls"),(LPTSTR)szFile); return; } } else { FreeDib(); hdibCurrent = hdib; lpbiCurrent = (LPVOID)GlobalLock(hdibCurrent); } if (lpbiCurrent->biClrUsed == 0 && lpbiCurrent->biBitCount <= 8) lpbiCurrent->biClrUsed = (1 << (int)lpbiCurrent->biBitCount); DibInfo(lpbiCurrent, &biCurrent); SetRect(&rcCurrent, 0, 0, (int)biCurrent.biWidth, (int)biCurrent.biHeight); SetRect(&rcSource, 0, 0, (int)biCurrent.biWidth, (int)biCurrent.biHeight); switch (biCurrent.biCompression) { case BI_RGB: dw= mmioFOURCC('N','o','n','e'); break; case BI_RLE4: dw= mmioFOURCC('R','l','e','4'); break; case BI_RLE8: dw= mmioFOURCC('R','l','e','8'); break; default: dw= biCurrent.biCompression; } for (i=0; ibiClrUsed == 0 && lpbi->biBitCount <= 8) lpbi->biClrUsed = (1 << (int)lpbi->biBitCount); dwFlags = 0; ckid = 0; dwQuality = ICGetDefaultQuality(hic); ProfBegin(); time = timeGetTime(); for (i=0; i 1) ErrMsg(TEXT("CompressTime = %ld.%03ld sec %ld.%03ld fps"), FPFIT(time, nFrames) ); } DWORD TimeDecompress(HIC hic, int bits) { LPBITMAPINFOHEADER lpbi; int i; HANDLE hdib; DWORD time = 0; DPF(("TimeDecompress")); hdib = CreateDib(bits, (int)biCurrent.biWidth, (int)biCurrent.biHeight); lpbi = (LPVOID)GlobalLock(hdib); if (ICDecompressQuery(hic, lpbiCurrent, lpbi) == ICERR_OK) { ICDecompressBegin(hic, lpbiCurrent, lpbi); ProfBegin(); time = timeGetTime(); for (i=0; inull-terminated command line | | cmdShow specifies how the window is initially displayed | | | | Returns: | | The exit code as specified in the WM_QUIT message. | | | \*----------------------------------------------------------------------------*/ #ifdef WIN32 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) #else int PASCAL WinMain(HANDLE hInst, HANDLE hPrev, LPSTR szCmdLine, int sw) #endif { MSG msg; /* Call initialization procedure */ if (!AppInit(hInst,hPrev,sw,szCmdLine)) return FALSE; DPF(("WinMain... init done")); hdd = DrawDibOpen(); /* * Polling messages from event queue */ for (;;) { if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)) { if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } else { if (rcCurrent.right == -1) SendMessage(hwndApp, WM_TIMER, 0, 0); else WaitMessage(); } } DrawDibClose(hdd); return msg.wParam; } /*----------------------------------------------------------------------------*\ | AppWndProc( hwnd, uiMessage, wParam, lParam ) | | | | Description: | | The window proc for the app's main (tiled) window. This processes all | | of the parent window's messages. | | | | Arguments: | | hwnd window handle for the window | | uiMessage message number | | wParam message-dependent | | lParam message-dependent | | | | Returns: | | 0 if processed, nonzero if ignored | | | \*----------------------------------------------------------------------------*/ LONG _export AppWndProc(hwnd, msg, wParam, lParam) HWND hwnd; unsigned msg; UINT wParam; long lParam; { PAINTSTRUCT ps; BOOL f; HDC hdc; int i; //DPF(("AppWndProc: hwnd %8x msg %8x wP=%8x lP=%8x\r\n", hwnd, msg, wParam, lParam)); switch (msg) { case WM_CREATE: InitDIB(hwnd, NULL, achFileName); // SD: these 2 lines reversed in Win 16 InitCompress(hwnd); break; case WM_LBUTTONDBLCLK: break; case WM_COMMAND: return AppCommand(hwnd,msg,wParam,lParam); case WM_INITMENU: DPF(("WM_INITMENU")); EnableMenuItem((HMENU)wParam, MENU_PASTE, IsClipboardFormatAvailable(CF_DIB) ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU)wParam, MENU_COPY, hdibCurrent ? MF_ENABLED : MF_GRAYED); EnableMenuItem((HMENU)wParam, MENU_SAVE, hdibCurrent ? MF_ENABLED : MF_GRAYED); CheckMenuItem((HMENU)wParam, MENU_DIB_4, biCurrent.biBitCount == 4 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU)wParam, MENU_DIB_8, biCurrent.biBitCount == 8 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU)wParam, MENU_DIB_16, biCurrent.biBitCount == 16 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU)wParam, MENU_DIB_24, biCurrent.biBitCount == 24 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU)wParam, MENU_STRETCH_1, rcCurrent.right == (int)biCurrent.biWidth ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU)wParam, MENU_STRETCH_2, rcCurrent.right == (int)biCurrent.biWidth*2 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU)wParam, MENU_STRETCH_15, rcCurrent.right == (int)biCurrent.biWidth*3/2 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU)wParam, MENU_STRETCH_WIN, rcCurrent.right == 0 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU)wParam, MENU_STRETCH_HUH, rcCurrent.right == -1 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU)wParam, MENU_JUST_DRAW_IT, (wDrawDibFlags & DDF_JUSTDRAWIT) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem((HMENU)wParam, MENU_FULLSCREEN, (wDrawDibFlags & DDF_FULLSCREEN) ? MF_CHECKED : MF_UNCHECKED); for (i=0; i> 16) & 0xffffu); } void NormalizeRect (PRECT prc) { if (prc->right < prc->left) SWAP(prc->right,prc->left); if (prc->bottom < prc->top) SWAP(prc->bottom,prc->top); } void RandRect(PRECT prc, int dx, int dy) { prc->left = rand() % dx; prc->right = rand() % dx; prc->top = rand() % dy; prc->bottom = rand() % dy; NormalizeRect(prc); } HANDLE CopyHandle(HANDLE h) { HANDLE hCopy; DPF(("Copying handle")); if (hCopy = GlobalAlloc(GHND,GlobalSize(h))) hmemcpy(GlobalLock(hCopy), GlobalLock(h), GlobalSize(h)); return hCopy; } #define BITMAP_X 160 #define BITMAP_Y 120 HANDLE MakeDib(UINT bits) { HANDLE hdib; LPBITMAPINFOHEADER lpbi; LPBYTE pb; int x,y; LONG biSizeImage = BITMAP_Y*(DWORD)((BITMAP_X*(bits/8)+3)&~3); DPF(("MakeDib routine")); hdib =GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+biSizeImage); lpbi = (LPVOID)GlobalLock(hdib) ; pb = (LPVOID)(lpbi+1); if (bits == 16) { for (y=0; ybiSize = sizeof(BITMAPINFOHEADER); lpbi->biWidth = BITMAP_X; lpbi->biHeight = BITMAP_Y; lpbi->biPlanes = 1; lpbi->biBitCount = bits; lpbi->biCompression = BI_RGB; lpbi->biSizeImage = biSizeImage; lpbi->biXPelsPerMeter = 0; lpbi->biYPelsPerMeter = 0; lpbi->biClrUsed = 0; lpbi->biClrImportant = 0; return hdib; } /***************************************************************************** * * dprintf() is called by the DPF macro if DEBUG is defined at compile time. * * The messages will be send to COM1: like any debug message. To * enable debug output, add the following to WIN.INI : * * [debug] * DDTEST=1 * ****************************************************************************/ #ifdef DEBUG #define MODNAME "DDTEST" static BOOL fDebug = 1; void FAR CDECL dprintf(LPSTR szFormat, ...) { char ach[128]; va_list va; if (fDebug == -1) fDebug = GetProfileIntA("Debug", MODNAME, FALSE); if (!fDebug) return; lstrcpyA(ach, MODNAME ": "); va_start(va, szFormat); wvsprintfA(ach+lstrlenA(ach),szFormat, va); va_end(va); lstrcatA(ach, "\r\n"); OutputDebugStringA(ach); } #endif