Jump to content
  • Advertisement
Sign in to follow this  
Dasil

Fullscreen Crash

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

Hi again, I was working on a game project, and I was developing it to be windowed, but then I decided to switch it to fullscreen. I made what I thought were the necessary changes, but when I run it, the program just crashes. I've looked through the code several times but I can't seem to find the problem. Can anyone help me? Winmain.cpp
#include "Main.h"

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

Application app;
HWND hWnd;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	WNDCLASSEX wc;
	MSG msg;

	ZeroMemory(&wc, sizeof(WNDCLASSEX));

	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WindowProc;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.lpszClassName = L"Window Class";

	RegisterClassEx(&wc);

	hWnd = CreateWindowEx(NULL,
						   L"Window Class",
						   L"Game",
						   WS_EX_TOPMOST | WS_POPUP,
						   0,
						   0,
						   SCREEN_WIDTH,
						   SCREEN_HEIGHT,
						   NULL,
						   NULL,
						   hInstance,
						   NULL);

	ShowWindow(hWnd, nShowCmd);

	app.initD3D(hWnd);

	while (true)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
				break;

			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		app.handleInput();
		app.render();
	}

	return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			return 0;
		}
	case WM_RBUTTONDOWN:
		{
			app.setRightClick(true);
			return 0;
		}
	case WM_RBUTTONUP:
		{
			app.setRightClick(false);
			return 0;
		}
	case WM_LBUTTONDOWN:
		{
			app.setLeftClick(true);
			return 0;
		}
	case WM_LBUTTONUP:
		{
			app.setLeftClick(false);
			return 0;
		}
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}

Application.cpp
#include "Main.h"

Application::Application()
{
	mHWnd = NULL;
	mD3D = NULL;
	mDevice = NULL;
	mLeftClick = false;
	mRightClick = false;
}

Application::~Application()
{
	cleanD3D();
}

void Application::initD3D(HWND hWnd)
{
	HRESULT hResult;

	mD3D = Direct3DCreate9(D3D_SDK_VERSION);

	ZeroMemory(&mD3Dpp, sizeof(mD3Dpp));

	mD3Dpp.Windowed = false;
	mD3Dpp.hDeviceWindow = hWnd;
	mD3Dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	mD3Dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
	mD3Dpp.BackBufferHeight = SCREEN_HEIGHT;
	mD3Dpp.BackBufferWidth = SCREEN_WIDTH;

	hResult = mD3D->CreateDevice(D3DADAPTER_DEFAULT,
					   D3DDEVTYPE_HAL,
					   hWnd,
					   D3DCREATE_SOFTWARE_VERTEXPROCESSING,
					   &mD3Dpp,
					   &mDevice);

	if (hResult != D3D_OK)
	{
		PostQuitMessage(0);
		MessageBox(NULL, L"Error creating device", L"Error", MB_OK);
	}

	hResult = D3DXCreateSprite(mDevice, &mSprite);

	if (hResult != D3D_OK)
	{
		PostQuitMessage(0);
		MessageBox(NULL, L"Error creating sprite interface", L"Error", MB_OK);
	}

	createFont();
	createObjects();
}

void Application::render()
{
	mDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

	mDevice->BeginScene();

	mSprite->Begin(D3DXSPRITE_ALPHABLEND);

 	handleCollisions();
	handleObjects();
	drawObjects();

	mSprite->End();

	mDevice->EndScene();

	mDevice->Present(NULL, NULL, NULL, NULL);
}

void Application::cleanD3D()
{
	mFont->Release();
	mSprite->Release();
	mDevice->Release();
	mD3D->Release();
}

void Application::handleObjects()
{
}

void Application::drawObjects()
{
}

void Application::handleInput()
{
	static UCHAR keyBuffer[256];

	if (!GetKeyboardState(keyBuffer))
	{
		MessageBox(NULL, L"Error setting up keyboard", L"Error", MB_OK);
		return;
	}

	if (keyBuffer[VK_UP] & 0xF0)
	{
	}
	if (keyBuffer[VK_DOWN] & 0xF0)
	{
	}
	if (keyBuffer[VK_LEFT] & 0xF0)
	{
	}
	if (keyBuffer[VK_RIGHT] & 0xF0)
	{
	}
	if (keyBuffer[VK_ESCAPE] & 0xF0)
	{
		PostQuitMessage(0);
	}
}

LPDIRECT3DDEVICE9 Application::getDevice()
{
	return mDevice;
}

LPDIRECT3D9 Application::getD3D()
{
	return mD3D;
}

HWND Application::getWindowHandle()
{
	return mHWnd;
}

D3DPRESENT_PARAMETERS Application::getPresentParameters()
{
	return mD3Dpp;
}

LPD3DXSPRITE Application::getSprite()
{
	return mSprite;
}

void Application::createObjects()
{
}

void Application::handleCollisions()
{
}

void Application::setLeftClick(bool value)
{
	mLeftClick = value;
}

void Application::setRightClick(bool value)
{
	mRightClick = value;
}

bool Application::getLeftClick()
{
	return mLeftClick;
}

bool Application::getRightClick()
{
	return mRightClick;
}

void Application::createFont()
{
	D3DXCreateFont(mDevice,
                   22,
                   0,
                   FW_BOLD,
                   1,
                   false,
                   DEFAULT_CHARSET,
                   OUT_DEFAULT_PRECIS,
                   DEFAULT_QUALITY,
                   DEFAULT_PITCH | FF_DONTCARE,
                   L"Arial",
                   &mFont);

}

LPD3DXFONT Application::getFont()
{
	return mFont;
}

Main.h
#ifndef MAIN_H
#define MAIN_H

#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#include <d3dx9.h>
#include "Application.h"

#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")

#define SCREEN_WIDTH 1680
#define SCREEN_HEIGHT 1050

extern Application app;

#endif

Any help would be appreciated.

Share this post


Link to post
Share on other sites
Advertisement
Actually, I just tried a different resolution (1280 x 1024) and it worked perfectly. Why would it do this, my moniter is set at 1680x1050, so why wouldn't it work on this resolution, but it works on a lower one?

Share this post


Link to post
Share on other sites
Use DX Caps viewer and see if your device supports the resolution you're on, with the backbuffer format you're using.

Share this post


Link to post
Share on other sites
You're checking return values, which is good - but you're not doing it quite right.
Instead of:
if (hResult != D3D_OK)
Use:
if (FAILED(hResult))
There's 2 billion possible success codes and you're only checking one of them.

That's not related to your problem though, but it might bite you later on. The reason it's crashing is that if a function fails, you carry on and use the pointer. For example, if CreateDevice() fails, you call PostQuitMessage(), MessageBox(), but then go on to call D3DXCreateSprite instead of returning from the function. That means that you're using an invalid pointer (mDevice is null).
As for why any function would fail - what do the Debug Runtimes say? I'd also recommend reading over This article for an overview of how to use the debugger to track down these sort of bugs (Although debugging a fullscreen application is pretty hard without a multi-monitor or remote debugging setup).

Also, your message loop is wrong - you need to process all window messages before rendering, not just one. Otherwise, if render() causes a window message to be added, you'll never empty your message queue, it'll fill up and make your application laggy and eventually crash. Fixing it is just a case of changing your if(PeekMessage(...)) to while(PeekMessage(...)).

Share this post


Link to post
Share on other sites
Thanks for the replies.

So are you saying that instead of using
while(true)
{
PeekMessage(...)
}

I should use while(PeekMessage(...))

for the loop?

Or do you mean:
while (true)
{
while(PeekMessage(...))
}

Share this post


Link to post
Share on other sites
Quote:
So are you saying that instead of using
while(true)
{
PeekMessage(...)
}

I should use while(PeekMessage(...))

for the loop?

Or do you mean:
while (true)
{
while(PeekMessage(...))
}


Use

while(true)
{
while(PeekMessage(...))
{
//Message handling
...
}
//Game stuff
//Game stuff
}


My game code had the same flaw, until I saw the problem pointed out in a post here somewhere. I think there must be a tutorial out there with the incorrect message loop, as it seems to be a common thing to do. I can't remember where I got the code from now, as it was a few years ago that I started my game, but someone should find it and inform the author!

Share this post


Link to post
Share on other sites
If you have ever read any of Andre LaMothe's books he does it that way, that's where I originally learned to do it the wrong way =p

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!