//////////////////////////////////////////////////////////////////////////////// // DirectInputStick.cpp // // DirectDraw... with sprites and a mouse cursor. // DirectInput... driving the sprites with the keyboard, mouse and joystick. #include #include #include #include "ddutil.h" #include "resource.h" HWND hWndMain; IDirectDraw7 *pDD; IDirectDrawSurface7 *lpPrimary, *lpBackBuffer; IDirectDrawSurface7 *lpA, *lpSprites; // Initialise DirectDraw and go to full screen mode. void InitDirectDraw() { DirectDrawCreateEx(NULL, (void **)&pDD, IID_IDirectDraw7, NULL); pDD->SetCooperativeLevel(hWndMain, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT); pDD->SetDisplayMode(640, 480, 16, 100, 0); DDSURFACEDESC2 ddsd; ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2)); ddsd.dwSize = sizeof(DDSURFACEDESC2); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 2; pDD->CreateSurface(&ddsd, &lpPrimary, NULL); ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; lpPrimary->GetAttachedSurface(&ddsd.ddsCaps, &lpBackBuffer); lpA = DDLoadBitmap(pDD, "a.bmp", 0, 0); lpSprites = DDLoadBitmap(pDD, "sprites.bmp", 0, 0); DDSetColorKey(lpSprites, RGB(255, 0, 255)); } void ExitDirectDraw() { lpSprites->Release(); lpSprites = NULL; lpA->Release(); lpA = NULL; lpPrimary->Release(); lpPrimary = NULL; lpBackBuffer = NULL; pDD->Release(); pDD = NULL; } IDirectInput7 *pDI; IDirectInputDevice7 *pKeyboard, *pMouse; IDirectInputDevice7 *pStick; BOOL CALLBACK DIDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) { LPDIDEVICEINSTANCE p = (LPDIDEVICEINSTANCE)pvRef; *p = *lpddi; if (lpddi->dwDevType & DIDEVTYPEJOYSTICK_GAMEPAD) return DIENUM_STOP; return DIENUM_CONTINUE; } // Initialise DirectInput and get the keyboard void InitDirectInput() { DirectInputCreateEx(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput7, (void **)&pDI, NULL); pDI->CreateDeviceEx(GUID_SysKeyboard, IID_IDirectInputDevice7, (void **)&pKeyboard, NULL); pKeyboard->SetDataFormat(&c_dfDIKeyboard); // Set the cooperative level pKeyboard->SetCooperativeLevel(hWndMain, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); pDI->CreateDeviceEx(GUID_SysMouse, IID_IDirectInputDevice7, (void **)&pMouse, NULL); pMouse->SetDataFormat(&c_dfDIMouse2); // Set the cooperative level pMouse->SetCooperativeLevel(hWndMain, DISCL_FOREGROUND | DISCL_EXCLUSIVE); DIDEVICEINSTANCE dev; pDI->EnumDevices(DIDEVTYPE_JOYSTICK, DIDevCallback, &dev, DIEDFL_ATTACHEDONLY); pDI->CreateDeviceEx(dev.guidInstance, IID_IDirectInputDevice7, (void **)&pStick, NULL); pStick->SetDataFormat(&c_dfDIJoystick2); // Set the cooperative level pStick->SetCooperativeLevel(hWndMain, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); DIPROPRANGE range; range.diph.dwSize = sizeof(DIPROPRANGE); range.diph.dwHeaderSize = sizeof(DIPROPHEADER); range.diph.dwHow = DIPH_BYOFFSET; range.diph.dwObj = DIJOFS_X; range.lMax = 1000; range.lMin = -1000; pStick->SetProperty(DIPROP_RANGE, &range.diph); range.diph.dwObj = DIJOFS_Y; pStick->SetProperty(DIPROP_RANGE, &range.diph); DIPROPDWORD dw; dw.dwData = DIPROPAXISMODE_ABS; dw.diph.dwSize = sizeof(DIPROPDWORD); dw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dw.diph.dwHow = DIPH_DEVICE; dw.diph.dwObj = 0; pStick->SetProperty(DIPROP_AXISMODE, &dw.diph); pKeyboard->Acquire(); pMouse->Acquire(); pStick->Acquire(); } void ExitDirectInput() { pStick->Unacquire(); pStick->Release(); pStick = NULL; pMouse->Unacquire(); pMouse->Release(); pMouse = NULL; pKeyboard->Unacquire(); pKeyboard->Release(); pKeyboard = NULL; pDI->Release(); pDI = NULL; } // Handle all messages for the main window. LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CLOSE: ExitDirectDraw(); DestroyWindow(hWnd); return 0; case WM_SETCURSOR: SetCursor(NULL); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } // Register the window class for the main window. void RegisterWindowClass() { WNDCLASSEX wcx; ZeroMemory(&wcx, sizeof(WNDCLASSEX)); wcx.cbSize = sizeof(WNDCLASSEX); wcx.lpfnWndProc = MainWindowProc; wcx.hInstance = GetModuleHandle(NULL); wcx.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MAIN)); wcx.hCursor = NULL; wcx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wcx.lpszMenuName = NULL; wcx.lpszClassName = "SampleWindowClass"; RegisterClassEx(&wcx); } // Idle-time processing function. void OnIdle(void) { if (lpPrimary == NULL) return; BYTE state[256]; pKeyboard->GetDeviceState(sizeof(state), &state); DIMOUSESTATE2 mouse; pMouse->GetDeviceState(sizeof(mouse), &mouse); DIJOYSTATE2 stick; pStick->Poll(); pStick->GetDeviceState(sizeof(stick), &stick); RECT r; r.left = r.top = 0; r.right = 640; r.bottom = 480; lpBackBuffer->BltFast(0, 0, lpA, &r, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT); static int y = 0; if (state[DIK_UP] & 0x80) y--; if (state[DIK_DOWN] & 0x80) y++; r.left = 128; r.top = 0; r.right = 192; r.bottom = 64; lpBackBuffer->BltFast(288, 208 + y, lpSprites, &r, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT); static int x = 0; x++; if (x > 100) x = -100; r.left = 0; r.right = 64; lpBackBuffer->BltFast(288 + x, 100, lpSprites, &r, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT); static int xMouse = 400, yMouse = 200; xMouse += mouse.lX / 4; yMouse += mouse.lY / 4; xMouse += stick.lX / 100; yMouse += stick.lY / 100; if (xMouse > (640 - 64 - 1)) xMouse = 640 - 64 - 1; if (yMouse > (480 - 64 - 1)) yMouse = 480 - 64 - 1; if (xMouse < 0) xMouse = 0; if (yMouse < 0) yMouse = 0; r.left = 64; r.right = 128; lpBackBuffer->BltFast(xMouse, yMouse, lpSprites, &r, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT); lpPrimary->Flip(NULL, DDFLIP_WAIT); } // Program entry point. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) { MSG msg; RegisterWindowClass(); hWndMain = CreateWindowEx(WS_EX_APPWINDOW, "SampleWindowClass", "DIrectDraw Sample", WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL); ShowWindow(hWndMain, SW_SHOW); InitDirectInput(); InitDirectDraw(); for (;;) { if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage(&msg, NULL, 0, 0)) break; DispatchMessage(&msg); } // idle-time processing OnIdle(); } return 0; }