mcdonald@uxe.cso.uiuc.edu (09/23/88)
Well, I have finally delivered my little Microsoft Windows program to IBM. Now I am thinking about converting my big one to it. Problem is, I wrote the tiny test program listed below to see how slow it would be. Turns out to be about nine (9) times slower than my normal graphics package. This thing just draws three balls on the screen, and they go around in circles leaving tracks. It works fine except for speed. I tried other methods of doing animation, but this seems to be the only one that doesn't flicker badly; besides, my big program needs a memory bitmap anyway as that is the only way to store the screen for a repaint. Anyone out there know a way to speed this up? (Besides trading my 16Mhz Model 80 for a 25Mhz model.) Doug McDonald (mcdonald@uiucuxe) /* This is the BALLS.DEF file: NAME BALLS DESCRIPTION 'Balls!' STUB 'WINSTUB.EXE' CODE MOVEABLE DATA MOVEABLE MULTIPLE HEAPSIZE 8192 STACKSIZE 8192 EXPORTS Microsoft_Windows_is_SLOW */ /* This batch file will create the program: cl /c /Gsw /Zp /Os balls.c link4 balls /noe,/al:16,,/nodef win87em slibcew slibw,balls.def; */ #include "windows.h" #include <math.h> #define PI (double)3.1415926 long FAR PASCAL Microsoft_Windows_is_SLOW(HWND, unsigned, WORD, LONG); char szAppName[] = "Balls"; int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow) HANDLE hInstance, hPrevInstance; LPSTR lpszCmdLine; int nCmdShow; { HWND hWnd; MSG msg; WNDCLASS wndclass; if (!hPrevInstance) { wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = Microsoft_Windows_is_SLOW; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = GetStockObject(BLACK_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) return (FALSE); } hWnd = CreateWindow(szAppName, "Balls!", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); while (1) { if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if(msg.message == WM_QUIT)break; TranslateMessage(&msg); DispatchMessage(&msg); } else DrawScreen(hWnd); } return msg.wParam; } static short xClient, yClient, xCenter, yCenter, xTotal, yTotal, xRadius, yRadius, xPixel, yPixel; static int iturn, ifirst; static int dx1, dy1, dx2, dy2, dx3, dy3; static HBRUSH hBrush1, hBrush2, hBrush3, hBrush4; static HPEN hPen1, hPen2, hPen3; static HANDLE hBitmap; static HDC hMemDC; long far PASCAL Microsoft_Windows_is_SLOW(hWnd, iMessage, wParam, lParam) HWND hWnd; unsigned iMessage; WORD wParam; LONG lParam; { HDC hDC; short nScale; PAINTSTRUCT ps; switch (iMessage) { case WM_CREATE: hDC = GetDC(hWnd); xPixel = GetDeviceCaps (hDC, ASPECTX); yPixel = GetDeviceCaps (hDC, ASPECTY); hBrush1 = CreateSolidBrush(RGB(0,0,255)); hPen1 = CreatePen(PS_SOLID, 1, RGB(0,0,255)); hBrush2 = CreateSolidBrush(RGB(0,255,0)); hPen2 = CreatePen(PS_SOLID, 1, RGB(0,255,0)); hBrush3 = CreateSolidBrush(RGB(255,0,0)); hPen3 = CreatePen(PS_SOLID, 1, RGB(255,0,0)); hBrush4 = CreateSolidBrush(RGB(0,0,0)); ReleaseDC(hWnd, hDC); break; case WM_SIZE: iturn = 0; ifirst = 0; xCenter = (xClient = LOWORD(lParam)) /2; yCenter = (yClient = HIWORD(lParam)) /2; nScale = min(xClient * xPixel, yClient * yPixel) /16; xRadius = nScale / xPixel; yRadius = nScale / yPixel; if(hBitmap != NULL)DeleteObject(hBitmap); if(hMemDC != NULL)DeleteDC(hMemDC); hDC = GetDC(hWnd); hBitmap = CreateCompatibleBitmap(hDC,xClient,yClient); hMemDC = CreateCompatibleDC(hDC); ReleaseDC(hWnd, hDC); SelectObject(hMemDC, hBitmap); SelectObject(hMemDC, hBrush4); SelectObject(hMemDC, GetStockObject(BLACK_PEN)); Rectangle(hMemDC,0,0,xClient,yClient); break; case WM_PAINT: hDC = BeginPaint(hWnd,&ps); SelectObject(hDC, hBrush4); BitBlt(hDC,0,0,xClient,yClient,hMemDC,0,0,SRCCOPY); EndPaint(hWnd,&ps); break; case WM_DESTROY: DeleteObject(hBrush1); DeleteObject(hPen1); DeleteObject(hBrush2); DeleteObject(hPen2); DeleteObject(hBrush3); DeleteObject(hPen3); DeleteObject(hBrush4); if(hBitmap != NULL)DeleteObject(hBitmap); if(hMemDC != NULL)DeleteDC(hMemDC); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, iMessage, wParam, lParam); } return 0L; } DrawScreen(hWnd) HWND hWnd; { HDC hDC; hDC = GetDC(hWnd); SelectObject(hMemDC, hBrush4); SelectObject(hMemDC, hPen1); SelectObject(hDC, hBrush4); if(ifirst)Ellipse(hMemDC, dx1 - xRadius, dy1 - yRadius, dx1 + xRadius , dy1 + yRadius); dx1 = xCenter + xRadius * 6 * cos((double)iturn * PI / 60); dy1 = yCenter + yRadius * 6 * sin((double)iturn * PI / 60); SelectObject(hMemDC, hBrush1); Ellipse(hMemDC, dx1 - xRadius, dy1 - yRadius, dx1 + xRadius , dy1 + yRadius); BitBlt(hDC,dx1 - xRadius * 2,dy1 - yRadius*2,xRadius*4,yRadius*4, hMemDC,dx1 - xRadius * 2,dy1 - yRadius*2,SRCCOPY); SelectObject(hMemDC, hBrush4); SelectObject(hMemDC, hPen2); if(ifirst)Ellipse(hMemDC, dx2 - xRadius, dy2 - yRadius, dx2 + xRadius , dy2 + yRadius); dx2 = xCenter + xRadius * 6 * cos((double)(iturn + 40) * PI / 60); dy2 = yCenter + yRadius * 6 * sin((double)(iturn + 40) * PI / 60); SelectObject(hMemDC, hBrush2); Ellipse(hMemDC, dx2 - xRadius, dy2 - yRadius, dx2 + xRadius , dy2 + yRadius); BitBlt(hDC,dx2 - xRadius * 2,dy2 - yRadius*2,xRadius*4,yRadius*4, hMemDC,dx2 - xRadius * 2,dy2 - yRadius*2,SRCCOPY); SelectObject(hMemDC, hBrush4); SelectObject(hMemDC, hPen3); if(ifirst)Ellipse(hMemDC, dx3 - xRadius, dy3 - yRadius, dx3 + xRadius , dy3 + yRadius); dx3 = xCenter + xRadius * 6 * cos((double)(iturn + 80) * PI / 60); dy3 = yCenter + yRadius * 6 * sin((double)(iturn + 80) * PI / 60); SelectObject(hMemDC, hBrush3); Ellipse(hMemDC, dx3 - xRadius, dy3 - yRadius, dx3 + xRadius , dy3 + yRadius); BitBlt(hDC,dx3 - xRadius * 2,dy3 - yRadius*2,xRadius*4,yRadius*4, hMemDC,dx3 - xRadius * 2,dy3 - yRadius*2,SRCCOPY); ReleaseDC(hWnd,hDC); iturn += 1; ifirst = 1; if (iturn == 120) iturn = 0; }