How to get Direct Input mouse Abs position?

Started by
9 comments, last by Possibility 23 years, 12 months ago
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
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
adamm@san.rr.com
will do, i am still reading about it in SDK but still cant figure it out

Possibility
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.
---------- JonHobson ----------

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
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).
"after many years of singularity, i'm still searching on the event horizon"
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.
adamm@san.rr.com
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+
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;
}

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-
Professional C++ and .NET developer trying to break into indie game development.
Follow my progress: http://blog.nuclex-games.com/ or Twitter - Topics: Ogre3D, Blender, game architecture tips & code snippets.

This topic is closed to new replies.

Advertisement