Jump to content
  • Advertisement
Sign in to follow this  
dist0rted

DirectDraw 7 Setup Problem

This topic is 5041 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

For some reason DirectDraw won't setup. I run my application and I make it exit if there's a problem in my DDSetup() function, and it exits on it's own. Here's the source code for it:
#include <windows.h>
#include <ddraw.h>
#include "ddutil.h"

char szAppName[256];

HWND hWnd;
MSG Msg;
WNDCLASSEX WndClass;
HDC hDC;

LPDIRECTDRAW7 lpDD;
DDSURFACEDESC2 DDSD;
DDSCAPS2 DDSCaps;
LPDIRECTDRAWSURFACE7 lpDDSPrimary, lpDDSSecondary;
LPDIRECTDRAWSURFACE7 lpDDSBlackBackground, lpDDSBitmapTest;

RECT rRect;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
bool DDSetup(void);
void DDRender(void);
void DDShutdown(void);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{

	strcpy(szAppName, "DirectX");

	WndClass.cbClsExtra = 0;
	WndClass.cbSize = sizeof(WNDCLASSEX);
	WndClass.cbWndExtra = 0;
	WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	WndClass.hIcon = LoadIcon(hInstance, szAppName);
	WndClass.hIconSm = LoadIcon(hInstance, szAppName);
	WndClass.lpfnWndProc = WndProc;
	WndClass.lpszClassName = szAppName;
	WndClass.lpszMenuName = NULL;
	WndClass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

	RegisterClassEx(&WndClass);

	hWnd = CreateWindowEx(NULL, szAppName, szAppName, WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);

	ShowWindow(hWnd, SW_SHOWDEFAULT);
	UpdateWindow(hWnd);

	if (!DDSetup())
	{

		PostQuitMessage(0);

	}

	while (Msg.message != WM_QUIT)
	{

		if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
		{

			TranslateMessage(&Msg);
			DispatchMessage(&Msg);

		}
		else
		{

			if (GetAsyncKeyState(VK_ESCAPE))
			{

				PostQuitMessage(0);

			}

			DDRender();

		}

	}

	DDShutdown();

	UnregisterClass(szAppName, hInstance);

}

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{

	switch (Msg)
	{

	case WM_CLOSE:

		DestroyWindow(hWnd);

		break;

	case WM_DESTROY:

		PostQuitMessage(0);

		break;

	default:

		break;

	}

	return DefWindowProc(hWnd, Msg, wParam, lParam);

}

bool DDSetup(void)
{

	if (DirectDrawCreateEx(NULL, (void **)&lpDD, IID_IDirectDraw7, NULL) != DD_OK)
	{

		return false;

	}

	if (lpDD->SetCooperativeLevel(hWnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT) != DD_OK)
	{

		return false;

	}

	if (lpDD->SetDisplayMode(800, 600, 16, 0, 0) != DD_OK)
	{

		return false;

	}

	DDSD.dwSize = sizeof(DDSD);
	DDSD.dwFlags = DDSD_CAPS;
	DDSD.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
	DDSD.dwBackBufferCount = 1;

	if (lpDD->CreateSurface(&DDSD, &lpDDSPrimary, NULL) != DD_OK)
	{

		return false;

	}

	DDSCaps.dwCaps = DDSCAPS_BACKBUFFER;

	lpDDSPrimary->GetAttachedSurface(&DDSCaps, &lpDDSSecondary);

	lpDDSBlackBackground = DDLoadBitmap(lpDD, "blackbackground.bmp", 0, 0);

	lpDDSBitmapTest = DDLoadBitmap(lpDD, "test.bmp", 0, 0);
	DDSetColorKey(lpDDSBitmapTest, CLR_INVALID);

	return true;

}

void DDRender(void)
{

	SetRect(&rRect, 0, 0, 800, 600);
	lpDDSSecondary->BltFast(0, 0, lpDDSBlackBackground, &rRect, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT);

	SetRect(&rRect, 0, 0, 32, 32);
	lpDDSSecondary->BltFast(0, 0, lpDDSBitmapTest, &rRect, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);

	lpDDSSecondary->GetDC(&hDC);

	SetBkMode(hDC, TRANSPARENT);
	SetTextColor(hDC, RGB(255, 0, 0));
	SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));

	TextOut(hDC, 100, 100, "Hello, World!", strlen("Hello, World!"));

	lpDDSSecondary->ReleaseDC(hDC);

	lpDDSPrimary->Flip(NULL, DDFLIP_WAIT);

}

void DDShutdown(void)
{

	if (lpDDSBlackBackground)
	{

		lpDDSBlackBackground->Release();
		lpDDSBlackBackground = NULL;

	}

	if (lpDDSSecondary)
	{

		lpDDSSecondary->Release();
		lpDDSSecondary = NULL;

	}

	if (lpDDSPrimary)
	{

		lpDDSPrimary->Release();
		lpDDSPrimary = NULL;

	}

	if (lpDD)
	{

		lpDD->Release();
		lpDD = NULL;

	}

}

I get no errors when I try to build and run this program. The blackbackground.bmp and test.bmp files are in the same directory as the main .exe.

Share this post


Link to post
Share on other sites
Advertisement
Hello,

I haven't done direct draw 7 in a while so I wouldn't be able to help you out with the correctness of your code. One thing that I can suggest (it helps in debugging) is that you can have your functions return a different error code (an integer) for each error that it produces, instead of returning false all the time. This will tell you more about your errors and where it is failing if you print out the error code or a message associated with it.

Another debugging technique that I use is to print out messages to see if the program is executing that piece of code.

Once you find out where the error is happening then you can concentrate on that specific piece of code.

Hope that helps you find the specific problem,

Richard

Share this post


Link to post
Share on other sites
I changed the Setup function to an int an had each error return a specific value to find that the error was in the SetCooperativeLevel() function, but what am I doing wrong? It looks fine to me.

Share this post


Link to post
Share on other sites
Hmmmm, sounds like an invalid handle to the window can be the only problem. Check to see if hWnd == 0, if it is there is a problem with the CreateWindowEx() call (unless of course you can see the window then there would be nothing wrong with the handle).

Try changing the parts in the CreateWindowEx() where the width and height is and change it to a number (i.e. 800 width and 600 height) see if that affects it.

Richard

Share this post


Link to post
Share on other sites
I would try tracing through the code with the debugger. There isn't that much code, so it shouldn't take very long to isolate the problem.

Share this post


Link to post
Share on other sites
I know it's not hWnd - I've done this before, but I accidentally deleted my other DirectX project so I started this one. I know that the Windows code is exactly the same, I had to look to the books on setting up DirectDraw again, though.

Yet I don't know how to use the debugger to check for errors. Any help?

Share this post


Link to post
Share on other sites
I have debugged your code and got it to run correctly and I'm very sure what makes the DirectDraw-program end. Take a look at these lines of code:


DDSD.dwSize = sizeof(DDSD);
DDSD.dwFlags = DDSD_CAPS;
DDSD.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
DDSD.dwBackBufferCount = 1;

HRESULT hResult = lpDD->CreateSurface(&DDSD, &lpDDSPrimary, NULL);




The dwBackBufferCount member is set to 1 but the member hasn't been enabled! For example the ddsCaps member has been enabled by setting DDSD.dwFlags to DDSD_CAPS. CreateSurface will check which flags are enabled and then check the corresponding DDSD members so DDSD_BACKBUFFERCOUNT must be set in DDSD.dwFlags to enable DDSD.dwBackBufferCount:


DDSD.dwSize = sizeof(DDSD);
DDSD.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
DDSD.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
DDSD.dwBackBufferCount = 1;

HRESULT hResult = lpDD->CreateSurface(&DDSD, &lpDDSPrimary, NULL);




The DDSD.BackBufferCount is needed because lpDDSPrimary has been set up for a flipping chain and CreateSurface expects at least 1 backbuffer but then the DDSD.dwBackBufferCount is not enabled. An error is produced and the application exits. Hope that helped.

\Jimmy H

Share this post


Link to post
Share on other sites
That is another error, but this still doesn't make the program run correctly. I know it's that SetCooperativeLevel() function, but I have no idea what I'm doing wrong. I've tried putting the screen size (1075 x 768) in place of the GetSystemMetrics() calls, but it still craps out on me. What the hell is going on here?

Share this post


Link to post
Share on other sites
Are you sure its the SetCooperativeLevel-function? The only problem to fix I found was when setting up the DDSD and calling CreateSurface for the primary surface, so it became:
DDSD.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
I will post the code I got to work, its exactly the same as your code but I included ddutil.cpp manually, enabled the DDSD.dwBackBufferCount member as explained and removed the loading and blitting of the bitmaps since I don't have them. I put comments above these changes. Here goes:

#include <windows.h>
#include <ddraw.h>
#include "ddutil.h"

//included the ddutil.cpp manually
#include "ddutil.cpp"

char szAppName[256];

HWND hWnd;
MSG Msg;
WNDCLASSEX WndClass;
HDC hDC;

LPDIRECTDRAW7 lpDD;
DDSURFACEDESC2 DDSD;
DDSCAPS2 DDSCaps;
LPDIRECTDRAWSURFACE7 lpDDSPrimary, lpDDSSecondary;
LPDIRECTDRAWSURFACE7 lpDDSBlackBackground, lpDDSBitmapTest;

RECT rRect;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
bool DDSetup(void);
void DDRender(void);
void DDShutdown(void);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{

strcpy(szAppName, "DirectX");

WndClass.cbClsExtra = 0;
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.cbWndExtra = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon(hInstance, szAppName);
WndClass.hIconSm = LoadIcon(hInstance, szAppName);
WndClass.lpfnWndProc = WndProc;
WndClass.lpszClassName = szAppName;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

RegisterClassEx(&WndClass);

hWnd = CreateWindowEx(NULL, szAppName, szAppName, WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);

if (!DDSetup())
{

PostQuitMessage(0);

}

while (Msg.message != WM_QUIT)
{

if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{

TranslateMessage(&Msg);
DispatchMessage(&Msg);

}
else
{

if (GetAsyncKeyState(VK_ESCAPE))
{

PostQuitMessage(0);

}

DDRender();

}

}

DDShutdown();

UnregisterClass(szAppName, hInstance);

}

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{

switch (Msg)
{

case WM_CLOSE:

DestroyWindow(hWnd);

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

break;

}

return DefWindowProc(hWnd, Msg, wParam, lParam);

}

bool DDSetup(void)
{

if (DirectDrawCreateEx(NULL, (void **)&lpDD, IID_IDirectDraw7, NULL) != DD_OK)
{

return false;

}

if (lpDD->SetCooperativeLevel(hWnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT) != DD_OK)
{

return false;

}

if (lpDD->SetDisplayMode(800, 600, 16, 0, 0) != DD_OK)
{

return false;

}

DDSD.dwSize = sizeof(DDSD);

//DDSD.dwFlags must be set to DDSD_CAPS | DDSD_BACKBUFFERCOUNT to enable
//both DDSD.ddsCaps and DDSD.dwBackBufferCount when calling CreateSurface
DDSD.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
DDSD.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
DDSD.dwBackBufferCount = 1;

if (lpDD->CreateSurface(&DDSD, &lpDDSPrimary, NULL) != DD_OK)
{

return false;

}

DDSCaps.dwCaps = DDSCAPS_BACKBUFFER;

lpDDSPrimary->GetAttachedSurface(&DDSCaps, &lpDDSSecondary);

//removed the loading of the bitmaps since I don't have them
//lpDDSBlackBackground = DDLoadBitmap(lpDD, "blackbackground.bmp", 0, 0);

//lpDDSBitmapTest = DDLoadBitmap(lpDD, "test.bmp", 0, 0);
//DDSetColorKey(lpDDSBitmapTest, CLR_INVALID);

return true;

}

void DDRender(void)
{
//removed the blt-ing of the bitmaps since I don't have them
//SetRect(&rRect, 0, 0, 800, 600);
//lpDDSSecondary->BltFast(0, 0, lpDDSBlackBackground, &rRect, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT);

//SetRect(&rRect, 0, 0, 32, 32);
//lpDDSSecondary->BltFast(0, 0, lpDDSBitmapTest, &rRect, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);

lpDDSSecondary->GetDC(&hDC);

SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, RGB(255, 0, 0));
SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));

TextOut(hDC, 100, 100, "Hello, World!", strlen("Hello, World!"));

lpDDSSecondary->ReleaseDC(hDC);

lpDDSPrimary->Flip(NULL, DDFLIP_WAIT);

}

void DDShutdown(void)
{

if (lpDDSBlackBackground)
{

lpDDSBlackBackground->Release();
lpDDSBlackBackground = NULL;

}

if (lpDDSSecondary)
{

lpDDSSecondary->Release();
lpDDSSecondary = NULL;

}

if (lpDDSPrimary)
{

lpDDSPrimary->Release();
lpDDSPrimary = NULL;

}

if (lpDD)
{

lpDD->Release();
lpDD = NULL;

}

}



I hope it helped this time. Believe me, this code works, i just compiled and run it. If not its not the code that's the problem then its probably the video card not supporting something or a linker that does not tell when there are linking errors. What compiler/environment do you use?

\Jimmy H

Share this post


Link to post
Share on other sites
Quote:
Original post by dist0rted
I've tried putting the screen size (1075 x 768)

For real? Because I doubt you'd find many video cards actually supporting that resolution. I'm sure you meant 1024x768. But I thought I'd mention it just to make sure.

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!