DirectInput problems

Started by
4 comments, last by sakky 21 years, 11 months ago
I''m having problems getting the DirectInput to send a WM_QUIT message when the ESCAPE key has been pressed. When I push the ESCAPE key nothing happens, but when I press the ALT key then the application exits. Why is this? Whats wrong? Here is my source.
  
#include "stdafx.h"

#define WIDTH	200
#define HEIGHT  200

	// Windows Globals

	HWND                 hwnd;
	HDC				     hDC;
	LPSTR			     szClassName = "DXapp";
	
	// DirectDraw Globals

	HRESULT			     DDrval;
	LPDIRECTDRAW7	     lpDD;
	LPDIRECTDRAWSURFACE7 lpDDSprimary;
	LPDIRECTDRAWSURFACE7 lpDDSback;
	LPDIRECTDRAWSURFACE7 lpDDSoffscreen;
	DDSURFACEDESC2		 ddsd;
	DDBLTFX				 ddbltfx;
	DDBLTFX				 clear;
	DDCOLORKEY			 DDColorKey = {0};
	COLORREF		     Transparent = RGB(0,0,0);
	
	// DirectInput Globals

	HRESULT				 DIrval;
	LPDIRECTINPUT7       lpDI;
	LPDIRECTINPUTDEVICE7 lpDIDkeyboard;
	UCHAR	  		     Keystate[256];
	UCHAR				 vKey;

	// DirectDraw Prototypes

	int  DD_Init(HWND hwnd,int Width,int Height);
	void DD_Clear();
	void DD_Kill();

	// DirectInput Prototypes

	int  DI_Init(HWND hwnd,HINSTANCE hInst);
	int  DI_Check_Keyboard();
	void DI_Kill();

	HRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);

int APIENTRY WinMain(HINSTANCE hInst,
                     HINSTANCE hPrevInst,
                     LPSTR     nCmdLine,
                     int       nCmdShow)
{
 	WNDCLASS wc;
	MSG msg;

	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
	wc.hCursor = LoadCursor(NULL,IDC_ARROW);
	wc.hIcon = LoadIcon(NULL,IDI_WINLOGO);
	wc.hInstance = hInst;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = szClassName;
	wc.lpszMenuName = NULL;
	wc.style = CS_OWNDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

	if(!RegisterClass(&wc)) return 0;

	hwnd = CreateWindow(szClassName,
		        NULL,
				WS_POPUP | WS_VISIBLE,
				0,0,
				FULL_X,
				FULL_Y,                          
				NULL,
				NULL,
				hInst,
				NULL);

	// Error check DD_Init()

	DDrval = DD_Init(hwnd,WIDTH,HEIGHT);
	if(FAILED(DDrval)) 
	{
		MessageBox(NULL,"Failed to Initialize DirectDraw","Error!",MB_OK);
		return false;
	}

	// Error check DI_Init()

	DIrval = DI_Init(hwnd,hInst);
	if(FAILED(DIrval))
	{
		MessageBox(NULL,"Failed to Initialize DirectInput","Error!",MB_OK);
		return false;
	}

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

			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			// Clear Backbuffer

			DD_Clear();

			lpDDSprimary-> Flip(NULL,0);

			// Check KeyBoard State

			DIrval = DI_Check_Keyboard();
			if(FAILED(DIrval))
			{
				MessageBox(NULL,"Error with DirectInput Device","Error!",MB_OK);
				return false;
			}

		}
	}

	// Destroy and Release all DirectX 

	// objects and Interfaces

	DD_Kill();
	DI_Kill();

	return msg.wParam;
}

HRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	switch(msg)
	{
		 case WM_DESTROY:
			  PostQuitMessage(0);
			  break;
	}

	return DefWindowProc(hwnd,msg,wParam,lParam);
}

// DirectDraw Function definitions

int DD_Init(HWND hwnd,int Width,int Height)
{
	DDrval = DirectDrawCreateEx(0,(void **)&lpDD,IID_IDirectDraw7,0);
	if(FAILED(DDrval))
	{
		MessageBox(NULL,"Filed to Create DirectDraw Object","Error!",MB_OK);
		return DDrval;
	}

	DDrval = lpDD->SetCooperativeLevel(hwnd,DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
	if(FAILED(DDrval))
	{
		MessageBox(NULL,"Couldn''t set Cooperative Level","Error!",MB_OK);
		return DDrval;
	}

	DDrval = lpDD->SetDisplayMode(800,600,16,0,0);
	if(FAILED(DDrval))
	{
		MessageBox(NULL,"Failed to set DisplayMode","Error!",MB_OK);
		return DDrval;
	}

	// Set PrimarySurface description

	memset(&ddsd,0,sizeof(DDSURFACEDESC));
	ddsd.dwSize = sizeof(ddsd); 
	ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; 
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | 
    DDSCAPS_FLIP | DDSCAPS_COMPLEX; 
 
	ddsd.dwBackBufferCount = 1;

	DDrval = lpDD-> CreateSurface(&ddsd,&lpDDSprimary,0);
	if(FAILED(DDrval))
	{
		MessageBox(NULL,"Failed to Create Primary Surface","Error!",MB_OK);
		return DDrval;
	}

	// Set BackBuffer Description

	ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; 
	DDrval = lpDDSprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpDDSback); 

	// Set Off-Screen Surface description

	memset(&ddsd,0,sizeof(DDSURFACEDESC));
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
	ddsd.dwWidth = Width;
	ddsd.dwHeight = Height;

	DDrval = lpDD->CreateSurface(&ddsd,&lpDDSoffscreen,0);
	if(FAILED(DDrval))
	{
		MessageBox(NULL,"Failed to create OffScreen-Surface","Error!",MB_OK);
		return DDrval;
	}

	// Set Transparent

	DDColorKey.dwColorSpaceHighValue = (DWORD) Transparent;
	DDColorKey.dwColorSpaceLowValue  = (DWORD) Transparent;

	memset(&ddbltfx,0,sizeof(ddbltfx));
	ddbltfx.dwSize = sizeof(ddbltfx);
	ddbltfx.dwDDFX = DDBLTFX_NOTEARING;
	ddbltfx.ddckSrcColorkey = DDColorKey;

	// DDBLTFX struct used to clear screen

	memset(&clear,0,sizeof(DDBLTFX));
	clear.dwSize = sizeof(clear);
	clear.dwFillColor = 0;

	return DDrval;
}

void DD_Clear()
{
	lpDDSback->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&clear);
}

void DD_Kill()
{
	if(lpDDSoffscreen != NULL)
	{
		lpDDSoffscreen-> Release();
		lpDDSoffscreen = NULL;
	}

	if(lpDDSback != NULL)
	{
		lpDDSback-> Release();
		lpDDSback = NULL;
	}

	if(lpDDSprimary != NULL)
	{
		lpDDSprimary-> Release();
		lpDDSprimary = NULL;
	}

	if(lpDD != NULL)
	{
		lpDD-> Release();
		lpDD = NULL;
	}
}

int DI_Init(HWND hwnd,HINSTANCE hInst)
{
	DIrval = DirectInputCreateEx(hInst,DIRECTINPUT_VERSION,IID_IDirectInput7,(void**)&lpDI,0); 
	if(FAILED(DIrval))
	{
		MessageBox(NULL,"Failed to create DirectInput Object","Error!",MB_OK);
		return DIrval;
	}

	DIrval = lpDI->CreateDeviceEx(GUID_SysKeyboard,IID_IDirectInputDevice7,(void**)&lpDIDkeyboard,0);       
	if(FAILED(DIrval))
	{
		MessageBox(NULL,"Failed to Create DirectInput Device","Error!",MB_OK);
		return DIrval;
	}

	DIrval = lpDIDkeyboard->SetDataFormat(&c_dfDIKeyboard);
	if(FAILED(DIrval))
	{
		MessageBox(NULL,"Failed to set Keyboard Data format","Error!",MB_OK);
		return DIrval;
	}

	DIrval = lpDIDkeyboard-> SetCooperativeLevel(hwnd,DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
	if(FAILED(DIrval))
	{
		MessageBox(NULL,"Failed to set Keyboard CooperativeLevel","Error!",MB_OK);
		return DIrval;
	}

	if(lpDIDkeyboard) lpDIDkeyboard-> Acquire();

	return DIrval;
}

int DI_Check_Keyboard()
{
	DIrval = lpDIDkeyboard->GetDeviceState(256,Keystate);
	if(FAILED(DIrval))
	{
		MessageBox(NULL,"Failed to GetDeviceState on Keyboard","Error!",MB_OK);
		return DIrval;
	}

	switch(Keystate[vKey])
	{
	     case DIK_ESCAPE:
			  SendMessage(hwnd,WM_QUIT,0,NULL);
			  break;
	}

	return DIrval;
}

void DI_Kill()
{
	if(lpDIDkeyboard != NULL)
	{
		lpDIDkeyboard-> Unacquire();
		lpDIDkeyboard-> Release();
		lpDIDkeyboard = NULL;
	}

	if(lpDI != NULL)
	{
		lpDI-> Release();
		lpDI = NULL;
	}
}
  
Any help would be nice thanx in advance
Take back the internet with the most awsome browser around, FireFox
Advertisement
Well, I just glanced over your code and I can't see where you initialise vKey. Then in DI_Check_Keyboard() you have switch(keystate[vKey]). I think you need to use if(keystate[DIK_ESCAPE] & 0x80) instead, but don't quote me on that .

EDIT: Got the test wrong...

[edited by - Krunk on May 3, 2002 7:02:14 PM]
Yeah, I changed the way I was checking for KEYs. I did have if like this



    if(Keystate[DIK_ESCAPE] 0x80){    SendMessage(hwnd,WM_QUIT,0,NULL);}    




But that didn't work either. That was the way LaMothe showed me in Windows Game Programming for Dummies. How am I supose to initialize the vKey any ways? Do I have to do something special to the UCHAR Keystate[256]? Its just simply not working right or somthing. Like DX isn't wanting to be bothered so it sitts there doing nothing.



What I don't egt is why the ALT key exits the application and not the ESCAPE key. How the hell is it doing that? Is there some thing wrong? Is there a possiblity that the MessageBoxes I'm using arn't showing up because DirectDraw is in the way? Then after it got in the way it stopped working right, or is omething wrong with my main loop, or DI implementation? Thanks for your advise and help tho; Does any one else have any ideas of whats going on here?




[edited by - Sakky on May 3, 2002 7:49:35 PM]
Take back the internet with the most awsome browser around, FireFox
quote:Original post by sakky
Yeah, I changed the way I was checking for KEYs. I did have if like this


You've missed out the operator in the if(...), but I assume you were using & (that's what LaMothe uses in TOTWGPG). If you used == that would cause problems though.

quote:How am I supose to initialize the vKey any ways?


At the moment, when you do keyState[vKey], vKey is uninitialised. That means it will contain whatever garbage was at its location before the program started (or possibly 0 in debug mode). If you don't want the program to do random things when you run it, you'll want to set its value before you use it ( vKey = whatever; )

quote:What I don't egt is why the ALT key exits the application and not the ESCAPE key. How the hell is it doing that? Is there some thing wrong? Is there a possiblity that the MessageBoxes I'm using arn't showing up because DirectDraw is in the way? Then after it got in the way it stopped working right, or is omething wrong with my main loop, or DI implementation? Thanks for your advise and help tho; Does any one else have any ideas of whats going on here?


I'm not sure what's going on. I'd like to try your code out, but for some reason the source box wont play fair. When I copy the code from it and paste it into a text editor all the linefeeds vanish and I get all the code on one line. I don't really fancy picking through it putting in returns . I wonder if pre tags work any better...

EDIT <pre> tags didn't help any .

[edited by - Krunk on May 4, 2002 8:32:59 AM]
Found it! The cause of the bug is this line in the message pump:
if(msg.wParam == WM_QUIT) break; 
Which should say:
if(msg.message == WM_QUIT) break; 
The WM_QUIT message was sent but not detected, because the wParam of a WM_QUIT is the parameter to PostQuitMessage (0 in this case). When you press ALT, however, one of the resulting messages has its wParam set to 0x12, which just happens to be the value WM_QUIT is defined as. Fun eh?

On a minor point of style, you might want to change your message pump a bit. At the moment it processes one message, then renders a frame. If a lot of messages got sent together (and the framerate was low enough) messages would start to back up in the queue. That might make windows think your program was "Not Responding". I use PeekMessage(,,,,PM_NOREMOVE) to see if any messages are there, then do a loop using PeekMessage(,,,,PM_REMOVE) to despatch them all. Then I draw a new frame.
So thats the deal with the ALT key thang. My friend told me somthing about that being posted on GameDev a lot of times. I should of looked in the old forum articles, he told me. So I was looking and can''t find were to go.

If(problem == What_you_said))
{
cout <<"Dow!, Dow! ,Dow!, Dow!";
}

I''v notive that VC acts a little funny tho. I''m use to MingW but I tried to use the source I made with MingW work in VC. Not even a chance. I get a internal error when I try to compile the code. The error always starts with were my globals are. But I can make the same code in VC and it will compiler fine. I wonder why its so picky? I just kept deleting my source because of this ALT problem with VC and the message CALLBACK. Actually its not VC''s fault but its lack of software knollage. I don''t know hardly any thang about VC. Just that its got BOMB-ASS IDE and its suports every thang MS. So no worries about COM(MingW DX package!!!).
Take back the internet with the most awsome browser around, FireFox

This topic is closed to new replies.

Advertisement