Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Zorodius

What. The. HELL?

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

I've been working on some fairly simple code, and totally rewriting some stuff I did a long time ago. I have encountered an error whose only logical explanation would appear to be demonic possession. If anyone can tell me why this is occuring, or give me the name of a good exorcist, I'd be grateful. First, a little information about what I'm doing: I'm trying to write a small sprite library that uses DirectDraw. To help me with all my coding needs, I've written a really simple function that takes a string as an argument and writes it to a file called ErrorRecord.txt. This way, I can easilly tell when and where problems are occuring. This function is called Rec(). I've written a program that uses DirectDraw to perform the adventurous task of changing the resolution. When a key is pressed, the program exits. Yes, I know, it's glorious. Thank you for that standing ovation. Now I'm attempting to add some code for manipulating sprites, one incredibly small step at a time. I have written a class, called Sprite, with almost nothing in it:
  
class Sprite{
	public:
		Sprite();
		~Sprite();
		bool LoadBitmap(char * filename, LPDIRECTDRAW lpdd);
	private:
		LPDIRECTDRAWSURFACE imageSurface;
};    
The constructors and destructors look like this:
  
Sprite::Sprite()
{
	Rec("Default constructor for Sprite class invoked.");
	
	imageSurface = NULL;
}

Sprite::~Sprite()
{
	Rec("Destructor for Sprite class invoked.");
	
	imageSurface->Release();
}    
Not exactly a lot of room for error so far. LoadBitmap() has been written, but isn't invoked anywhere, so I'm not listing it here. Now, in WinMain, I have something that looks like this:
  
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE ignoreMe, LPSTR arguments, int showStyle)
{
	MSG recentMsg;
	
	ClearRec();
	Rec("Program Launched. Beginning Initialization...");
	
		// Attempt to initialize.

		if(!InitializeAll(hinst, showStyle))
		{
			Rec("Error during Initialization.");
			return 1;
		}

...(other stuff)...
    
ClearRec() just empties the previous Error Record. InitializeAll looks like this:
  
bool InitializeAll(HINSTANCE hinst, int showStyle)
{
	HWND hWnd;
	WNDCLASS wc;
	
	srand((unsigned)time(NULL));
	primaryWindowHandle = NULL;
	
	// *** Window Initialization ***

	InitDefaultWindowClass(&wc, hinst);
	
	Rec("Registering class.");
		if(!RegisterClass(&wc))
		{
			Rec("Error registering class.");
			return false;
		}

       ... (more initialization stuff) ...

        Rec("Allocating sprite.");
	exampleSprite = new Sprite;
	Rec("Sprite allocated.");
	
	Rec("Initialization Successfully Completed.");
	return true;
}
   
Now, here's the problem. If I take the EXACT code I have right there, and comment out the line "exampleSprite = new Sprite;", the code works perfectly . No problems whatsoever. However, with that line in, the program quits out earlier, and my Error Record.txt looks like this:
  
Sun Feb 24 02:26:11 2002 Program Launched. Beginning Initialization...
Sun Feb 24 02:26:11 2002 Registering class.
Sun Feb 24 02:26:11 2002 Error registering class.
Sun Feb 24 02:26:11 2002 Error during Initialization.
    
HOW CAN THIS BE? The line exampleSprite = new Sprite; is found AFTER the window class registration! Through what occult powers has it come to pass that the existance of this line causes the code to fail BEFORE THE LINE IS EVEN ENCOUNTERED? Has this error mysteriously traversed the temporal continuum for the sole purpose of causing my program to fail? If anyone knows how this is happening, please, let me know. Alternately, if you agree that this is really weird, let me know that too The compiler I'm using is an older Metrowerks one. (Edited to switch the code tags to source tags) Edited by - Zorodius on February 24, 2002 8:29:13 AM

Share this post


Link to post
Share on other sites
Advertisement
Further testing would seem to reveal that the only way to make this functional is to comment out the constructor for the Sprite class. Even if there is no code whatsoever in the sprite class constructor, it causes my program to fail at the window class registration phase. However, if I comment out the constructor entirely, it works just fine (although the destructor must be modified such that it is not releasing an unallocated object, but the program itself proceeds precisely as would be expected.)

I changed "imageSurface->Release();" to "if(imageSurface != NULL) imageSurface->Release();", because this was obviously wrong, but it didn't affect anything.

I also thought the problem might be related to my choice of names - maybe there was another Sprite type already defined, and it was creating problems somehow. I tried adding on some random letters, changing "Sprite" to "NZXSprite", and that also had no effect.

Why would the existance of a constructor in a totally seperate class cause this program to fail at the WNDCLASS registration? Particularly when that constructor has not been invoked and contains no code ? Maybe it's merely symptomatic of another problem, but it's extremely clear that, for whatever reason, having the constructor in existance causes the call to RegisterClass() to fail.

Demonic possession is sounding more and more likely.

Edited by - Zorodius on February 24, 2002 10:06:39 AM

Share this post


Link to post
Share on other sites
well, i haven''t had a whole lot of practice with directX, but one thing caught my eye. in your InitializeAll function, you set primaryWindowHandle = NULL; is primary a global? i assumed so due to no local declaration. that would probably cause other directX functions to fail if it didn''t have a handle. just my 2 cents.

cyn

Share this post


Link to post
Share on other sites
In the error log you give, there isn''t a logging message from the constructor, nor your "Allocating sprite." message. Did you edit those out, or are they really not showing up?

I think there is something else going on here. Most likely things are getting initialized in the wrong order.

Take care,
Bill

Share this post


Link to post
Share on other sites
You''re right, it is a global, and it would create problems if it wasn''t set to something. It is correctly set, though, in the section of code I replaced with "... (more initialization stuff) ..." (for brevity''s sake).

Just in case, here is the InitializeAll function in it''s complete form:

  
bool InitializeAll(HINSTANCE hinst, int showStyle)
{
HWND hWnd;
WNDCLASS wc;

srand((unsigned)time(NULL));
primaryWindowHandle = NULL;

// *** Window Initialization ***

InitDefaultWindowClass(&wc, hinst);

Rec("Registering class.");
if(!RegisterClass(&wc))
{
Rec("Error registering class.");
return false;
}

Rec("Creating window.");
hWnd = CreateWindow(VERSION, VERSION, WS_POPUP, 0, 0, SCREENWIDTH, SCREENHEIGHT, NULL, NULL, hinst, NULL);
primaryWindowHandle = hWnd;

ShowWindow(hWnd, showStyle);
UpdateWindow(hWnd);

// *** DirectDraw Initialization ***

DirectDrawCreate(NULL, &lpDD, NULL);
lpDD->SetCooperativeLevel(hWnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
lpDD->SetDisplayMode(SCREENWIDTH, SCREENHEIGHT, SCREENDEPTH);

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

Rec("Creating primary surface.");
if(lpDD->CreateSurface(&DDsd, &primarySurface, NULL) != DD_OK)
return false;

DDSCaps.dwCaps = DDSCAPS_BACKBUFFER;

Rec("Getting attached surface.");
primarySurface->GetAttachedSurface(&DDSCaps, &backSurface);

Rec("Allocating sprite.");
exampleSprite = new Sprite;
Rec("Sprite allocated.");

Rec("Initialization Successfully Completed.");
return true;
}

Share this post


Link to post
Share on other sites
quote:
In the error log you give, there isn't a logging message from the constructor, nor your "Allocating sprite." message. Did you edit those out, or are they really not showing up?


You are completely right, and that is precisely why this problem is so confusing to me. They really aren't showing up. Somehow, the existance of the constructor creates problems even though the constructor is never invoked .

Edited by - Zorodius on February 24, 2002 11:22:19 AM

Share this post


Link to post
Share on other sites
quote:
Don''t you have to fill in some fields in the WindowClass structure?


Sure do, which is why the InitDefaultWindowClass(&wc, hinst); call is made. That was also left out for brevity''s sake.

Just in case, here it is:
  
void InitDefaultWindowClass(WNDCLASS * wc, HINSTANCE hinst)
{
wc->lpszClassName = VERSION;
wc->hInstance = hinst;
wc->lpfnWndProc = ProcessMessage;
wc->hCursor = LoadCursor(NULL, IDC_ARROW);
wc->hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc->hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wc->style = 0;
wc->cbClsExtra = 0;
wc->cbWndExtra = 0;
}

Share this post


Link to post
Share on other sites
You are setting primaryWindowHandle = hWnd and then continueing to use hWnd, which would make primaryWindowHandle out of date.

Assuming you are using primaryWindowHandle for something, you need to use it for all the initialization functions, not hWnd (including ShowWindow and UpdateWindow).

Edit.. though your code does not seem to even get that far. Hmm.

Edited by - BenHanson on February 24, 2002 11:57:32 AM

Share this post


Link to post
Share on other sites
Hate to use up my 100th post on this (look at the date I registered and you may understand - I wonder if anyone else who has been around this long as fewer posts than I)...

Anyway, if RegisterClass fails, make a call to GetLastError() and see what it''s returning. You can use ErrLook to find out what the value is. This should tell you why RegisterClass is failing, or at least point you in the right direction.



Mark Fassett
Laughing Dragon Entertainment
http://www.laughing-dragon.com

Share this post


Link to post
Share on other sites

  • 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!