Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Possibility

How to get Direct Input mouse Abs position?

This topic is 6935 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, I had gotten a book a while ago to set up a direct input mouse, but the mouse position is given in relative position. The book showed how to set the position to absolute, but its so inaccurate. For example, If I have mouse on the left side of the screen, and its at position 0 and move it the right side when int 1024x768 resolution, the mouse position should be at 1023 then. But with direct input its different every time, its so inprecise. It usually ends up saying it only moved like 1/2 to 1/3 of the actually amount it moved. In that example, it would usually say on the rigth side it was only x position 500 to 800, not 1023. I know how to use the windows mouse coordinate system, that returns the real true precise mouse coordinates, but if you hit a keyboard key, it screws that mouse position up. So I checked in directX 7 SDK, and found something about ABS position, but I can never understand that SDK, they do such a horrible job of explaining stuff. Here is what i have for my DI Mouse set up currently: /////////////////////////////////////////////////////////// //---- DIRECT INPUT MOUSE SETUP----// if(lpDI->CreateDevice(GUID_SysMouse, &pMouse, NULL) != DI_OK) { ErrStr = Err_CreateMouse; return FALSE; } if(pMouse->SetDataFormat(&c_dfDIMouse) != DI_OK) { SafeRelease(pMouse); return FALSE; } if(pMouse->SetCooperativeLevel(hWnd, DISCL_FOREGROUND / DISCL_NONEXCLUSIVE) != DI_OK) { SafeRelease(pMouse); return FALSE; } if(pMouse->SetEventNotification(CreateEvent(0, 0, 0, 0)) != DI_OK) { SafeRelease(pMouse); return FALSE; } DIPROPDWORD dipdw = { {sizeof(DIPROPDWORD), sizeof(DIPROPHEADER), 0, DIPH_DEVICE}, 32}; if(pMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph) != DI_OK) { SafeRelease(pMouse); return FALSE; } if (pMouse->Acquire() != DI_OK) { SafeRelease(pMouse); return FALSE; } ///////////////////////////////////////////////////////// Now here is what the SDK for having the mouse data return ABS position instead of relative: The axis mode, which specifies whether relative or absolute data should be returned, is a property that can be changed before the device is acquired. (See Device Properties.) To set the axis mode to absolute, call IDirectInputDevice7::SetProperty with the DIPROP_AXISMODE value in the rguidProp parameter and with DIPROPAXISMODE_ABS in the dwData member of the DIPROPDWORD structure. I have tried to understand how to actually do this and read all of it, but I am just to stupid and cant understand how I actually do. Please help. Possibility

Share this post


Link to post
Share on other sites
Advertisement
Hey I''m having the -exact- same problem!
If you figure it out, would you email me?
I''ll do the same..

Adam M.
adamm@san.rr.com

Share this post


Link to post
Share on other sites
I presume the only time you would want the screen coordinates would be for a menu. If this is so, I would just use the WM_MOUSEMOVE windows message: This gives you screen coordinates of the mouse. It may not be as fast as DInput, but it should be adequate.

If you use the LOWORD(lParam) macro you have the x position of the cursor. The HIWORD(lParam) gives you the y pos.

Share this post


Link to post
Share on other sites
Well this is how i get the absolute value coordinates, i don't fully understand you problem, but...
I have two variables (they are ints and both are globals) for the absolute x and y position on the screen, you never reset them to zero or else you'll lose the absolute coordinates.

When the mouse is move, i add the relative values given to the variables. For example if direct input reports a -5 for the relative value on the x axis, i add it to the absolute x value. Then to stop the mouse from giving coordinates that are less than or greater that the width and height of the screen, i have four if statements...

if(abs_mouse_x < 0)
abs_mouse_x =0;

if(abs_mouse_y < 0)
abs_mouse_x =0;

if(abs_mouse_x > screen_w)
abs_mouse_x = screen_w;

if(abs_mouse_y > screen_h)
abs_mouse_y = screen_h;

This method has given me precise coordinates
Hope this helps




Edited by - +AA_970+ on 4/28/00 8:49:56 PM

Share this post


Link to post
Share on other sites
I always have problem using abs position. No matter how I tell DInput to return abs position, it still give me rel position.

In the end, I use back the relative position and do the math myself (to convert it to abs position).

Share this post


Link to post
Share on other sites
Yes, that''s what we''re trying to do, but the problem is that the relatives don''t add up to the real screen position!
ie. if i have a 640x480 window.. and move the cursor from the left side to the right side, directinput only says it''s moved maybe 200-300 pixels.. not the full 640. The buffer size is 16 events, and it''s running in its own thread that does nothing but wait on the event and process the movement/clicking. Using WM_MOUSEMOVE always returns the proper value though... I should check to see if the dinput buffer is being overrun and I''m losing data.. but I sincerely doubt it, as it does this even when my program does nothing but process mouse events.

Share this post


Link to post
Share on other sites
i don''t know much about windows programming and not sure what you are talking about when you say "...it''s running in its own thread that does nothing but wait on the event and process the movement/clicking." I assume your talking about the main window procedure (WindowProc). Try updating your mouse data from within WinMain.

+AA_970+

Share this post


Link to post
Share on other sites
use this method

while(!fDone) {
hr = lpdiMouse->
GetDeviceData(sizeof(data),&data,&elements,0);
if(hr == DI_OK && elements == 1) {
switch(data.dwOfs) {
case DIMOFS_X:
XPos += data.dwData;
break;
case DIMOFS_Y:
YPos += data.dwData;
break;
}
}
else if(elements == 0)
fDone = true;
}

Share this post


Link to post
Share on other sites
Hehee, did you build all those initialization steps yourself ? If you''ve done so, it cannot imagine how you''ve missed the axis mode in SetDataFormat()

 DIDATAFORMAT DIDataFormat;
 
 CopyMemory(&DIDataFormat, &c_dfDIMouse2, sizeof(DIDataFormat));
 DIDataFormat.dwFlags = DIDF_RELAXIS; // or DIDF_ABSAXIS
 lpDIDevice->SetDataFormat(&DIDataFormat);

Anyway, using the mouse in relative mode and adding the movements to an x and y coordinate are probably the better way, absolute mode can sometimes (especially with glide) cause problems (ex. mouse limited to 640x480 in a resolution of 1024x768).
This also allows to easily place the mouse at another position and other things

-Markus-

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!