ich arbeite gerade das Buch "Advanced 3D Game Programming with DirectX 10.0" von Peter Walsh durch und habe mir zum besseren Verständnis ein DX10 Testprojekt erstellt,
in dem ich die Dinge ausprogrobiere und ein wenig erweitere die in dem Buch stehen. Jetzt bin ich Kapitel mit Direct Input angekommen und habe die Input Klasse für die Tastatur
in das Projekt integriert. Sound hatte ich bereits im Vorfeld gemacht und das läuft auch einwandfrei. Nur die Tastatureingabe ist ein wenig träge, so muss ich eine Taste nun mindestens
eine Sekunde gedrückt halten bis die Routine das merkt. Die Input-Abfrage wird über den Main-Loop angestossen:
Code: Alles auswählen
while (!stateManager->IsExitApplicationSet())
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
inputManager->UpdateDevices();
window.Clear();
siTriRenderer.Render();
window.Present();
}
Jetzt wäre meine Idee, die Tastaturabfrage innerhalb des Input-Managers über einen eigenen Thread laufen zu lassen, ähnlich wie die Sound-Ausgabe.
Nur fürchte ich, das es dann zu Problemen kommt da die Tastaturabfrage die Meldung über gedrückte Tasten direkt an die entsprechenden Klassen
(in meinem Testprojekt die Application-Class) weitergibt.
Hier der Code für die Tastaturabfrage:
Code: Alles auswählen
#include "Keyboard.h"
#include <boost/foreach.hpp>
// Initialize static variables
const UINT Keyboard::ms_keyArraySize = (256 * sizeof(BYTE));
Keyboard::Keyboard(HWND hwnd, IUnknownHolder<IDirectInput8>& directInput)
: m_keyState(new BYTE[256])
{
// Create direct input 8 object
////////////////////////////////////
if (FAILED(directInput->CreateDevice(GUID_SysKeyboard, &m_directInputDevice, NULL)))
throw Exception("Unable to create direct input device for keyboard");
// Set the keyboard data format
////////////////////////////////////
if (FAILED(m_directInputDevice->SetDataFormat(&c_dfDIKeyboard)))
{
SafeRelease(m_directInputDevice);
throw Exception("Unable to set data format for keyboard input device");
}
// Set the cooperative level
////////////////////////////////////
if (FAILED(m_directInputDevice->SetCooperativeLevel(hwnd, (DISCL_FOREGROUND | DISCL_NONEXCLUSIVE))))
throw Exception("Unable to set cooperative level for keyboard input device");
// Initialize the keystate array
ZeroMemory(m_keyState.get(), ms_keyArraySize);
}
Keyboard::~Keyboard()
{
if (m_directInputDevice)
{
m_directInputDevice->Unacquire();
SafeRelease(m_directInputDevice);
}
}
bool Keyboard::Poll(unsigned int key) const
{
return (m_keyState[key] & 0x80) ? true : false;
}
bool Keyboard::Update()
{
BYTE keyState[256];
ZeroMemory(&keyState, sizeof(keyState));
for (unsigned int i = 0; i < 1; i++)
{
if (FAILED(m_directInputDevice->Poll())
|| FAILED(m_directInputDevice->GetDeviceState(sizeof(keyState), &keyState)))
{
if (i > 0 || FAILED(m_directInputDevice->Acquire()))
return false;
else
continue;
}
}
if (m_receivers.size() > 0)
{
for (unsigned int i = 0; i < 256; i++)
{
if (m_keyState.get()[i] != keyState[i])
{
// Something happened to this key since last check
if (!(keyState[i] & 0x80))
BOOST_FOREACH(IKeyboardReceiver* receiver, m_receivers)
{
receiver->KeyUp(i);
}
else
{
// We do nothing cause the key was just pressed and it'll get a
// key down signal next from us; otherwise the receiver would be
// triggered twice.
}
}
// copy the key state over
m_keyState[i] = keyState[i];
if (Poll(i))
{
// Key was pressed
BOOST_FOREACH(IKeyboardReceiver* receiver, m_receivers)
{
receiver->KeyDown(i);
}
}
}
}
else
{
// copy the new states over
memcpy(m_keyState.get(), keyState, 256);
}
return true;
}
Danke im Voraus.