Sign in to follow this  
joe_bubamara

buffered raw input?

Recommended Posts

Has anyone got buffered raw input to work? I don't have problemw with reading input with GetRawiInputData; but when using GetRawInputBuffer, it just doesn't work. Below is msdn example rewritten to both compile AND run: case WM_INPUT: //void __glwBufferedHandle(HRAWINPUT input) { unsigned int size = 0; PRAWINPUT raw; int status; status = GetRawInputBuffer(0,&size,sizeof(RAWINPUTHEADER)); //glwPrintLastError(L"GetRawInputBuffer: "); printf("status %d size %d\n",status,size); raw = (PRAWINPUT)malloc(sizeof(RAWINPUT)*16); size = sizeof(RAWINPUT)*16; if(!raw) puts("no buffer"); for (;;) { int nInput = GetRawInputBuffer(raw, &size, sizeof(RAWINPUTHEADER)); printf("nInput = %d\n", nInput); if (nInput == -1){ puts("nInput == -1"); break; } if(nInput == 0) { puts("no input read"); break; } PRAWINPUT* paRawInput = (PRAWINPUT*)malloc(sizeof(PRAWINPUT) * nInput); if (paRawInput == NULL) { puts("NUL"); break; } PRAWINPUT pri = raw; for (UINT i = 0; i < nInput; ++i) { printf("found input %d\n", i); paRawInput[i] = pri; pri = NEXTRAWINPUTBLOCK(pri); } DefRawInputProc(paRawInput, nInput, sizeof(RAWINPUTHEADER)); free(paRawInput); } free(raw); } Observe this line: size = sizeof(RAWINPUT)*160; According to docs, calling: GetRawInputBuffer(0,&size,sizeof(RAWINPUTHEADER)); should give you size of required buffer. That never happends. It ALWAYS returns 0. So I have just alloced some big buffer to make it run. However no input is ever read? nInput should contain number of structures in buffer that are red, but it is always 0, or -1 sometime (but GetLastError repports no error :-)) Anyone with some suggestions? Is there anyone who has got buffered raw input to work? After a long sleeples night, I start to believe that this api is just a big buggy cirkus working only in some basic cases, or maybe it is me missing something important?

Share this post


Link to post
Share on other sites
Hi Gage, thnks, I missed that post (I have seen hundreds of other posts :-)).

Yeah it explains some things, and now that is probably explanation why directx creates separate thread for reading input.

Now according to this article: http://msdn.microsoft.com/en-us/library/bb206183(VS.85).aspx

(and some ppl on this forums), this is nonsense to do. But obivously there was reason why directx "just creates separate thread and starts to listen for input", as many repeates as mantra. If we want to support multiple devices and do thins in timely manner, what alternative do we have, at least acording to that post Gage pointed me to? We can do exactly like directx does, and create another thread or read everything one by one message? Or are there any other suggestions and experiences on how to make this work?

I have seen some posts on this forums where ppl are advising others to use rawinput and buffer reading, can they maybe explain how they do? I woul really be glad and thankfull for help.

I am trying to make my own input library with support for multiple mouse, keybds, gamepads/joystics and which will NOT require directx to be installed in order to work, so I am really eager to get this thing sorted out.

cheers

Share this post


Link to post
Share on other sites
There's some code here that implements a simple buffered input scheme using only Win32 messages. It doesn't use multithreading or raw input (that code is supposed to be educational so it is simple and heavily commented). It only reads keyboard info but it should still give you the general idea.

Share this post


Link to post
Share on other sites
thnks for reply and the link; I have looked through the link, and here is how I see that code.

Most important thing is it doesn't and CAN NOT handle input from multiple keyboards at all. That is main disatvantage of using standard window's messages, and that is reason why rawinput is invented (and directx but they thought more of several joysticks rather then keyboards or mouses).

Secondly it still processes one by one message, it just doesn't pass those to application, but saves them in internal buffer before it passes it to the app. Point with buffered rawinput is that number of windows messages should be minimized - I think, I am unsure here.

I believe it works like this: with GetRawInputData, there is one WM_INPUT message for every keypress, mouse move etc, while buffered method should peel out several of those messages at once, so total number of WM_INPUT messages will be reduced and thus total number of window proc runs should be as well reduced.

I at least believe that this is how it should work, but I might be wrong, I am not that experienced with win32, and rawinput docs are really bad and scarce.

Maybe that is reason why buffered method does not work in WM_INPUT message, as the post you pointed me to says. It should probably remove ALL wm_input messages from the geue, and application will not see WM_INPUT messages at all, so that is probably why directx uses another thread for processing. Once again, I am not sure of all this, I am just trying to reason about it and uderstand what is going on. I hope there is soemone with a bit more knowledge of win32 and raw input who can clear things up a bit?

As a side note, I don't that like packing/repacking of the input the example does, it wastes 3 times more space then unnecessary, but I understand that was not point with example ... :-)

Share this post


Link to post
Share on other sites
Sorry, but maybe I should clear things up a bit. I am making my own little tiny library for handling input. It should be as small as possible, effective as possible and support multiple keyboards, mice and gamepads/joysticks (I will use it for making console like games, with several pads). It should work on mac/win/linux and for win platform one desire is to have it independent of directx so that platform is selfcontained (and portable) as much as possible.

I didn't consider this detail important for problem regarding buffered input, but maybe it explains why rawinput is important to me and why standard windows messages are out of question.

Share this post


Link to post
Share on other sites
For reading from multiple mice then raw input is the way to go, it has been some time since I implemented this in a framework and you are correct the only word that can be used to describe the msdn docs is shit.(or maybe piss poor) There is a framework which is cross platform using raw input on windows for multiple mice devices, but for the life of me I can not remember the name of it at present. It may be in my bookmarks on the psp I will have a look and post back if I find the link.

Share this post


Link to post
Share on other sites
You maybe mean this: http://www.mouse-party.com/index.shtml

what you think of is "mouse party" games or something like that. I have seen their framework and at least the code and example they give for free is not much more then what you can find on code project tutorials or elsewhere on the net about rawinput. Needles to say is they are using unbuffered method.

I can already use unbuffered method myself with any number of keyboards, mice or joysticks. Generally rawinput sucks when it comes to mouse in other aspects as well, but that belongs to some other post :-). Just as short mention: read this

http://msdn.microsoft.com/en-us/library/bb206183(VS.85).aspx

and think about what happened once you need absolute coordinates. No it is not to just "simple track and add relative coordinates", as I have seen ppl saying in several posts on gamedev and elsewhere ... read article carefully. Or make demo and draw your custom cursor and compare with system cursor as I did.

Share this post


Link to post
Share on other sites
ohhohhh ... the wonder of search ... why didn't I ever used "many mouse" as search term :-).

Thnks for pointer, this is totally new library to me, I will check it out ASAP.

_____________________________

Nice little library, but they also use unbuffered method. thnks for the link, I maybe can use it on mac and linux instead of writing my own.

[Edited by - joe_bubamara on May 6, 2008 4:25:22 PM]

Share this post


Link to post
Share on other sites
I have just tryed a little experiment and hooked buffered input handler on WH_GETMESSAGE. I hoped that intercepting WM_INPUT before it reaches win procedure shoud help things; but nada.

I see that I am properly called and handler executes on WM_INPUT message, however GetRawInputBuffer(0,&size,sizeof(RAWINPUTHEADER)); still always returns 0 and never reads any input.

I don't have time to try version with hidden popup window as explained in that post above, but some time in near few days I will try that one as well.

Share this post


Link to post
Share on other sites
Quote:
Original post by joe_bubamara
I see that I am properly called and handler executes on WM_INPUT message, however GetRawInputBuffer(0,&size,sizeof(RAWINPUTHEADER)); still always returns 0 and never reads any input.

This is correct behaviour which the docs do state
Quote:
If pData is NULL and the function is successful, the return value is zero...

Quote:
pData
[out] Pointer to a buffer of RAWINPUT structures that contain the raw input data. If NULL, the minimum required buffer, in bytes, is returned in *pcbSize.


You should be doing something like

RAWINPUT *raw;
status = GetRawInputBuffer(0,&size,sizeof(RAWINPUTHEADER));
assert(status == 0);
raw = new RAWINPUT [sizeof(RAWINPUT)*size];
UINT count = GetRawInputBuffer(raw,&size,sizeof(RAWINPUTHEADER));



edit:
Hmm I actually think the function docs are incorrect in respect to the size as it says "If NULL, the minimum required buffer, in bytes, is returned in *pcbSize." I think that should read "If NULL, the minimum required buffer, the amount of RAWINPUT structures, is returned in *pcbSize."

Share this post


Link to post
Share on other sites
dmail, I was already doing that what you are saying I should; read my code carefully. When I said "returned value is zero", I meant the value returned in "size" - the value of required buffer, not the return value of the function itself (which is status of success). I thaught it was obvious so I didn't pointed that out in my post ( and I also use "0" instead of "NULL", which is same thing since NULL is just defined to be zero, but I didn't care to explain such simple details :-)). I think that it was pretty clear in my first post, that this "minimum required size" is always set to 0. That's why I override value of size in this line: size = sizeof(RAWINPUT)*16; - just to get it to continue on with the execution to see if I can read any data ... :-).

Just to mention there is also "status" value and I did check the GetLastError after every call and can assure that it returnes 0 (success) in all cases (I have just removed those checks for example posted on gamedev for simplicity).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this