• Advertisement
Sign in to follow this  

Blitting Help

This topic is 4245 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

It seems like I pop in every so often to just ask for help and then leave. D< Well, thanks. Onto the code. This is supposed to be sort of like a Echt-a-Sketch thing. When you click the arrow keys it's supposed to blit a 4x4 square in the direction of the arrow key you pressed. This was based on other code I wrote that did not use the blitter, and only did 1 pixel. There are no syntax errors, or at least there shouldn't be.
#define WIN32_LEAN_AND_MEAN

#include<windows.h>
#include<windowsx.h>
#include<ddraw.h>

#define WINCLASS "winclass"

#define KEYDOWN(VK_CODE) ((GetAsyncKeyState(VK_CODE)& 0x8000) ? 1 : 0)

int x = 400,y = 300;

LPDIRECTDRAW7 lpdd = NULL;
PALETTEENTRY palette[256];
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL;
LPDIRECTDRAWPALETTE lpddpal = NULL;
DDSURFACEDESC2 ddsd;
HWND windowhandle;
int windowclosed = 0;

int Game_Main();
int Game_Init();
int Game_ShutDown();
LRESULT CALLBACK WinProc(HWND hwnd,
						 UINT msg,
						 WPARAM wparam,
						 LPARAM lparam)
{
	switch(msg)
	{
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			return 0;
		}break;
	}
	return DefWindowProc(hwnd, msg, wparam, lparam);
}

int WINAPI WinMain(HINSTANCE hinstance,
				   HINSTANCE hprevinstance,
				   LPSTR lpcmdline,
				   int ncmdshow)
{
	WNDCLASSEX winclass;
	HWND hwnd;
	MSG msg;
	
	winclass.cbClsExtra = 0;
	winclass.cbSize = sizeof(WNDCLASSEX);
	winclass.cbWndExtra = 0;
	winclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
	winclass.hInstance = hinstance;
	winclass.lpfnWndProc = WinProc;
	winclass.lpszClassName = WINCLASS;
	winclass.lpszMenuName = NULL;
	winclass.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;

	if(!RegisterClassEx(&winclass))
		return 0;

	if(!(hwnd = CreateWindowEx(NULL,
								WINCLASS,
								"Paintz",
								WS_POPUP | WS_VISIBLE,
								0,0,
								800,600,
								NULL,
								NULL,
								hinstance,
								NULL)))
		return 0;
	
	windowhandle = hwnd;

	Game_Init();	

	while(TRUE)
	{
		
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			if(msg.message == WM_QUIT)
				break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		Game_Main();
	}

	Game_ShutDown();

	return msg.lParam;
}

int Game_Main()
{
	if(KEYDOWN(VK_ESCAPE))
	{
		SendMessage(windowhandle, WM_DESTROY, NULL, NULL);
		windowclosed = 1;
	}
	if(windowclosed = 1)
		return 0;
	if(FAILED(lpddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL)))
		return 0;

	DDBLTFX ddbltfx;
	RECT rect;

	int pitch = (int)ddsd.lPitch;
	UCHAR* surface = (UCHAR*)ddsd.lpSurface;
	UCHAR color = 0;

	memset(&ddbltfx, 0, sizeof(ddbltfx));
	ddbltfx.dwSize = sizeof(ddbltfx);

	ddbltfx.dwFillColor = 0;

	if(KEYDOWN(VK_RIGHT) | KEYDOWN(VK_LEFT) | KEYDOWN(VK_UP) | KEYDOWN(VK_DOWN))
	{
		if(KEYDOWN(VK_RIGHT))
		{
			if(x+1 > 799)
				x = 799;
			if(x+1 < 799)
				x++;
		}
		if(KEYDOWN(VK_LEFT))
		{
			if(x-1 < 0)
				x = 0;
			if(x-1 > 0)
				x--;
		}
		if(KEYDOWN(VK_UP))
		{
			if(y-1 > 599)
				y = 599;
			if(y-1 < 599)
				y--;
		}
		if(KEYDOWN(VK_DOWN))
		{
			if(y+1 == 0)
				y = 0;
			if(y+1 > 0)
				y++;
		}
		rect.right = x+2;
		rect.left = x-2;
		rect.top = y-2;
		rect.bottom = y+2;
		if(FAILED(lpddsprimary->Blt(&rect,NULL,NULL,
									DDBLT_COLORFILL | DDBLT_WAIT,
									&ddbltfx)))
			return 0;
	}

	if(FAILED(lpddsprimary->Unlock(NULL)))
		return 0;

	Sleep(30);

	return 0;
}
int Game_Init()
{
	if(FAILED(DirectDrawCreateEx(NULL, (void**)&lpdd, IID_IDirectDraw7, NULL)))
		return 0;
	if(FAILED(lpdd->SetCooperativeLevel(windowhandle, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT | DDSCL_ALLOWMODEX)))
		return 0;
	if(FAILED(lpdd->SetDisplayMode(800,600,8,0,0)))
		return 0;

	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);

	ddsd.dwFlags = DDSD_CAPS;

	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

	palette[0].peRed = 255;
	palette[0].peGreen = 255;
	palette[0].peBlue = 255;
	palette[0].peFlags = PC_NOCOLLAPSE;

	if(FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette, &lpddpal, NULL)))
		return 0;

	if(FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
		return 0;

	if(FAILED(lpddsprimary->SetPalette(lpddpal)))
		return 0;

	return 0;
}
int Game_ShutDown()
{
	return 0;
}

Share this post


Link to post
Share on other sites
Advertisement
I've only had a quick look at your code and you haven't actually described what is going wrong, but:

Why are you locking your primary surface and retrieving the surface pointer when you are then not using the pointer? I believe that the blt operation is probably failing because the surface is locked.

You don't need to lock a surface to blt to it. In fact, if you lock a surface, I'm pretty sure that DirectDraw CAN'T blit to it until it is unlocked.

Try removing your lock and unlock code and all should be fine.

HTH Paul

[EDIT] I'm also slightly confused by your palette code, although I never did a lot with 256 color DirectDraw. You seem to be initalising the first member of your palette values to pure white, but not initialising any of the others, then passing this into CreatePalette.

I remember writing code years ago to load a palette from a 256 color bitmap. As I recall I had to create an array of 256 palette entries, fill them all in from the bitmap header then pass the array to CreatePalette.

Since your palette variable is global, all the other entries will be set to zero so you will have one white color in index 0, and all the rest will be black.

Of course, this may be what you want in which case, ignore me.

[EDIT AGAIN (Sorry, will go away in a minute!)] You are also not clearing your primary buffer at any point so your background will end up containing whatever random crap was in the graphics memory when your program is run. I appreciate your etch-a-sketch will go tits up if you clear the buffer every frame so you should probably blit to the entire buffer once in your init code to clear it to white.

[Edited by - EasilyConfused on July 7, 2006 6:25:21 AM]

Share this post


Link to post
Share on other sites
I was using the surface pointer before for my other code that this was based one. ><

But I still have trouble with it. D=
Still doesn't do anything when I press the arrow keys.

There aren't that many changes to this. I took out the lock, and anything that would have needed the lock. Added some releases but that probably won't affect the blitter.


#define WIN32_LEAN_AND_MEAN

#include<windows.h>
#include<windowsx.h>
#include<ddraw.h>

#define WINCLASS "winclass"

#define KEYDOWN(VK_CODE) ((GetAsyncKeyState(VK_CODE)& 0x8000) ? 1 : 0)

int x = 400,y = 300;

LPDIRECTDRAW7 lpdd = NULL;
PALETTEENTRY palette[256];
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL;
LPDIRECTDRAWPALETTE lpddpal = NULL;
DDSURFACEDESC2 ddsd;
HWND windowhandle;
int windowclosed = 0;

int Game_Main();
int Game_Init();
int Game_ShutDown();
LRESULT CALLBACK WinProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
switch(msg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}break;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}

int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
WNDCLASSEX winclass;
HWND hwnd;
MSG msg;

winclass.cbClsExtra = 0;
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.cbWndExtra = 0;
winclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
winclass.hInstance = hinstance;
winclass.lpfnWndProc = WinProc;
winclass.lpszClassName = WINCLASS;
winclass.lpszMenuName = NULL;
winclass.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;

if(!RegisterClassEx(&winclass))
return 0;

if(!(hwnd = CreateWindowEx(NULL,
WINCLASS,
"Paintz",
WS_POPUP | WS_VISIBLE,
0,0,
800,600,
NULL,
NULL,
hinstance,
NULL)))
return 0;

windowhandle = hwnd;

Game_Init();

while(TRUE)
{

if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}

Game_Main();
}

Game_ShutDown();

return msg.lParam;
}

int Game_Main()
{
if(KEYDOWN(VK_ESCAPE))
{
SendMessage(windowhandle, WM_DESTROY, NULL, NULL);
windowclosed = 1;
}
if(windowclosed = 1)
return 0;

DDBLTFX ddbltfx;
RECT rect;

UCHAR color = 0;

memset(&ddbltfx, 0, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);

ddbltfx.dwFillColor = 0;

if(KEYDOWN(VK_RIGHT) | KEYDOWN(VK_LEFT) | KEYDOWN(VK_UP) | KEYDOWN(VK_DOWN))
{
if(KEYDOWN(VK_RIGHT))
{
if(x+1 > 799)
x = 799;
if(x+1 < 799)
x++;
}
if(KEYDOWN(VK_LEFT))
{
if(x-1 < 0)
x = 0;
if(x-1 > 0)
x--;
}
if(KEYDOWN(VK_UP))
{
if(y-1 > 599)
y = 599;
if(y-1 < 599)
y--;
}
if(KEYDOWN(VK_DOWN))
{
if(y+1 == 0)
y = 0;
if(y+1 > 0)
y++;
}
rect.right = x+2;
rect.left = x-2;
rect.top = y-2;
rect.bottom = y+2;
if(FAILED(lpddsprimary->Blt(&rect,NULL,NULL,
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx)))
return 0;
}

memset(&ddsd, 0, sizeof(ddsd));

Sleep(30);

return 0;
}
int Game_Init()
{
if(FAILED(DirectDrawCreateEx(NULL, (void**)&lpdd, IID_IDirectDraw7, NULL)))
return 0;
if(FAILED(lpdd->SetCooperativeLevel(windowhandle, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT | DDSCL_ALLOWMODEX)))
return 0;
if(FAILED(lpdd->SetDisplayMode(800,600,8,0,0)))
return 0;

memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

ddsd.dwFlags = DDSD_CAPS;

ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

palette[0].peRed = 255;
palette[0].peGreen = 255;
palette[0].peBlue = 255;
palette[0].peFlags = PC_NOCOLLAPSE;

if(FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette, &lpddpal, NULL)))
return 0;

if(FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
return 0;

if(FAILED(lpddsprimary->SetPalette(lpddpal)))
return 0;

return 0;
}
int Game_ShutDown()
{
if(FAILED(lpdd->Release()))
return 0;
if(FAILED(lpddsprimary->Release()))
return 0;
if(FAILED(lpddpal->Release()))
return 0;
return 0;
}




Also, how would I clear the primary buffer? I will have to use memset() right?

Thanks in advance.

[Edit]
Well, I tried getting this to work in a program that my blitting function actually worked, and it worked. Odd. But I'd still like to know what's wrong with my code. @_@

[Edited by - NecoSpes on July 7, 2006 2:14:47 PM]

Share this post


Link to post
Share on other sites
NecoSpecs - your graphics code works fine. There are two tiny but annoying errors in GameMain():

if(windowclosed = 1) return 0;

should be:

if(windowclosed == 1) return 0;

and

if(KEYDOWN(VK_RIGHT) | KEYDOWN(VK_LEFT) | KEYDOWN(VK_UP) | KEYDOWN(VK_DOWN))

should be:

if(KEYDOWN(VK_RIGHT) || KEYDOWN(VK_LEFT) || KEYDOWN(VK_UP) || KEYDOWN(VK_DOWN))

Trouble with a complicated thing like a DirectDraw app is that you quite often can't see the wood for the trees. Compiled with corrections with BCC55 and happily let me draw silly pictures on the screen.

HTH Paul

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement