Check this code.. why is dx7 ddraw so slow...

Started by
2 comments, last by drarem 22 years, 6 months ago
Please refer to the code below: compiled in Dev-C++.. even in 640x480, the ''sprite'' moves slowly across the screen, the mouse is instantaneous but the sprite, when i''m holding down the left arrow key, moves slow. I even put the main code into a while(running=true) type of loop and used getasynckeystates to detect when you hit VK_ESCAPE or VK_LEFT.. moves smoother but still slow. I know in win32 api, it would zip across the screen, even CDXLIB using MSVC v5.0, I had to add a delay. i''m blitting the background (bypassing the clearscreen), to gain a little speed, is there something I am overlooking? thanx in advance it compiles to 17kb Feel free to use this code as I have begged/borrowed/stolen from the net, but if you make lotsa money using it in your next great 2D engine, I want a cut. haha #include "stdafx.h" #include #include #include HINSTANCE g_hinstance; HWND g_hwnd; bool g_running; bool g_active; const char* g_appName = "My DirectDraw Program"; char szBitmap[ ] = "Greenstone.bmp"; char szBckgnd[ ] = "backgrnd.bmp"; int ef=32; int f=0; HBITMAP hbm; HDC hdcImage= NULL; HDC hdcSurf= NULL; IDirectDraw7* dd; IDirectDrawSurface7* primary; IDirectDrawSurface7* backgrnd; IDirectDrawSurface7* back; IDirectDrawSurface7* lpA; DDSURFACEDESC2 ddsd; void update(); bool createWindow(); LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM); bool initDirectDraw(int,int,int); void clearScreen(); void flip(); void cleanUp(); void lock(); void unlock(); void setPixel(int, int, unsigned char); void CopyBitmap(IDirectDrawSurface7*, HBITMAP, int, int, int, int); int APIENTRY WinMain(HINSTANCE hinstance, HINSTANCE, LPSTR cmdLine, int) { g_hinstance = hinstance; RECT lpR; RECT lpB; int e=0; POINT p; if(!createWindow()) return 0; SetFocus(g_hwnd); ShowWindow(g_hwnd, SW_SHOWNORMAL); UpdateWindow(g_hwnd); if(!initDirectDraw(800,600,16)) return 0; g_running = true; backgrnd = DDLoadBitmap(dd, "backgrnd.bmp", 0, 0); lpA = DDLoadBitmap(dd, "Greenstone.bmp", 0, 0); DDSetColorKey(lpA, RGB(0, 0, 0)); lpB.left=0; lpB.right=800; lpB.top=0; lpB.bottom=600; lpR.left=0; lpR.right=64; lpR.top=0; lpR.bottom=64; back->BltFast(0, 0, backgrnd, &lpB, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT); back->BltFast(0, 0, lpA, &lpR, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT); while(true) { MSG msg; if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { if(msg.message == WM_QUIT) return msg.wParam; // Send messages to WindowProc TranslateMessage(&msg); DispatchMessage(&msg); } else if(g_running && g_active) // call variable updates here // then update() to call screen updates, which flips screen at the end while (g_running) { // update(); // for (e=0; eBltFast(0, 0, backgrnd, &lpB, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT); back->BltFast(ef, 0, lpA, &lpR, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT); GetCursorPos(&p); back->BltFast(p.x, p.y, lpA, &lpR, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT); if (GetAsyncKeyState(VK_ESCAPE)) g_running = false; if (GetAsyncKeyState(VK_RIGHT)) ef+=1; flip(); } } // Prevent compiler warning even though we never get here return -1; } bool createWindow() { WNDCLASSEX wc; ZeroMemory(&wc, sizeof(wc)); wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hIcon = LoadIcon(0, IDI_APPLICATION); wc.hIconSm = LoadIcon(0, IDI_WINLOGO); wc.hInstance = g_hinstance; wc.lpfnWndProc = wndProc; wc.lpszClassName = g_appName; wc.cbSize = sizeof(wc); wc.style = CS_VREDRAW | CS_HREDRAW; if(RegisterClassEx(&wc)) { g_hwnd = CreateWindowEx( WS_EX_TOPMOST, g_appName, g_appName, WS_POPUP | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, g_hinstance, 0 ); return g_hwnd != 0; } return false; } LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l) { switch(msg) { case WM_SETCURSOR: SetCursor(NULL); return 0; case WM_KEYDOWN: if (GetAsyncKeyState(VK_ESCAPE)) msg = WM_DESTROY; case WM_DESTROY: cleanUp(); PostQuitMessage(0); return 0; case WM_ACTIVATE: g_active = (LOWORD(w) != WA_INACTIVE) && !((BOOL)HIWORD(w)); break; } return DefWindowProc(hwnd, msg, w, l); } bool initDirectDraw(int Sx, int Sy, int Sc) { HRESULT r = DirectDrawCreateEx(0, (void**)&dd, IID_IDirectDraw7, 0); if(FAILED(r)) return false; r = dd->SetCooperativeLevel(g_hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT); if(FAILED(r)) return false; r = dd->SetDisplayMode(Sx, Sy, Sc, 0, 0); if(FAILED(r)) { dd->Release(); return false; } ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; r = dd->CreateSurface(&ddsd, &primary, 0); if(FAILED(r)) { dd->Release(); return false; } ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; r = primary->GetAttachedSurface(&ddsd.ddsCaps, &back); if(FAILED(r)) { primary->Release(); dd->Release(); return false; } return true; } void clearScreen() { DDBLTFX clsBltFX; ZeroMemory(&clsBltFX, sizeof(clsBltFX)); clsBltFX.dwSize = sizeof(clsBltFX); back->Blt(0, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &clsBltFX); } void flip() { // dd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0); primary->Flip(0, DDFLIP_WAIT); } void cleanUp() { if(dd) { dd->Release(); if(primary) primary->Release(); } } unsigned char* videoMemory; long pitch; void lock() { DDSURFACEDESC2 ddsd; ddsd.dwSize = sizeof(ddsd); back->Lock(0, &ddsd, DDLOCK_WAIT, 0); videoMemory = (unsigned char*)ddsd.lpSurface; pitch = ddsd.lPitch; } void unlock() { back->Unlock(0); } void setPixel(int x, int y, int c) { videoMemory[x + pitch * y] = c; } void update() { flip(); // clearScreen(); }
I'll give you a beating like Rodney King who deserved it!=====================================Any and all ideas, theories, and text c2004,c2009 BrainDead Software. All Rights Reserved.
Advertisement
I don''t think there is any problem with speed here. The problem is that DDraw probably locks along your screen''s refresh rate, so you only get about 60 or 75 frames per second. And since you are moving the sprite a single pixel each frame, it will only move 60 or 75 pixels per second, which feels slow.

Either try to disable the "vertical retrace", or just speed up the movement of the sprite. I don''t think this is a performance problem, anyway.

My Stuff : [ Whispers in Akarra (online rpg) || L33T WAR (multiplayer game) || The Asteroid Menace (another game) ]
I find that 1pel/frame is a very slow velocity for sprites. Try like, 4 or 5pels/frame.

Paradigm Shift 2000

Edited by - Paradigm Shift 2000 on October 20, 2001 7:28:16 PM
"I am Locutus of Borg. Resistance is Futile." -- Locutus of Borg
Thank you thank you! It does speed it up and yet it looks smooth, which confuses me..

with this command:

primary->Flip(0, DDFLIP_WAIT);
it looks very smooth and fast, I would think it would move in chunks..

however with this command:

dd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
it moves in chunks (however many pels/framerate I set it for)...

why is that?




I fseek, therefore I fam.
I'll give you a beating like Rodney King who deserved it!=====================================Any and all ideas, theories, and text c2004,c2009 BrainDead Software. All Rights Reserved.

This topic is closed to new replies.

Advertisement