• entries
743
1924
• views
581612

# User defined controls

185 views

[Updated DEMO now available.]

Woohoo [grin]

That was a lot of hard work.

Firstly, I had to switch to using DirectInput rather than responding to WM_KEYUP and WM_KEYDOWNs, since it felt a bit rubbish that you couldn't define the ALT keys.

Then I copy-pasted the entire DIK_* list from the MS DirectInput SDK into a text file and removed all the commas.

Next I wrote a program to read in this list and output a C++ file that, when compiled, produced a text file with the actual numeric value of each DIK_* along with the DIK_* next to it on a line.

Then I removed all the DIK_ bits, took out all the Japanese and weird keys and renamed each key with a meaningful name.

Then I wrote another program that took in this new file and spat out in my config format. I then wrote a static lib that wraps the DirectInput keyboard stuff and also loads a configuration file that names each key based on its index in the DirectInput keyboard array that you retrieve.

Bingo bongo, done. Not only can you now define keys and get a string onscreen in the menu, but since you can also search my CKeyState object by text name for the relevant code, I can store the key options by name in the udo.cfg file:

; Udo system settings file; Autogenerated file - do not modify; Please refer to user.cfg for editable settingsdisplay_mode="1024 X 768"sound_on=truemenu_up="UP"menu_down="DOWN"menu_select="RETURN"escape="ESCAPE"space="SPACE"up="UP"down="DOWN"left="LEFT"right="RIGHT"fire="SPACE"

All minor details, but important ones. Implementing the menu was suprisingly easy, actually.

Never written a game with user defined controls before. Cool. Obviously if you were playing on a non-UK keyboard, you would have to provide a different keydefs.cfg file, but that's not a problem as far as I am concerned. Certainly beats messing about with GetKeyNameText().

In case it is ever of use to anyone else (or in case I lose it), here's the keydefs.cfg file. The numbers correspond with the index of each key in the array returned by IDirectInputDevice8::GetDeviceState() when applied to a keyboard.

11="0"2="1"3="2"4="3"5="4"6="5"7="6"8="7"9="8"10="9"30="A"78="+"40="'"48="B"14="BACKSPACE"43="#"46="C"58="CAPSLOCK"51=","32="D"83="."211="DELETE"181="/"208="DOWN"18="E"207="END"13="="1="ESCAPE"33="F"59="F1"60="F2"61="F3"62="F4"63="F5"64="F6"65="F7"66="F8"67="F9"68="F10"87="F11"88="F12"100="F13"101="F14"102="F15"34="G"41=""35="H"199="HOME"23="I"210="INSERT"36="J"37="K"38="L"26="["29="CTRL"203="LEFT"56="ALT"42="SHIFT"50="M"12="-"55="*"49="N"201="PAGEUP"209="PAGEDOWN"69="NUMLOCK"82="0"79="1"80="2"81="3"75="4"76="5"77="6"71="7"72="8"73="9"179=","156="ENTER"141="="24="O"25="P"52="."16="Q"19="R"27="]"157="CTRL"28="RETURN"205="RIGHT"184="ALT"54="SHIFT"31="S"39=";"53="/"86="\"57="SPACE"74="-"20="T"15="TAB"22="U"200="UP"47="V"17="W"45="X"21="Y"44="Z"`

Using the alt keys with windows messages requires trapping the WM_SYSKEY messages as well as WM_KEYDOWN/WM_KEYUP.

Internally, all DirectInput does is subclass your window and trap those messages for keyboard input.

Side note: always make sure to initialize DirectInput before Direct3D (if you're using D3D for your 2D stuff). If you init D3D first, it freaks out when DirectInput subclasses the window and Bad Things Happen. It was a bunch of weird window-related bugs that took me a long time to track down.

Cheers for the pointers Drillian. By sheer chance, I happened to initialise DirectInput before Direct3D, so that was lucky [smile].

See what you mean about the WM_SYSKEYDOWN and so on. Just been running some tests and that would have probably worked just as well.

The other reason for using DirectInput was that there aren't VK_WHATEVER codes defined for every key on the keyboard whereas DirectInput does appear to define DIK_WHATEVER for everything. I'm assuming these are different values to the virtual key codes I was using before. Perhaps I'm wrong.

Anyway, thanks again.

Windows doesn't have a VK_ for every key because characters and numbers are sent as their ascii value. This is actually why I don't like DirectInput (you have to convert everything by hand.)

I love this project lol. The demos are lots of fun. Keep up the good work!

Quote:
 Original post by Programmer16 Windows doesn't have a VK_ for every key because characters and numbers are sent as their ascii value. This is actually why I don't like DirectInput (you have to convert everything by hand.)

Right. Gotcha. Cheers.

I figure if I need to respond to ASCII keypresses I can still respond to WM_CHAR and WM_KEYUP and DOWN messages even though I'm using DirectInput.

Maybe I should just dump DirectInput. Dunno.

Quote:
Original post by EasilyConfused
Quote:
 Original post by Programmer16 Windows doesn't have a VK_ for every key because characters and numbers are sent as their ascii value. This is actually why I don't like DirectInput (you have to convert everything by hand.)

Right. Gotcha. Cheers.

I figure if I need to respond to ASCII keypresses I can still respond to WM_CHAR and WM_KEYUP and DOWN messages even though I'm using DirectInput.

Maybe I should just dump DirectInput. Dunno.

To be honest, you've got the system done and it's not a problem at the moment, so I'd keep it. Just my opinion though :).

However, IIRC once you enable DirectInput you can't receive Windows input messages anymore (without disabling DirectInput anyway.)

I still seem to be getting WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN and WM_SYSKEYUP messages even though DirectInput is enabled.

I'm using WM_SYSKEYDOWN to check for Alt-F4 to close the application and that still works.