Application of keyboard and mouse in directinput

Source: Internet
Author: User

to design a PC game, there must be no less input of the keyboard and mouse. Windows also provides mouse messages such as wm_lbuttondown and wm_rbuttonup, as well as keyboard input messages such as wm_keydown and wm_keyup. However, directinput still provides support for the mouse and keyboard, because directinput provides a more direct and faster access method to the input device. Just as we directly take over the keyboard interrupt in DOS, rather than using the nasty int16 to handle keyboard input (using int16 to handle keyboard input is especially evident in the story of Jin yongqun Xia, where the character will always have a nap before walking, this makes me feel very uncomfortable! I don't think I have to worry about it ).
of course, Windows keyboard messages are greatly improved compared to int16 messages (because it provides a wm_keyup message), but it is still insufficient in some aspects. Because the message mechanism in Windows is a buffer mechanism, unprocessed keyboard, mouse, and messages are placed in the buffer for the next processing. This is very important for some application software, however, for games (especially some action games, including sports games), it seems like a snake. For example, in a football game, when you intercept a opponent's ball, the ball is always set to the same key as the ball, shoot, shovel, and long pass, this seems to be a well-recognized standard-but now the opponent's ball is out of his feet, and the ball is under your feet. At this moment, you wanted to bring the ball around him, however, you have already pressed the ball snatching key. Because of this damn buffer mechanism, you must first handle this ball snatching key (that is, the shot key ), therefore, your action becomes a blind back-to-field remote shot (equivalent to a wide margin. You cannot control your own actions. It is really a failure to be a player. This is where the buffer mechanism is not applicable.

Directinput provides two access methods: Buffer and immediate access to the input device. The immediate method is exactly the solution to the above disadvantages. The keyboard initialization section in directinput is a long time agoArticle. Although it is for directx7, there is little difference between the directinput part in dx8 and dx7. Replace lpdirectinput7 with lpdirectinput8 and lpdirectinputdevice7 with lpdirectinputdevice8, in addition, the creation of the directinput object needs to be changed a little bit. The following function is used in dx8:

Directinput8create (hinst, directinput_version, iid_idirectinput8, (lpvoid *) & lpdi, null );

We can see the specific parameters in it. I will not talk about them much.

Next, let's talk about the mouse. The mouse buffer mechanism is very important. Moving the mouse is based on the accumulation of rolling counts. The mouse is sampled every 8 ms (the USB mouse is like this, I guess the same is true). If you only get the current status, it would be too slow to move the mouse. (no one will be using it.ProgramCall the mouse status to obtain the function every 8 ms ). The reason for using directinput is not because of buffering, but because of my personal preferences. A general game is used to determine whether the mouse position is at the edge of the screen when you roll the screen. I personally do not like this kind of practice very much. It may be because I am stupid to play games, and the pictures are often removed inexplicably, which makes me feel very problematic, why does the cursor point to the side of the screen to roll the screen? So I hope that moving the mouse is the basis of the screen, which is impossible in the message mechanism of windows. In the message mechanism of windows, when the mouse moves to the edge of the screen, the application cannot receive the wm_mousemove message. However, it can be implemented by myself in directinput. directinput only receives the scroll count of the mouse, which has no restrictions on the cursor position.

The following describes the initialization of the directinput mouse object.CodeThere is nothing to say.

// ========================================
Lpdirectinput8 PDI;
Lpdirectinputdevice8 lpmouse;

// Store the surface of the mouse cursor
Lpdirect3dsurface8 lpdscursor;
Handle hmouseevent;

// It is signed, so you can determine whether the cursor is removed from the screen to determine whether to roll the screen
Short mousex = fullscreen_width/2, Mousey = fullscreen_height/2;

Bool initinput ()
{
Hresult hres;
Hres = directinput8create (hinst, directinput_version, iid_idirectinput8, (lpvoid *) & lpdi, null );
If (failed (hres ))
Return false;

Hres = lpdi-> createdevice (guid_sysmouse, & lpmouse, null );
If (failed (hres ))
Return false;

Hres = lpmouse-> setdataformat (& c_dfdimouse );
If (failed (hres ))
Return false;

Hres = lpmouse-> setcooperativelevel (hmainwnd, discl_exclusive | discl_foreground );
If (failed (hres ))
Return false;

Hmouseevent = createevent (null, false, false, null );
If (! Hmouseevent)
Return false;

Hres = lpmouse-> seteventnotification (hmouseevent );
If (failed (hres ))
Return false;

Dipropdword dipdw;
Dipdw. diph. dwsize = sizeof (dipropdword );
Dipdw. diph. dwheadersize = sizeof (dipropheader );
Dipdw. diph. dwobj = 0;
Dipdw. diph. dwhow = diph_device;
Dipdw. dwdata = mouse_samplebuffer; // the predefined value is 16.
Hres = lpmouse-> setproperty (diprop_buffersize, & dipdw. diph );
If (failed (hres ))
Return false;

Lpmouse-> acquire ();

Return true;
}
Now we have taken over the mouse completely, so it is beyond reproach that the mouse cursor display task also falls on our head, but as I mentioned in getting started with d3d8, the cursor display can be supported by d3d8. Next we will create a cursor:

D3dlocked_rect DLR;
// The surface of the cursor can only be in the a8r8g8b8 format. It occupies an Alpha byte and does not support translucent data. It is really shit.

Hres = lpdevice-> createimagesurface (32, 32, d3dfmt_a8r8g8b8, & lpdscursor );
If (failed (hres ))
Return false;

Hres = lpdscursor-> lockrect (& DLR, null, 0 );
If (failed (hres ))
Return false;

// Write data to the surface. No need to talk about it.
..................
Hres = lpdscursor-> unlockrect ();
Hres = lpdevice-> setcursorproperties (0, 0, lpdscursor );
If (failed (hres ))
Return false;

Lpdevice-> showcursor (true );
The next step is to access the mouse data. Here I only process the mouse movement.

Void mouseevent ()
{
Dideviceobjectdata OD;
Hresult hres;
DWORD count;
Short x = 0, y = 0;
While (1)
{
Count = 1;
Hres = lpmouse-> getdevicedata (sizeof (dideviceobjectdata), & OD, & count, 0 );
If (hres = dierr_inputlost)
{
Lpmouse-> acquire ();
Return;
}

If (failed (hres) |! Count)
Break;

Switch (OD. dwofs)
{
Case dimofs_x:
X + = (short) OD. dwdata;
Break;
Case dimofs_y:
Y + = (short) OD. dwdata;
Break;
// Left-click or right-click the physical device and press/release it. If there is a left-side key exchange, you have to judge it by yourself.
Case dimofs_button0:
Case dimofs_button1:
If (OD. dwdata & 0x80)
// Press the key
............
Else
// Key release
............
}
}

If (X | Y)
{
Mousex + = X;
Mousey + = y;
// Determines the position of the cursor and whether to roll the screen.
............
Lpdevice-> setcursorposition (mousex, Mousey, d3dcursor_immediate_update );
}
}

Okay, now it's over. But I personally think there is a small defect. If you try it, you will find that moving the mouse is slower than Windows. Why? I saw an acceleration option in the Windows mouse settings, and thought it was probably because of this. Then simulate it. (Only the changes to the above function are listed below)

Short xaccel, yaccel;
Xaccel = yaccel = 1;

While (1)
{
............
Switch (OD. dwofs)
{
Case dimofs_x:
X + = (short) OD. dwdata * xaccel;
Xaccel ++;
Break;
Case dimofs_y:
Y + = (short) OD. dwdata * yaccel;
Yaccel ++;
Break;
............
}
.........
}

After this change, the mouse moved a lot more smoothly.

In addition, there is a time mark in the dideviceobjectdata structure, which can be used to determine the double-click of the mouse. Now our mouse simulation has taken shape. After you take over the mouse, you can define your own messages, such as what to drag (in Windows, it is annoying to judge the drag, and define one by yourself), three-click, or something. The advantage is self-evident, of course, it also brings about a disadvantage-that is, there are more code written, but this is the responsibility of game programmers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.