Sign in to follow this  

Win32 Input Library [Public Version 1.0]

This topic is 4193 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

I've been working on a Win32 input library recently because I want to get started on making a few games this summer. Rather than use another 3rd party's API for input (I wrote a SDL input wrapper a while back), I decided to just use Win32 and C to get this done. I used a lot of the same concepts that are found in cInput (the SDL one), but this time I didn't mess around with C++. I've implemented all of the same functionality that I had before and want to add some more, but right now is a good time to try and get some testing done. I've found a few minor bugs when writing the docs, but I'm sure there are some left. So, if anyone has a Win32 project right now and wants to try out a input library, I could use a few testers with real projects! Here's what you can do with the library:
  • Get/Set/Modify mouse position
  • Get/Set Key states
  • Get/Set Mouse Button states (supports X1 and X2 mouse buttons)
  • Check the focus of the keyboard/mouse
  • Check to see if the mouse cursor is in the window
  • Grab the mouse to the window
  • Simple event checking system, only 1 main event callback (which is optional)
  • Supported events include mouse hovering, mouse leaving the window, and the mouse wheel.
  • Key/Mouse Combinations
  • User Typing Support (when you need to let the user type in something)
  • Library can be used with multiple windows in your project and does not "force only one".
  • Full Documentation + lots of examples (all in the header file, online docs are built from that)
  • Source Code will be avaliable at version 1.0. Project uses ZLib license
  • I will make a C++ port, but only after 1.0 to ensure the library is very solid.
  • Multiple compiler support is planned, but right now only Visual Studio can be used. If anyone wants to test and has only DevCpp, I should be able to get a port of that done for you.
I want to add some more features as I go along (such as gestures), but for now I want to get testing done to make sure it's pretty solid. The main thing I'm looking for is inconsisties and logic errors. I'll probabally go though and make some NeHe ports using this lib for testing as well. If anyone has any questions, I'm around. Thanks! Input Library [Edited by - Drew_Benton on June 16, 2006 10:20:59 PM]

Share this post


Link to post
Share on other sites
This is a really good input library, good job! I'll definetly have a look at it and, seeing the intended license, I might use it in the game I'm currently making. I'd have appreciated something a bit more C++ish but I'll wait to see your future port. Could you update this topic when you will have improvements on your work? I'd like to be able to watch this topic to have e-mail notices.

Very good job, once again, and thanks for choosing the ZLib license!

Share this post


Link to post
Share on other sites
I have just finished up version 0.2 (well quite a few hours ago actually). This release was done to make the library a lot easier to use. The library will now clean up everything automatically so the user does not have to worry about that. In addition, a hook for the window is used to automate everything so it is now just a plug-and-play styled library.

Here are the version 0.2 changes:
  • A call to Input_Create sets a message hook for the window so the Input_WndProc function does not have to be called manually.
  • Input library *should* be able to work with *any project* now due to the change in the architecture. All you need is a HWND! I have tested successfully with SDL and will add more for each other lib I try.
  • The Input_WndProc has been removed from public exposure and is now only used internally.
  • The library keeps track of all Input structs and will free them at the end of the program.
  • The library keeps track of all tCOMBO structs and will free them at the end of the program.
  • The <Input_Destroy> and <Input_DestroyCombo> functions have been left in to allow the user to free resources when needed.
  • The Input struct now has a <Input_OnEvent_FuncPtr> variable, OnEvent, that will be called (if it is not NULL) on a event. Set this if you want those messages for that Input struct to be routed to your function.
  • Input_Create will now fail if no HWND is specified.
  • Docs have been updated to reflect all changes.
  • Library has been reverified to be leak free after changes.



Quote:
Original post by Trillian
This is a really good input library, good job! I'll definetly have a look at it and, seeing the intended license, I might use it in the game I'm currently making. I'd have appreciated something a bit more C++ish but I'll wait to see your future port. Could you update this topic when you will have improvements on your work? I'd like to be able to watch this topic to have e-mail notices.

Very good job, once again, and thanks for choosing the ZLib license!


Thanks for your feedback! I was considering making the C++ port sooner, but after working with it for a little, I decided against it. It would require a re-work of all of the docs and examples as well as a lot of the code, so I will not do that until I get a more solid baseline to use.

However, I will see if I can put together a C++ wrapper for the time being. That way I still have the original C library to use, and I can change the wrapper as I develop. If the wrapper turns out allright, I might not need to make a C++ port. I don't think the overhead of the wrapper will be that bad, but we'll see how that goes.

As for features I am currently looking into: Mouse Gestures, Mouse Button Combos, Input Recording/Playback System, and "Pressure" Simulation. A few of those might add too much to the library so I can't say I'll end up adding all of that.

I'll post another update this afternoon, I am working on version 0.3 right now and am probabally going to add one more thing and then do some more testing for bugs.

[Edited by - Drew_Benton on May 24, 2006 4:16:30 PM]

Share this post


Link to post
Share on other sites
I've got version 0.3 done now if anyone wants to give that a try. The main changes are now there is a C++ wrapper avaliable if you want to use that. It is part of the header file and will only be compiled in if there is a preprocessor define set. Since the library uses a local application hook on the window its used on, I'm confident to say that it should work with *any* project. I'm still trying out various 3rd party apps, but so far all I've tried have worked flawlessly.

Here are the version 0.3 changes:

  • Removed an unused define and internal array.
  • Type cast malloc memory to aid in future C++ port. Library can now compile without modifications as C or C++ code.
  • Library will still compile under Warning Level 4 (/W4) without any warnings.
  • A simple C++ wrapper was made to allow for a little cleaner use of the library.
  • Little cleanup of implementation file in respect to global variables and free functions.
  • How-to added for Ogre3D (not tested) and Allegro (tested). While the tests were not extensive, the basic test of "does it compile and run" was used (Input_GetKeyState was the tested function).
  • Redefined INPUT_*_BUTTON values to allow for mouse buttons to be used more intuitively.
  • Mouse buttons are now part of the combo system.
  • Moved the combo specific data out of the "key data" and into the "event data".
  • The Input_MsgHook function now correctly allows other hooks to execute.
  • Docs have been updated to reflect all changes.



I doubt I will get into adding the input tracking and playback, just due to of all the "technicalities" of that concept or the "pressure simulation", but I do want to add in mouse gestures, so I think that will be the big update for 0.4 as well as more testing and bug looking. I used the library with NeHe's lesson 21 (the line game) and it worked fine. I'll try a few more of his demos and then some more complex examples, such as Ogre and Irrlicht.

[Edited by - Drew_Benton on May 25, 2006 5:16:36 PM]

Share this post


Link to post
Share on other sites
Well version 0.4 is now done and I have simple mouse gestures added!

Here are the version 0.4 changes:
  • Added a simple 'dumb' gesture system!
  • This version is not well tested or what I'd call 'stable', expect changes and updates soon. It is being released as a beta test.



For version 0.5 I will be cleaning up the gesture system as well as make some general improvements to the library. The gesture system is very "dumb", it only supports simple line gestures that are of different directions. For example, a right then up gesture would work fine but a right then left gesture would not (at this time).

Using the gestures is pretty easy, I know I don't have the good docs for doing it but it's just a matter of calling the Input_CreateGesture with first the Input struct to register it with, then the number of gestures you are going to add, and then finally a list of the direction and then the "type" of movement for it. There are 3 main types, short, medium, and long. The directions are left, right, up, and down. Take a look at Example 9 for a complete example.

[smile]

[edit]
Oh and I forgot to mention, to execute a mouse gesture, press and hold the left mouse button, execute the gesture, and then relase the mouse left mouse button.

[Edited by - Drew_Benton on May 27, 2006 1:56:56 AM]

Share this post


Link to post
Share on other sites
After a full days of work, I present version 0.5!

Here are the version 0.5 changes:
  • Redid the structure of all the libraries data types. Everything is now properly seperated and made for easy update.
  • Removed a few extra functions that would not server a good purpose for the library. Added a few more to complete functionality.
  • Removed global variables and used static local functions instead to hold the global variables needed (only 1).
  • Fixed bugs with the combo and gesture systems.
  • Updated code so it will compile with VS6, VS7, and Dev-Cpp 4.9.9.2.
  • Added functionality to cursor grabbing so a rectangle is now supported as well as a full window.
  • Hardcoded support for hover and mouse leave events have been removed and in place is a compile time preprocessor that allows the programmer to select which is needed for the program.
  • Defines that do no need to be public have been moved to the proper location.
  • Additional mouse information has been added for the left/right control keys on the mouse event.
  • Both mouse and keyboard data is filled out for each respective event, so if you have a keyboard event, you can see the data of the mouse though the mouse event if desired.
  • How-To section on the docs was copy-pasted over with minor edits, will have to go though that more in depth to verify it is all correct. The full examples were recompiled and fixed as needed, so they are fine.
  • The programmer is now in charge of starting/stopping gesture recording, in the last version it was hardcoded to start on left mouse button up/down.
  • Minor code cleanup and variable name changes. Organized the implementation file a bit too.



I am very happy with the library right now. I did a total refractor today, I went though almost line by line and made improvements and changes. I redid most of the docs as well, but I still need to be on the look out for those "careless mistakes" [wink]. I could still use some testers if any one has a project that they need an input system for [smile] Of course, tech support is free and will be readily avaliable!

Anyways, right now I think I will be on the lookout for bugs and documentation errors. I'm pretty happy with the set of functionality I have right now, I don't plan on adding anything else right now. Although if anyone has something they'd like to see that I don't have, I will always consider it. I think that's about it for now, if anyone has any questions or comments, please share!

[Edited by - Drew_Benton on May 27, 2006 3:33:31 PM]

Share this post


Link to post
Share on other sites
I woke up this morning and something came to mind, why am I passing around Input*s when all I need is an ID?

Here are the version 0.6 changes:
  • Fixed a bug when incorrectly setting a new mouse position in a key event.
  • There will be no more Input* objects needing to be passed around, everything has been resolved to using an ID instead. The user will still get an Input struct pointer, so they can set the ‘OnEvent’ variable as well as store the ID for that object.
  • Updated the docs to reflect the new API style as well as did some cleanup of the How-To section. All of the Full Examples have been updated and verified to be copy and paste compile and run ready.
  • Library is still leak free.
  • C++ Wrapper has been properly updated.



Basically what I did was make the library even easier to use by not making the user keep track of the actualy Input*, all they need to do is keep track of the ID for their input object. If the need should arise to get the Input* again, then there is a function, Input_GetObject, that can be passed the ID and the Input* will be returned.

I went though the How-To's and cleaned those up as well as fixed all of the examples. Of course the full examples do not express the "best way" to use the library, just "a way" to help people get started. I downloaded Ogre last night and will be trying out my library with it later today, so I will include those results in version 0.7. I think I will also try out Irriclit as well.

Speaking of version 0.7, right now all I forsee is cleanup. The idea of taking out the Input* was something I thought of last night out of the blue when I was getting in bed, so I woke up first thing this afternoon and fixed everything. I am pretty sastified with all of my work so far, I don't detect any memory leaks or abnormal behavior, but I'm sure there are a few bugs hiding. I found a bug I introduced in Version 0.6 when playing with a camera tutorial and my input library. I will be testing with some more stuff like that as well to see if I can find any other flaws. That's it for now!

[Edited by - Drew_Benton on May 30, 2006 2:17:49 AM]

Share this post


Link to post
Share on other sites
Now that GameDev is back up and running, here is the latest version!

Here are the version 0.7 changes:
  • The mouse hover behavior has been properly changed so it will only generate one hover event at a time when the mouse is still.
  • Few minor perforance enchantments.
  • Removed a change made in 0.5 (The 3rd listed *)
  • Made all internal functions static.
  • Removed all interal calls to Input_GetObject(Input_GetObject_D for debug) and used direct access to the input array for release mode. No bounds checking is done in release mode now.



Not much going on now, just a few performance enchancements and stuff. I'm still on the lookout for bugs and logic errors, but I don't think I'll find any more of those until I start using the library in an applicable sense, which should be soon. I do plan to write a tips and tricks section to give programmers a guide of how to use the library to the best of its ability. I had started on that section, spent a good 45 minutes making the first entry, then when I went to recompile the example in VS6, I accidently overwrote the new version with the old version. So lots of work lost there, that's why it's not in version 0.7.

Anyways things are pretty good so far, I think I really only need to start using the library heavily to iron out any last bugs. After that, I think that should be it and version 1.0 will be official! As usual, any comments or suggestions, I'd like to hear [wink].

[Edited by - Drew_Benton on May 31, 2006 5:30:18 PM]

Share this post


Link to post
Share on other sites
It's looking pretty sweet, I'll remember it if I'm ever in the market for an input library. [wink]

Drew, I'm glad to see another fan of Natural Docs, too!

Share this post


Link to post
Share on other sites
Quote:
Original post by Boder
It's looking pretty sweet, I'll remember it if I'm ever in the market for an input library. [wink]

Drew, I'm glad to see another fan of Natural Docs, too!


Thanks! Yea, I am really liking the Natural Docs. Sometime this summer I actually want to do some modding of it so I can have syntax colored code for the examples and stuff.



I finally decided to give input recording and playback another try and this time I think I got it down right!

Here are the version 0.8 changes:
  • Few lines of code cleanup.
  • Added a state flag to the Input object. Input objects can now be turned off and on as needed using the <Input_SetState> function.
  • Added in an input recording and playback system. It is still under testing, but so far I think it is stable. Right now it is limited, record is sent to log.txt and read from log.txt. The pausing has not been tested in playback and recording either, so only start and stop should be used.



I did lots of basic testing with the input playback and recording and it looks somewhat stable and reliable. I still have lots of testing and stuff to do with it though, so it's just a "beta feature" right now. I will probabally expand the API for it as well rather than just have one state function to be used. I'm sure there may be a few problems here or there with it because one part of my code I have:

if(!Input_Buffer(data))
{
/* Not sure yet */
}

So yea [smile] I have to do some more thinking it though. Other than that its just the usual cleanups and stuff. I updated the howto and example sections with the details of how to use the playback and recording system as of now, but I'm sure it will change. Expect more to come!

[Edited by - Drew_Benton on June 3, 2006 1:43:15 PM]

Share this post


Link to post
Share on other sites
I finally got back to working on some updates after a few days break (been playing Silkroad Online [grin])

Here are the version 0.9 changes:
  • Redid some of the logics of input recording and playback. The file written and read can now be specified in the new API functions.
  • New API functions for input recording and playing.
  • On Input playback, when paused, the time paused is tracked to properly keep input relative. This functionality has not yet been tested though.
  • Moved pricate defines out of this header file into the proper location.
  • The input recording/playback system uses its own custom structure rather than a MSG.
  • Updated examples for playback and recording as well as the how-to.



Now, the input playback and recording system is a lot better than it was before. However, I am not yet happy with it, well the concept of it. THe thing is, input can be played back just as its entered, but how do you handle getting input from the user concurrently while playing back the old input without interfering with the data that is being played back? I was thinking of adding a flag that represents events from played back data, but I'm not sure how much that would help, if any. I was thinking about adding another event loop for played back data, but that would be way too complicated. Anyways, I'll think about it some more later tonight, time for a game break. As for other parts of the library, I think everything is still holding together, but if anyone runs across anything fishy, please let me know!

[Edited by - Drew_Benton on June 16, 2006 10:45:21 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Cool! I'll use it for my Irrlicht-powered Fatal Freedom: All or Everything. I was looking for a non-SDL input library for some time now.



-Anteater (www.decapgames.2ya.com)


Share this post


Link to post
Share on other sites
This looks great, clean api, excellent documentation and nice license.
I would like to use it, I don't want to be annoying but any idea when you will make the source available? The problem is I want to use it with D, there is a tool to automatically generate bindings but the COFF object file format is not supported by the digital mars linker, so I'll have to recompile the thing with the DM C compiler.
I have to say again that the documentation is great, and looks good too!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I'm having linker troubles with GCC/MinGW. Does this library work with MinGW or just MSVC?

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
I'm having linker troubles with GCC/MinGW. Does this library work with MinGW or just MSVC?


It should work with MingW, I've tried it out, but I did not yet make a release for it. I'll do that soon, I will spend maybe one more day looking over it and then relase 1.0 w/ source [smile] It does compile though with those two, its just the package is for MSVC right now. I'll get that updated.

Share this post


Link to post
Share on other sites
Ok guys sorry for the delays, been slacking [wink] Here is version 1.0 which represents the first public release after all of my testing and stuff. Nothing has changed since the last version though. If anyone runs into trouble using it, finds bugs, or anything else, just let me know! Complete documented source is included as well as the docs in a Natural Docs format. Included in the final package is just the docs, which are also online, as well as the header and implementation file. They can just be added to your existing project. I've tested this with a wide varitey of compilers, so it should work fine with DevCpp and all VS versions from 6.0 and above.

Input Library 1.0

I hope you guys enjoy it! If you have any trouble with the source just let me know, I'm around [smile]

Share this post


Link to post
Share on other sites
Wonderful job, it was very nice of you to keep this "developper log" on this thread, it was interesting to note your progress.

I'm going to start using your library right away!

Share this post


Link to post
Share on other sites
I agree with Trillian, I had bookmarked this and it was a very nice effort of presenting your work and making it usable for others. While I won't use the lib I will look at natural docs, never heard of this until now

Share this post


Link to post
Share on other sites
Thanks guys, I appreciate it!

Sadly though, I'm going to hae to axe support for SDL and all my "intuitions" that this library should work with any 3rd party library. It would seem that in SDL, TranslateMessage is not being called along with DispatchMessage, so certain messages are never received. Furthermore, there is something else going on so I'm getting 2x of each event that I'm not supposed to.

Now seeing this, I'll make the updates to the library docs so it's more accurately represented. I fixed the TranslateMessage problem with SDL, but I'm still looking for the other bug where 2x events are being processed. I think I'll switch frameworks for my little 2D lib I'm working on. Tis a shame, maybe I'll try to get on the mailing list to see why certain Win32 stuff is not being used with SDL.

I'll also be on the lookout for more bugs and any improvements, now that I have a chance to use it in practice. While I'm at it, for anyone using OpenGL and needs a GUI, check out SXML GUI (by JavaCoolDude). Aside from the two bugs I found with SDL itself, I was able to easily integrate that GUI and my input system together, so I'm very happy with the design of both [smile] I'm going to be switching frameworks to GLFW probabally, so I'll post either a new reply here or a new thread showing the relation of the input library with the GUI lib and the rest of my code.

Cheers and thanks for the feedback!

Share this post


Link to post
Share on other sites
For anyone using CEGUI (which I am currently experimenting with) I have the code for using the input library with it. I will be updating the library itself soon, but for now here is the code to inject input into CeGUI from the Input library. Just setup CeGUI normally and add in the following code to your input handling function.


void OnInputEvent(tInputEvent* event)
{
if(event->message.M_Move)
{
CEGUI::System::getSingleton().injectMousePosition(static_cast<float>(event->mouse.x), static_cast<float>(event->mouse.y));
}
else if(event->message.M_LeftButtonDown)
{
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);
}
else if(event->message.M_MiddleButtonDown)
{
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);
}
else if(event->message.M_RightButtonDown)
{
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);
}
else if(event->message.M_LeftButtonUp)
{
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);
}
else if(event->message.M_MiddleButtonUp)
{
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton);
}
else if(event->message.M_RightButtonUp)
{
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton);
}
else if(event->message.M_WheelDown)
{
CEGUI::System::getSingleton().injectMouseWheelChange( -1 );
}
else if(event->message.M_WheelUp)
{
CEGUI::System::getSingleton().injectMouseWheelChange( 1 );
}
else if(event->message.K_Char)
{
CEGUI::System::getSingleton().injectChar(event->keyboard.nVirtKey);
}
else if(event->message.K_KeyDown)
{
CEGUI::System::getSingleton().injectKeyDown(event->keyboard.nVirtKey);
}
else if(event->message.K_KeyUp)
{
CEGUI::System::getSingleton().injectKeyUp(event->keyboard.nVirtKey);
}
}



All you have to do is register the OnInputEvent with your Input's OnEvent variable and you will be all set. If you already have one, combine the code (watch out for duplicate cases if you have some!)

More to come later!

Share this post


Link to post
Share on other sites
Sign in to follow this