I'm very confused with this particular error, and was hoping that someone here would be kind enough to tell me why this error is occuring...
I have a simple Input class:
Code:
#ifndef _INPUT_H_
#define _INPUT_H_
#include <dinput.h>
class InputDevice
{
public:
~InputDevice(void);
LPDIRECTINPUT8 Interface;
LPDIRECTINPUTDEVICE8 Device;
protected:
InputDevice(void);
private:
};
InputDevice::InputDevice(void)
{
}
InputDevice::~InputDevice(void)
{
}
#endif
Then I have a simple KeyboardDevice Class and Keys class:
Code:
#ifndef _KEYBOARD_H_
#define _KEYBOARD_H_
#include "inputdevice.h"
#include <iostream>
using namespace std;
class KeyboardDevice : public InputDevice
{
public:
KeyboardDevice(void);
~KeyboardDevice(void);
void Update(void);
bool Pressed(const unsigned short Key);
void Print(void);
protected:
unsigned short state[256], pState[256];
};
struct Keys
{
static const unsigned short
Num1 = 0x01,
Num3 = 0x02,
Num5 = 0x03,
Num7 = 0x04,
Num9 = 0x05,
Dash = 0x06,
BackSpace = 0x07,
Q = 0x08,
E = 0x09,
T = 0x0A,
U = 0x0B,
O = 0x0C,
BracketLeft = 0x0D,
Return = 0x0E,
A = 0x0F,
D = 0x10,
G = 0x11,
J = 0x12,
L = 0x13,
Comma = 0x14,
ShiftLeft = 0x15,
Z = 0x16,
C = 0x17,
B = 0x18,
M = 0x19,
Period = 0x1A,
ShiftRight = 0x1B,
AltLeft = 0x1C,
F2 = 0x1E,
F4 = 0x1F,
F6 = 0x20,
F8 = 0x21,
NumPad8 = 0x24,
NumPadMinus = 0x25,
NumPad5 = 0x26,
NumPadPlus = 0x27,
NumPad2 = 0x28,
NumPad0 = 0x29,
CapsLock = 29,
Equals = 92,
Up = 100,
Down = 104;
};
#include "keyboarddevice.h"
KeyboardDevice::KeyboardDevice(void)
{
}
KeyboardDevice::~KeyboardDevice(void)
{
}
void KeyboardDevice::Update(void)
{
for(int i = 0; i < 256; i++) pState[i] = state[i];
Device->GetDeviceState(256, (LPVOID)state);
}
bool KeyboardDevice::Pressed(const unsigned short Key)
{
//if(state[DIK_ESCAPE] & 0x80) return true;
//else return false;
return (state[Key] & 0x806);// && !pState[Key & 0x80];
}
void KeyboardDevice::Print(void)
{
for(int i = 0; i < 256; i++)
{
if((state[i] & 0x80) != 0)
cout << i << "\n";
} cout << "0x00\n";
}
#endif
...and I run it in this program:
Code:
// include the necessary header files
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <dinput.h>
#include "graphicdevice.h"
#include "keyboarddevice.h"
#include <iostream>
// define the screen resolution and keyboard macros
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
// #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
// #define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
using namespace std;
// include the DirectX Library files
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "dxguid.lib")
GraphicDevice Graphics;
KeyboardDevice Keyboard;
D3DCOLOR color = D3DCOLOR_XRGB(0, 0, 0);
// function prototypes
void initD3D(HWND hWnd);
void render_frame(void);
void cleanD3D(void);
void init_graphics(void);
void init_light(void);
void initDInput(HINSTANCE hInstance, HWND hWnd); // sets up and initializes DirectInput
void detect_input(void); // gets the current input state
void cleanDInput(void); // closes DirectInput and releases memory
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hWnd;
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = "WindowClass";
wc.lpfnWndProc = WindowProc;
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL, "WindowClass", "Our DirectInput Program",
WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
// set up and initialize DirectX
initD3D(hWnd);
initDInput(hInstance, hWnd); // initialize DirectInput
MSG msg;
while(TRUE)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(msg.message == WM_QUIT)
break;
detect_input(); // update the input data before rendering
render_frame();
}
// clean up DirectX and COM
cleanD3D();
cleanDInput(); // release DirectInput
return msg.wParam;
}
// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
Graphics.Interface = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
// create a device class using this information and the info from the d3dpp stuct
Graphics.Interface->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&Graphics.Device);
}
// this is the function used to render a single frame
void render_frame(void)
{
Graphics.GetService()->GetService()->Device->Clear(0, NULL, D3DCLEAR_TARGET, color, 1.0f, 0);
Keyboard.Print();
Graphics.GetService()->GetService()->Device->EndScene();
Graphics.GetService()->GetService()->Device->Present(NULL, NULL, NULL, NULL);
}
// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
Graphics.Device->Release();
Graphics.Interface->Release();
}
// this is the function that puts the 3D models into video RAM
void init_graphics(void)
{
}
void init_light(void)
{
}
// this is the function that initializes DirectInput
void initDInput(HINSTANCE hInstance, HWND hWnd)
{
// create the DirectInput interface
DirectInput8Create(hInstance, // the handle to the application
DIRECTINPUT_VERSION, // the compatible version
IID_IDirectInput8, // the DirectInput interface version
(void**)&Keyboard.Interface, // the pointer to the interface
NULL); // COM stuff, so we'll set it to NULL
// create the keyboard device
Keyboard.Interface->CreateDevice(GUID_SysKeyboard, // the default keyboard ID being used
&Keyboard.Device, // the pointer to the device interface
NULL); // COM stuff, so we'll set it to NULL
Keyboard.Device->SetDataFormat(&c_dfDIKeyboard);
Keyboard.Device->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
}
void detect_input(void)
{
Keyboard.Device->Acquire();
Keyboard.Update();
}
void cleanDInput(void)
{
Keyboard.Device->Unacquire(); // make sure the keyboard is unacquired
Keyboard.Interface->Release(); // close DirectInput before exiting
}
Now, the issue is:
- I can ONLY check a limited number of keys. For some reason, the Direct Input defined preprocessor directives don't match up with the keys that are being pressed.
For example:
0x01 is SUPPOSED to be the escape key; INSTEAD it is read as the Num1 key!
0x02 is SUPPOSED to be the Num1 key; INSTEAD it is read as the Num 3 key!
Does anyone here have any idea why this would occur?! This is SERIOUSLY confusing me!