Jump to content
  • Advertisement

Archived

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

PoLiSh_Peta

This is so hard

This topic is 5231 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''m trying to make a pong clone and I''m having problem after problem, and all I have is the windows stuff and Direct Input set up. Now Windows gives me an error when I run my .exe, so I don''t know what the problem is. Here''s the area of code that''s most likely the problem: Function to read input.
BOOL cInput::Read()
{
	#define KEYDOWN(name, key) (name[key] & 0x80)

	hr = Keyboard->GetDeviceState( sizeof( buffer ),( LPVOID )&buffer );

	//I''m not sure what to do here.

	BOOL ReturnValue = TRUE;
	
	if (KEYDOWN(buffer, DIK_ESCAPE))
	{
		ReturnValue = FALSE;
	}

	return ReturnValue;
}
Frame function that will call for the input updates.
BOOL cSystemStuff::Frame()
{
	BOOL ReturnValue = TRUE;
	
	if( PtrMainInput->Read() == FALSE )
	{
		ReturnValue = FALSE;
	}
		else
		{
			ReturnValue = TRUE;
		}

	return ReturnValue;

}
Main Run function.
BOOL cSystemStuff::Run()
{
	
	//create a MSG instance.

	MSG Msg;

	//Register our class

	if( !RegisterClassEx( &WindowStructure ) )
	{
		return FALSE;
	}

	//Create the actual window

	m_hWnd = CreateWindow( ClassName,
						   Caption,
						   Style,
						   XPos,
						   YPos,
						   Width,
						   Height,
						   NULL,
						   NULL,
						   m_hInst,
						   NULL );


	if( !m_hWnd )
	{
		return FALSE;
	}

	//Show and update window

	ShowWindow( m_hWnd, SW_NORMAL );
	UpdateWindow( m_hWnd );

	//Initialize COM

	CoInitialize( NULL );

	//Create out memory of the MSG to prepare for Message pump

	ZeroMemory( &Msg, sizeof( MSG ) );

	//Main loop

	while( Msg.message != WM_QUIT )
	{
		//Handle any Windows messages if need be

		if( PeekMessage( &Msg, NULL, 0, 0, PM_REMOVE ) ) 
		{
			TranslateMessage( &Msg );
			DispatchMessage( &Msg );
		} 
			else 
			{
				//Do the frame processing crap here

				
				if( Frame() == FALSE )
				{

					
					break;
				}
			}
	}

	//Shutdown window and everything else

	Shutdown();

	//Uninitialize COM

	CoUninitialize();

	//Unregister our window class

	UnregisterClass( ClassName, m_hInst );

	return TRUE;
}
Any ideas as to what''s the problem? Also, is this a good method for the main loop? I''m trying to just make the application quit when the user hits the escape key, but I can''t even make that work Maybe my design needs improvement? I really need help, I know this stuff is just about to "click" for me. Also, what about setting the framerate? Would I add a function call or something in the Run function or the Frame function? Please help! -Peter

Share this post


Link to post
Share on other sites
Advertisement
Try clearing out that input buffer every frame, before getting the device state. Use memset.

memset(&m_keyboardBuffer, 0, sizeof(m_keyboardBuffer));

Share this post


Link to post
Share on other sites
The error comes from Windows, it says there was an error and the program needs to abort. There's no linker/syntax or whatever error reported from the compiler.

Ahh, after running in debug mode, here's what I've come up with:

Unhandled exception in blah blah: 0x0000005: Access Violation
And then there's a yellow arrow pointing at this line:
hr = Keyboard->GetDeviceState( sizeof( buffer ),( LPVOID )&buffer );


Mind you, this is without memset() in there. With memset() in there before the above function call, I get the same access violation, and then it gives me an option to what I believe is the ASM code for the memset() function call and it asks me where to put it.

-Peter

[edited by - PoLiSh_Peta on February 20, 2004 8:47:05 PM]

[edited by - PoLiSh_Peta on February 20, 2004 8:48:08 PM]

Share this post


Link to post
Share on other sites
Well, I've changed around a few things, and now it's just the memset() function that's screwing me over.

All compiles and links correctly. When I execute it, windows forces me to abort it. Gives me some access violation, and then it asks me where to place teh ASM code for the memset() function. What's up with that? Need this program solved soon!


BOOL cInput::Read()
{
#define KEYDOWN(name, key) (name[key] & 0x80)

memset( &buffer, 0, sizeof( buffer ) );

hr = Keyboard->GetDeviceState( sizeof( buffer ),( LPVOID )&buffer );

//I'm not sure what to do here.


if (KEYDOWN(buffer, DIK_ESCAPE))
{
IsAppDone = TRUE;
}

return TRUE;
}




Another thing: It says DIRECTINPUT_VERSION undefined, what do I do here?

Thanks

-Peter

[edited by - PoLiSh_Peta on February 20, 2004 11:58:29 PM]

[edited by - PoLiSh_Peta on February 20, 2004 12:00:41 AM]

Share this post


Link to post
Share on other sites
What is buffer's type? And are you setting the data type with DirectInput? Look at in the SDK documentation for:

IDirectInputDevice8::GetDeviceState
IDirectInputDevice8::SetDataFormat

While I assume that you are expecting an array of 256 bytes ala c_dfDIKeyboard, its not clear that's what this is from the code.

From the DX9 SDK examples:

// Obtain an interface to the system keyboard device.

if( FAILED( hr = g_pDI->CreateDevice( GUID_SysKeyboard, &g_pKeyboard, NULL ) ) )
return hr;

// Set the data format to "keyboard format" - a predefined data format

//

// A data format specifies which controls on a device we

// are interested in, and how they should be reported.

//

// This tells DirectInput that we will be passing an array

// of 256 bytes to IDirectInputDevice::GetDeviceState.

if( FAILED( hr = g_pKeyboard->SetDataFormat( &c_dfDIKeyboard ) ) )
return hr;


The GetDeviceState() example looks like:




HRESULT hr;
TCHAR strNewText[256*5 + 1] = TEXT("");
TCHAR strElement[10];
BYTE diks[256]; // DirectInput keyboard state buffer

int i;

if( NULL == g_pKeyboard )
return S_OK;

// Get the input's device state, and put the state in dims

ZeroMemory( diks, sizeof(diks) );
hr = g_pKeyboard->GetDeviceState( sizeof(diks), diks );
if( FAILED(hr) )
{
// DirectInput may be telling us that the input stream has been

// interrupted. We aren't tracking any state between polls, so

// we don't have any special reset that needs to be done.

// We just re-acquire and try again.


// If input is lost then acquire and keep trying

hr = g_pKeyboard->Acquire();
while( hr == DIERR_INPUTLOST )
hr = g_pKeyboard->Acquire();

// Update the dialog text

if( hr == DIERR_OTHERAPPHASPRIO || hr == DIERR_NOTACQUIRED )
SetDlgItemText( hDlg, IDC_DATA, TEXT("
Unacquired") );

// hr may be DIERR_OTHERAPPHASPRIO or other errors. This

// may occur when the app is minimized or in the process of

// switching, so just try again later

return S_OK;
}



in the sdk examples.


My guess is that you, memset, and DiretInput are not on the same sheet of music with regards to what 'buffer' is. Also, you may want to "clean" your entire build and rebuild everything - sometimes stuff gets de-synchonized and creates very difficult problems to sort out.


Hope that helps.

#dth-0


[edited by - xiuhcoatl on February 20, 2004 12:23:43 AM]

[edited by - xiuhcoatl on February 20, 2004 12:25:13 AM]

Share this post


Link to post
Share on other sites
My function is not all that different from the SDK one. They just have some extra stuff for error handling which I don''t need. I changed the buffer type to BYTE, and used ZeroMemory() to clean out the buffer before getting the input, and it''s the same old crash after running the exe. What on EARTH good be wrong with this? This extremely frustrating, and it''s only DirectInput.


#ifndef Input_H_
#define Input_H_

typedef unsigned char UCHAR;

//Macro to release COM objects

#define ReleaseCOM(x) if(x) { x->Release(); x = NULL; }

//Macros for testing whether a key is up or down

#define KeyDown(data, n) ((data[n] & 0x80) ? true : false)
#define KeyUp(data, n) ((data[n] & 0x80) ? false : true)

class cInput
{
public:

cInput( HINSTANCE, HWND );
~cInput();

BOOL InitializeKeyboard();
BOOL Shutdown();

BOOL Read();

private:

HINSTANCE m_hInst;
HWND m_hWnd;

HRESULT hr;

//Direct input stuff we''ll need

LPDIRECTINPUT8 m_DIObject;
LPDIRECTINPUTDEVICE8 Keyboard;

//Buffer to hold input from the keyboard

BYTE buffer[ 256 ];

};

static cInput* PtrMainInput = NULL;

#endif



#include "Global_Header.h"

cInput::cInput( HINSTANCE hInst, HWND hWnd )
{
//Set the input class pointer to this instantiation

PtrMainInput = this;

//Set local HINSTANCE and HWND variables

m_hInst = hInst;
m_hWnd = hWnd;

//Create main Direct Input object

hr = DirectInput8Create( m_hInst,
DIRECTINPUT_VERSION,
IID_IDirectInput8,
( void** ) &m_DIObject,
NULL );

//Make a call to initialize the keyboard device.

InitializeKeyboard();

}

cInput::~cInput()
{
//Make a call to shutdown Direct Input

Shutdown();
}

BOOL cInput::InitializeKeyboard()
{
hr = m_DIObject->CreateDevice( GUID_SysKeyboard, &Keyboard, NULL );

hr = Keyboard->SetDataFormat( &c_dfDIKeyboard );

hr = Keyboard->SetCooperativeLevel( m_hWnd,
DISCL_FOREGROUND | DISCL_NONEXCLUSIVE );

if( Keyboard ) Keyboard->Acquire();

return TRUE;
}

BOOL cInput::Shutdown()
{
Keyboard->Unacquire();

ReleaseCOM( Keyboard );

ReleaseCOM( m_DIObject );

m_hWnd = NULL;

return TRUE;
}

BOOL cInput::Read()
{
#define KEYDOWN(name, key) (name[key] & 0x80)

ZeroMemory( buffer, sizeof(buffer) );

hr = Keyboard->GetDeviceState( sizeof( buffer ),( LPVOID )&buffer );

//I''m not sure what to do here.


if (KEYDOWN(buffer, DIK_ESCAPE))
{
IsAppDone = TRUE;
}

return TRUE;
}

Share this post


Link to post
Share on other sites
quote:
Original post by PoLiSh_Peta
They just have some extra stuff for error handling which I don't need.
You need to do that error checking and handling. In your InitializeKeyboard() function, you don't check to see whether the keyboard was successfully intialized or not. It returns true no matter what, even if the keyboard creation failed.

This is why you are getting an access violation when you try to call a function in keyboard, because keyboard is NULL.

If you need more help to see how to do the proper error checking and handling, look at the DInput SDK tutorials. They go through step-by-step, and you should include all the error checking they do. Otherwise, you will get access violations like that.


Dustin Franklin
Mircrosoft DirectX MVP

[edited by - circlesoft on February 21, 2004 12:13:08 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Remove the & before buffer


hr = Keyboard->GetDeviceState( sizeof( buffer ),( LPVOID )&buffer );


to


hr = Keyboard->GetDeviceState( sizeof( buffer ),( LPVOID )buffer);

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!