//--------------------------------------------------------------------------------------- // // Simple Windows DirectInput Example Code // // Jim Shaw 15/3/2004 // //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- // Always include windows.h for windows programs //--------------------------------------------------------------------------------------- #include #define DIRECTINPUT_VERSION 0x800 #include #include //--------------------------------------------------------------------------------------- // Window dimensions //--------------------------------------------------------------------------------------- #define SCREEN_X 640 #define SCREEN_Y 480 //--------------------------------------------------------------------------------------- // Variable to hold the address of the Windows window //--------------------------------------------------------------------------------------- HWND game_window; //--------------------------------------------------------------------------------------- // Name of our window class. every class has a name. every window is one of a class. // this can be pretty much anything //--------------------------------------------------------------------------------------- char game_class[]="DICPPWindow"; static int quit = 0; //--------------------------------------------------------------------------------------- // Function prototypes //--------------------------------------------------------------------------------------- int init_dinput(HINSTANCE); void shutdown_dinput(void); void show_dinput_status(HDC hdc); //--------------------------------------------------------------------------------------- // DirectInput Variables //--------------------------------------------------------------------------------------- IDirectInput8 *dinput; IDirectInputDevice8 *keyboard; IDirectInputDevice8 *mouse; IDirectInputDevice8 *joystick; unsigned char keymap[256]; DIMOUSESTATE2 mousedata; DIJOYSTATE2 joydata; //--------------------------------------------------------------------------------------- // Every window has a WindowProc which handles messages Windows sends to them. These // are things like key presses, mouse clicks, and thousands of other things you might // be interested in. //--------------------------------------------------------------------------------------- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { //this message gets sent to the window when you click the close box on it case WM_DESTROY: //tell Windows to close the app PostQuitMessage(0); quit = 1; break; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hwnd, &ps); show_dinput_status(ps.hdc); EndPaint(hwnd, &ps); } break; case WM_TIMER: InvalidateRect(hwnd, 0, TRUE); break; //this message gets sent when you press a key case WM_KEYDOWN: switch (wParam) { //pressed Escape key? case VK_ESCAPE: //tell Windows to close the app PostQuitMessage(0); quit = 1; break; } break; //any message you don't process gets passed to this function inside Windows. default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } //any message you do process, return 0 (unless the message documentation says otherwise) return 0; } //--------------------------------------------------------------------------------------- // WinMain is like main() in C programs, just for Windows apps. //--------------------------------------------------------------------------------------- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX clas; MSG msg; int style; RECT rect; //Here we create the Class we named above clas.cbSize = sizeof(WNDCLASSEX); clas.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; clas.lpfnWndProc = WindowProc;//<- tell it where the WindowProc is clas.cbClsExtra = 0; clas.cbWndExtra = 0; clas.hInstance = hInstance; clas.hIcon = NULL; clas.hCursor = NULL; clas.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);//<- background colour of window clas.lpszMenuName = NULL; clas.lpszClassName = game_class;//<- the class name clas.hIconSm = 0; //do it! RegisterClassEx(&clas); //style of the window - what boxes do we need (close minimised etc) style = WS_CAPTION|WS_SYSMENU|WS_MAXIMIZEBOX|WS_MINIMIZEBOX; //create the window game_window = CreateWindowEx(0, game_class, "DirectInput", style, CW_USEDEFAULT, CW_USEDEFAULT, 1,1, NULL, NULL, hInstance, 0); //adjust the window size so that a SCREEN_X x SCREEN_Y window will fit inside its frame rect.left = rect.top = 0; rect.right = SCREEN_X; rect.bottom = SCREEN_Y; AdjustWindowRectEx(&rect, style , FALSE, 0); SetWindowPos(game_window, NULL, 0,0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE|SWP_NOZORDER); //show the window on the desktop ShowWindow(game_window, nCmdShow); if (init_dinput(hInstance) == 0) { MessageBox(NULL, "A problem occurred creating DirectInput.\nCheck your DirectX version.\n" "This demo requires DirectX9.0 or better.", "DirectX Initialisation Error", MB_ICONWARNING|MB_OK); shutdown_dinput(); return 0; } // Create a timer to refresh the window SetTimer(game_window, 1, 1000/30, NULL); //message processing loop //all Windows programs have one of these. It receives the messages Windows sends to the program and //passes them to the WindowProc in the Class we registered for the window. quit = 0; do { //Are there any messages waiting? while (GetMessage(&msg, game_window, 0,0) > 0 && !quit) { //pass the message to WindowProc TranslateMessage(&msg); DispatchMessage(&msg); } } while (!quit); // Close everything down KillTimer(game_window, 1); shutdown_dinput(); return 0; } //--------------------------------------------------------------------------------------- // Callback to look at DirectInput devices to see if we're interested in them //--------------------------------------------------------------------------------------- BOOL CALLBACK dinput_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) { HRESULT err; err = dinput->CreateDevice(lpddi->guidInstance, &joystick, NULL); if (err != DI_OK) return DIENUM_STOP; err = joystick->SetDataFormat(&c_dfDIJoystick2); if (err != DI_OK) { joystick->Release(); joystick = NULL; return DIENUM_STOP; } err = joystick->SetCooperativeLevel(game_window, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND); err = joystick->Acquire(); return DIENUM_STOP; } //--------------------------------------------------------------------------------------- // Create the DirectInput interface and access mouse, keyboard and joystick //--------------------------------------------------------------------------------------- int init_dinput(HINSTANCE hInst) { HRESULT err; // Create the DirectInput interface err = DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void **)&dinput, NULL); if (err != DI_OK) return 0; // Create the Keyboard device err = dinput->CreateDevice(GUID_SysKeyboard, &keyboard, NULL); err = keyboard->SetDataFormat(&c_dfDIKeyboard); err = keyboard->SetCooperativeLevel(game_window, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND); err = keyboard->Acquire(); // Create the mouse device err = dinput->CreateDevice(GUID_SysMouse, &mouse, NULL); err = mouse->SetDataFormat(&c_dfDIMouse2); err = mouse->SetCooperativeLevel(game_window, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND); err = mouse->Acquire(); // Check for a joystick device, and create it if one exists err = dinput->EnumDevices(DI8DEVCLASS_GAMECTRL, dinput_enum_callback, 0, DIEDFL_ALLDEVICES); return 1; } //--------------------------------------------------------------------------------------- // Shutdown DirectInput //--------------------------------------------------------------------------------------- void shutdown_dinput(void) { if (joystick) { joystick->Unacquire(); joystick->Release(); } if (mouse) { mouse->Unacquire(); mouse->Release(); } if (keyboard) { keyboard->Unacquire(); keyboard->Release(); } if (dinput) dinput->Release(); } //--------------------------------------------------------------------------------------- // Read data back from the controllers //--------------------------------------------------------------------------------------- void read_dinput_status(void) { HRESULT err; // Read the keyboard err = keyboard->Poll(); err = keyboard->GetDeviceState(256, keymap); // Read the mouse err = mouse->Poll(); err = mouse->GetDeviceState(sizeof mousedata, &mousedata); // Read the joystick if (joystick) { err = joystick->Poll(); err = joystick->GetDeviceState(sizeof joydata, &joydata); } } //--------------------------------------------------------------------------------------- // Display current device inputs //--------------------------------------------------------------------------------------- void show_dinput_status(HDC hdc) { int x, y; char text[256]; read_dinput_status(); // Keymap status TextOut(hdc, 0,0, "Keyboard", 8); for (y = 0; y < 16; y++) { for (x = 0; x < 16; x++) { if (keymap[x+16*y]) TextOut(hdc, x*10, (y+1)*16, "1", 1); else TextOut(hdc, x*10, (y+1)*16, "0", 1); } } // Mouse status TextOut(hdc, 260,0, "Mouse", 5); sprintf(text, "XYZ %d,%d,%d", mousedata.lX, mousedata.lY, mousedata.lZ); TextOut(hdc, 260, 16, text, strlen(text)); for (x = 0; x < 8; x++) { if (mousedata.rgbButtons[x]) TextOut(hdc, 260+x*10,32, "1", 1); else TextOut(hdc, 260+x*10,32, "0", 1); } //Joystick status TextOut(hdc, 400, 0, "Joystick", 8); if (joystick) { sprintf(text, "XYZ %d,%d,%d", joydata.lX, joydata.lY, joydata.lZ); TextOut(hdc, 400, 16, text, strlen(text)); } else { TextOut(hdc, 400, 16, "Unattached", 10); } }