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"
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.