DirectDraw7 doesn't like me.

Started by
11 comments, last by Sponge99 23 years, 8 months ago
Alright. I''m pissed. I''m doing ultra-basic DirectDraw stuff, from Lamothe''s book. But it gives some stupid errors. They aren''t compiler errors; they''re runtime errors. Here''s my DirectDraw init funtion:

bool CreateDDraw(HWND hWnd)
{
	
	ZeroMemory(&lpdd, sizeof(LPDIRECTDRAW));
	ZeroMemory(&lpdd4, sizeof(LPDIRECTDRAW));

	if (DirectDrawCreate(NULL, &lpdd, NULL) != DD_OK)
	{
		return false;
	}

	if (lpdd->QueryInterface(IID_IDirectDraw2,
							(LPVOID*)&lpdd4) != S_OK)
	{
		DestroyDDraw(hWnd);
		return false;
	}

	if (lpdd4->SetCooperativeLevel(hWnd,
									DDSCL_EXCLUSIVE |
									DDSCL_FULLSCREEN |
									DDSCL_ALLOWREBOOT) != DD_OK)
	{
		DestroyDDraw(hWnd);
		return false;
	}

	lpdd4->SetDisplayMode(640, 480, 8);/////////////////

	return true;
}
 
The line with all the comment thingies (what''s their name?) is where my problem is. I need it to set the display, but it doesn''t work. If it is commented out and then compiled/run, the program works ok (except for lack of 640x480x8 res), but when compiled with it, it runs, sets the screen mode to 640x480x8, then gives me a Debug Error box with a message about a value not staying the same between a function pointer...even though I''m not using one. Please help! Thanks!!
"Now watch as I run away in a womanly fashion." - Batman
Advertisement
Sorry about the the use of the code tag. Indentation just don''t work right.
"Now watch as I run away in a womanly fashion." - Batman
Well i see a few problems:

First, You cannot have 2 pointers to Direct Draw (this is 90% of your problem).
Delete one (lpdd4 would be a good choice since your using DD 7). Also you don''t have to use ZeroMemory with the pointers at all.

ZeroMemory(&lpdd, sizeof(LPDIRECTDRAW));
ZeroMemory(&lpdd4, sizeof(LPDIRECTDRAW));

Try something like:

LPDIRECTDRAW7 lpdd;
(Notice it''s LPDIRECTDRAW7 not LPDIRECTDRAW)


Now notice all the places you have "lpdd->..." and "lpdd4->...", you can only have one pointer to direct draw (as i mentioned) so assuming your gonna use "lpdd" alone change "lpdd4" to "lpdd".



Your next problem is with:

(lpdd->QueryInterface(IID_IDirectDraw2, (LPVOID*)&lpdd4) != S_OK)

first notice the lpdd4 in the second parameter change it to lpdd.
Now look at the first parameter you have IID_IDirectDraw2, your using direct draw 7 change it to IID_IDirectDraw7.



+AA_970+
OK, what you said all made sense (albeit, it wasn't what the book said), except I still have
2 problems..

My compiler doesn't know what LPDIRECTDRAW7 is, and it also doesn't know what
IID_IDirectDraw7 is. Is there a header file I'm missing?

Another weird thing: It works if I don't lpdd->QueryInterface. What gives?

Edited by - Sponge99 on August 25, 2000 3:55:28 AM
"Now watch as I run away in a womanly fashion." - Batman
make sure you have the DX7SDK
copy all the header files from the dxsdk into MSVC\include folder.. and all the libs from dxsdk into MSVC\lib folder

why are you querying the interface anyway?
...and make sure you have added dxguid.lib or whatever it''s called and/or defined INITGUID.

Regards,
David Stubbs
Regards,Dave
I don''t want to criticize you, +AA_970+, but his DirectDraw initializations are perfecly normal. He isn''t creating 2 DD interfaces, this is the old way of getting a higher DD interface: Create a DirectDraw (version1) interface and query for the version you''d like to use, DirectDraw4 for example.

With your modifications, he either would start using DirectDraw 1 from DirectX 1.0 (trashing lpdd4), or he would overwrite his old lpdd pointer and not be able to free the lpdd-interface again.

-

Sponge, first in your ZeroMemory, you write sizeof(LPDIRECTDRAW), since this is a pointer (LP stands for linear pointer), the sizeof() will always be 4. You cannot ZeroMemory() the DirectDraw pointer because you do not know the size of the DirectDraw-object. It''s defined as follows:
struct IDirectDraw;
typedef struct IDirectDraw FAR *LPDIRECTDRAW
so the compiler doesn''t know its size.
Those ZeroMemory() calls could be replaced with
lpdd = NULL;
lpdd4 = NULL;
which would do exactly the same in this case (lpdd is a 32-bits pointer, overwriting its adress in memory with 4 bytes is just the same as setting it to NULL )

Since both of your calls use sizeof(LPDIRECTDRAW), could it be that lpdd and lpdd4 are both of type LPDIRECTDRAW ? It should read
LPDIRECTDRAW lpdd;
LPDIRECTDRAW4 lpdd4;

The next line, QueryInterface now asks for a LPDIRECTDRAW2 (IID_IDirectDraw2) object to be put into the lpdd4 (LPDIRECTDRAW4) variable. (With +AA_970+''s modifications you had put a DD2 object in a DD1 variable, not good either...)
I''d just suggest you to use IID_IDirectDraw4 to get your LPDIRECTDRAW4 interface.

Ok, that should do the trick, but another thing:
What you''re using is DirectDraw of DirectX 6, not 7 !

I''ll post another message with the code for DX7, one second.

-Markus-
Professional C++ and .NET developer trying to break into indie game development.
Follow my progress: http://blog.nuclex-games.com/ or Twitter - Topics: Ogre3D, Blender, game architecture tips & code snippets.
Argh! >

I''ve included dxguid.lib (or whatever it''s called) AND defined INITGUID (why??). I''m Querying the interface because TOTWGPG tells me too. Should I? Maybe that''s my problem right there....
"Now watch as I run away in a womanly fashion." - Batman
To use DirectDraw7, first set up VC:

Menu "Extras"
Item "Options"
Tab "Directories"
Add your "X:\Whereever\DXSDK\Include" directory and drag-drop it to the top. Then select lib files from the dropbox to the right and do the same with the "X:\Whereever\DXSDK\Lib" directory.

This will make VC search in the DirectX7 dirs before its own ones. It is needed because VC is equipped with DX3 or DX5, and if you #include "DDraw.h", the compiler will see the DX3/5 files and use them before he reaches the DX7 dir.

-
Now your project settings

Menu "Project"
Item "Settings"
Tab "Linker"
Under "Object / Library modules", add "dxguid.lib ddraw.lib", so the line reads "dxguid.lib ddraw.lib kernel32.lib user32.....".
(The order the libs appear doesn't matter this time)

-
And, finally, how to initialize DirectDraw7
    ///////////////////////////////////////////////////////// Header.h file//LPDIRECTDRAW7 lpDD;///////////////////////////////////////////////////////// Functions.cpp file//if(DirectDrawCreateEx(NULL, (void **)&lpDD, IID_IDirectDraw7, NULL) != DD_OK) {  return false;}if(lpDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN) != DD_OK) {  DestroyDDraw(hWnd);  return false;}if(lpDD->SetDisplayMode(640, 480, 8, 0, 0) != DD_OK) {  DestroyDDraw(hWnd);  return false;}    


See, the DX7 DDraw initialization is a lot easier than previous versions and the interface names (DD7 for DX7 unlike DD4 for DX6) is, imho, more logical
I don't know that book you mentioned, but it's using DX6, not DX7. Perhaps they re-used code from the DX6 version of the book, only adding new DX7 features in some places ?

Note that if using INITGUID instead of including dxguid.lib, you should define INITGUID in just _one_ .cpp file, _before_ including DDraw.h (or any other dx header file).

-Markus-


Edited by - Cygon on August 25, 2000 7:32:42 AM
Professional C++ and .NET developer trying to break into indie game development.
Follow my progress: http://blog.nuclex-games.com/ or Twitter - Topics: Ogre3D, Blender, game architecture tips & code snippets.
YES!!!! THANKYOU!

That was all that was wrong, that stupid QueryInterface crap. Could someone tell me what that was used for? Haahhaa! I feel much better now.

Problems still exhibited: SetDisplayMode doesn't take 5 parameters, only 3...and it doesn't work if I use DirectDrawCreateEx (it compiles fine) but does if I use DirectDrawCreate......

Thankyou all for the help, atleast it works now, god I love this place.

Edited by - Sponge99 on August 25, 2000 7:46:51 AM
"Now watch as I run away in a womanly fashion." - Batman

This topic is closed to new replies.

Advertisement