Legacy GM Keyboard layout key definitions for customized controls

GM Version: ALL
Target Platform: ANY
Download: No download required

Summary:
This is how to put all your keyboard layout keys in one array and retrieve them after for customized user controls in your game.

Tutorial:
I wanted to give this piece of code for anyone wanting to have something fast to customize the controls and show them in your game. Please note that the keyboard layout is set for ENGLISH US. If some keys do not fit with the character's in the array, simply change the character string. There's way too many languages out their to sum it all out in one small array.

This piece of code is better placed in the create even of a controller that loads before anything else. It create's a global variable called "asc_def" defining every ascii code for each button on your keyboard. Even if this is said in the comments of the script, I'll mention it again, this won't give you the different 255 ascii codes but only tell you which key on the keyboard was pressed. I hope this will save the time for many other people.

Code:
// This script sets the names of the ascii values of the keyboard keys
// You can use this table to ask for controls or to show which controls do what.
// Good for customized user controls configuration

// NOTE: This will NOT tell you if a letter is lower case or not
//       It simply telles you which BUTTON on the keyboard is used.

global.asc_def[255] = "Undefined"; // Initialise array of key definitions

// Build key definitions table
for (var i=255;i>=0;i--)
  {
  global.asc_def[i] = "Undefined";
  }

// In GM, the controls are set to the keyboard keys and NOT
// every possible character. Below is the list of all the possible
// keycodes usually used with the built-in GM variable vk_ or ord()...
// Some characters, depending on your language, may vary. Simply
// modify the string in the table below to your needs. Default keyboard
// layout used is "English - US".

// Set known characters.
global.asc_def[8] = "Backspace";
global.asc_def[9] = "Tab";
global.asc_def[12] = "Numpad 5 (nmlk off)";
global.asc_def[13] = "Enter";
global.asc_def[19] = "Pause";
global.asc_def[20] = "Caps lock";
global.asc_def[27] = "Escape";
global.asc_def[32] = "Space";
global.asc_def[33] = "Page up";
global.asc_def[34] = "Page down";
global.asc_def[35] = "End";
global.asc_def[36] = "Home";
global.asc_def[37] = "Left";
global.asc_def[38] = "Up";
global.asc_def[39] = "Right";
global.asc_def[40] = "Down";
global.asc_def[45] = "Insert";
global.asc_def[46] = "Delete";
global.asc_def[48] = "0";
global.asc_def[49] = "1";
global.asc_def[50] = "2";
global.asc_def[51] = "3";
global.asc_def[52] = "4";
global.asc_def[53] = "5";
global.asc_def[54] = "6";
global.asc_def[55] = "7";
global.asc_def[56] = "8";
global.asc_def[57] = "9";
global.asc_def[65] = "A";
global.asc_def[66] = "B";
global.asc_def[67] = "C";
global.asc_def[68] = "D";
global.asc_def[69] = "E";
global.asc_def[70] = "F";
global.asc_def[71] = "G";
global.asc_def[72] = "H";
global.asc_def[73] = "I";
global.asc_def[74] = "J";
global.asc_def[75] = "K";
global.asc_def[76] = "L";
global.asc_def[77] = "M";
global.asc_def[78] = "N";
global.asc_def[79] = "O";
global.asc_def[80] = "P";
global.asc_def[81] = "Q";
global.asc_def[82] = "R";
global.asc_def[83] = "S";
global.asc_def[84] = "T";
global.asc_def[85] = "U";
global.asc_def[86] = "V";
global.asc_def[87] = "W";
global.asc_def[88] = "X";
global.asc_def[89] = "Y";
global.asc_def[90] = "Z";
global.asc_def[91] = "Windows";
global.asc_def[96] = "Numpad 0";
global.asc_def[97] = "Numpad 1";
global.asc_def[98] = "Numpad 2";
global.asc_def[99] = "Numpad 3";
global.asc_def[100] = "Numpad 4";
global.asc_def[101] = "Numpad 5";
global.asc_def[102] = "Numpad 6";
global.asc_def[103] = "Numpad 7";
global.asc_def[104] = "Numpad 8";
global.asc_def[105] = "Numpad 9";
global.asc_def[106] = "Numpad *";
global.asc_def[107] = "Numpad +";
global.asc_def[109] = "Numpad -";
global.asc_def[110] = "Numpad .";
global.asc_def[111] = "Numpad /";
global.asc_def[112] = "F1";
global.asc_def[113] = "F2";
global.asc_def[114] = "F3";
global.asc_def[115] = "F4";
global.asc_def[116] = "F5";
global.asc_def[117] = "F6";
global.asc_def[118] = "F7";
global.asc_def[119] = "F8";
global.asc_def[120] = "F9";
global.asc_def[121] = "F10";
global.asc_def[122] = "F11";
global.asc_def[123] = "F12";
global.asc_def[144] = "Num lock";
global.asc_def[145] = "Scroll lock";
global.asc_def[160] = "Shift (left)";
global.asc_def[161] = "Shift (right)";
global.asc_def[162] = "Ctrl (left)";
global.asc_def[163] = "Ctrl (right)";
global.asc_def[164] = "Alt (left)";
global.asc_def[165] = "Alt (right)";
global.asc_def[186] = ";";
global.asc_def[187] = "=";
global.asc_def[188] = ",";
global.asc_def[189] = "-";
global.asc_def[190] = ".";
global.asc_def[191] = "?";
global.asc_def[192] = "~";
global.asc_def[219] = "[";
global.asc_def[220] = "\";
global.asc_def[221] = "]";
global.asc_def[222] = "'";
 
Last edited:

RangerX

Member
Nice stuff. I made one for my game which covers English and French. (my game is billingual)
Do you have an "any key" on this? Could be an idea if you didn't.
 
This script is to assign strings to keyboard buttons. There is no button on a keyboard called "any key". If you have such a need simply check if keycode > 0 and output your string as "any key". As for multiple languages, GM can only handle 2 dimensional arrays so for each global.asc_def, you would have a second dimension [#,0] for a language and [x,1] for another one. In your case RangerX:

global.asc_def[13,0] = "Enter";
global.asc_def[13,1] = "Entré";

Or else, simply hav a translator that checks the language and translates every string from english to french. For example a script that would be a bit like this (may not be exact for GML but you can understand where it's going:

key_def = global.asc_def(keycode);
if (language="fr") {key_def = scr_translate(key_def,"fr")}

Thanks for your comment and your thoughts are well taken into account, I could add more to the code in the futur!
 
R

RealsLife

Guest
Why are these

global.asc_def[186] = ";";
global.asc_def[187] = "=";
global.asc_def[188] = ",";
global.asc_def[189] = "-";
global.asc_def[190] = ".";
global.asc_def[191] = "?";
global.asc_def[192] = "~";
global.asc_def[219] = "[";
global.asc_def[220] = "\";
global.asc_def[221] = "]";
global.asc_def[222] = "'";

and even other numbers you wrote not the same value as the ascii table in game maker studio helpfiles?

I don't understand anything about ascii anymore...

I though that it was you push a button -> ascii code -> show ascii code character on screen.

Also your keys work but the only that are not working for me are the more special characters as ^$µù=[]? Can someone explain?
 
Why are these

global.asc_def[186] = ";";
global.asc_def[187] = "=";
global.asc_def[188] = ",";
global.asc_def[189] = "-";
global.asc_def[190] = ".";
global.asc_def[191] = "?";
global.asc_def[192] = "~";
global.asc_def[219] = "[";
global.asc_def[220] = "\";
global.asc_def[221] = "]";
global.asc_def[222] = "'";

and even other numbers you wrote not the same value as the ascii table in game maker studio helpfiles?

I don't understand anything about ascii anymore...

I though that it was you push a button -> ascii code -> show ascii code character on screen.

Also your keys work but the only that are not working for me are the more special characters as ^$µù=[]? Can someone explain?
As I mentionned. This only tells you which BUTTON on the keyboard was pressed and not which character was typed.

As for the special keys, I noted that the layout was entered as a US English keyboard. If you need it for another language, you will need to modify the strings in the array to your needs.
 
A small error slipped in the code where the insert and delete keys were mapped to the same keycode. I changed it in the code in the first post. Thank to @Energy Engine for submitting this issue.
 
How do i exactly implement this and use it?
This piece of code is better placed in the create even of a controller that loads before anything else. It create's a global variable called "asc_def" defining every ascii code for each button on your keyboard
After, on each KeyPress event, you retrieve the vaue to print on the player's screen using global.asc_def[ascii_code_pressed];
Of course, this is for GM 1.4. As for GM 2.0, I cannot confirm it still works the same way.
 
After, on each KeyPress event, you retrieve the vaue to print on the player's screen using global.asc_def[ascii_code_pressed];
Of course, this is for GM 1.4. As for GM 2.0, I cannot confirm it still works the same way.
Do you maybe have an example file I could see? I just can't get it to wrap around my head properly with my current setup :confused:
 
Do you maybe have an example file I could see? I just can't get it to wrap around my head properly with my current setup :confused:
Unfortunately I did not use GM for a while and I am really busy in preparing for a trip so I cannot give you a solid GM 1.4 example. I'm sorry :( . But I remember this code perfectly.

This code is a simple array that you call in a global object. That is an object you will load before all the others in a room. So you paste this script in the creation event of this object, usually, it's in a controller object. Once this script has been loaded, the global.asc_def array is available for all objects in the game.

This permits a developper to create a customized player input room. For example, permit the player to change the controls in their game for other keys than those you chose. When they press a keyboard key, you simply retrieve the information in the global.asc_def array which is in string format. And you can draw that text on the screen to show the user which key he/she pressed.

This script is a really simple array. It does not do anything else than store 255 different strings in memory to let us have access to a string representation of a keycode. GM 1.4 treats keycodes differently than ascii codes. Keycodes represent the physical button pressed as for ascii codes represent the actual character types. So to say things clearer, if you keep caps lock on and type the letter "A" and then turn caps off and type "a", my array will always return "A" because it's the physical "A" key on the keyboard that was pressed. It permits us to use keycodes and actually see the right key in string format that was pressed.

You would simply add a keyboard event or do a keyboard_keydown() call and return the given keycode in a string variable that will be used to show onscreen what was just pressed. It's good for debugging and for player custom controls rooms. I hope this answer your question a bit :)
 
After, on each KeyPress event, you retrieve the vaue to print on the player's screen using global.asc_def[ascii_code_pressed];
Of course, this is for GM 1.4. As for GM 2.0, I cannot confirm it still works the same way.
Actually never mind! I figured it all out. I've been working for too long and forgot how everything runs... Anyways, thanks for your help!
 
Unfortunately I did not use GM for a while and I am really busy in preparing for a trip so I cannot give you a solid GM 1.4 example. I'm sorry :( . But I remember this code perfectly.

This code is a simple array that you call in a global object. That is an object you will load before all the others in a room. So you paste this script in the creation event of this object, usually, it's in a controller object. Once this script has been loaded, the global.asc_def array is available for all objects in the game.

This permits a developper to create a customized player input room. For example, permit the player to change the controls in their game for other keys than those you chose. When they press a keyboard key, you simply retrieve the information in the global.asc_def array which is in string format. And you can draw that text on the screen to show the user which key he/she pressed.

This script is a really simple array. It does not do anything else than store 255 different strings in memory to let us have access to a string representation of a keycode. GM 1.4 treats keycodes differently than ascii codes. Keycodes represent the physical button pressed as for ascii codes represent the actual character types. So to say things clearer, if you keep caps lock on and type the letter "A" and then turn caps off and type "a", my array will always return "A" because it's the physical "A" key on the keyboard that was pressed. It permits us to use keycodes and actually see the right key in string format that was pressed.

You would simply add a keyboard event or do a keyboard_keydown() call and return the given keycode in a string variable that will be used to show onscreen what was just pressed. It's good for debugging and for player custom controls rooms. I hope this answer your question a bit :)
I really appreciate your explanation, It was just me being a fool not actually realizing what I was doing :oops:
 

Neraxa

Member
Hey you guys! I know this is an 'older' post, but I was hoping you could help me out. I am pretty 101 in the whole keybindings / settings thing, so this is very new territory haha

I have implemented the code you made in the create event of my controller object - the object that initializes the whole thing.
But when i tried using it in the code, it was like all the buttons you can press in the game all continulously activated at once like in a step event, and if i press the key matching for example the attack button, the player stops attacking. So its like its reversed.

This is the code i got:




-----

Here is the code that is initialized in the create event, in the same controller object, after your code is run:


Code:
global.keyMoveRight = global.asc_def[68];

global.keyMoveLeft = global.asc_def[65];

global.keyJump = global.asc_def[87];

global.keyConsumable1 = global.asc_def[81];

global.keyConsumable2 = global.asc_def[82];

global.keyAttack = global.asc_def[32];


The idea is that i take the values from your code and store it in the global variables so I can save the information. Though this stores the string assigned to the array variables, so I'm not sure if it takes the number/key value itself.

-----


-----

Next I use the global variables I have made in the Player objects step event to make a Melee Attack:



GML:
if global.keyAttack > 46 && global.keyAttack < 91 && keyboard_check(ord(global.keyAttack)) {

scr_MeleeAttack1()

} else {

if keyboard_check(global.keyAttack) {

scr_MeleeAttack1()

}

}

I chose to make it an if else statement because of 'ord'. keyboard_check(ord can only be used for numbers and letters, while keyboard_check has to be used for all other kinds of buttons (at least in my understanding).
I can see an issue here with my code however, as I check for key values when saying "global.keyAttack > 46 %% global.keyAttack < 91", while the value in global.keyAttack is actually a string.
Though I dont know how else to make it.

-----




I feel like I have completely misunderstood something and cant wrap my head around how to make this work.
So uhm, yeah I would love you guys' help haha

Big thanks in advance!
 
global.asc_def is an array. So checking for the contents of the array will simply give you a readable string to show onscreen for the player and not the actual needed code for your keyboard input.

This means that setting this:
GML:
global.keyAttack = global.asc_def[32];
is wrong. You need to do it THIS way:
GML:
global.keyAttack = 32;
You absolutely need to assign an integer to your key. THEN, on a configuration screen, you can draw text like this:
GML:
draw_text(x,y,"Attack key: "+global.asc_def[global.keyAttack]);
Your code in the step event should be as simple as this:
GML:
if (keyboard_check(global.keyAttack) {
  scr_MeleeAttack1()
}
My code simply permits you to display the key name if you need that type of function in your game. And since the work of writting all key names is laborious and teadious, I simply supplied the array containing it all so you do not need to type it all yourself. GMS does not permit to have a description of a key pressed, it only supplies the functions to read the key code so displaying to the player that the "Attack key is 32" means nothing while as displaying "Attack key is Space" makes much more sence. Once could also think that supplying the string version of the keycode could work, when you press "Space", "Control", "Alt" and other function keys, that would simply display nothing as a string and therefor makes it useless. That's why I supplied this array so you do not have to go through that task of finding out which keycode is what.

So your mistake in your code is that you assign a text value to the key rather than assigning it the keycode. I hope this helps.
 

Neraxa

Member
I can't thank you enough for helping me out! I made the changes and it works flawlessly! I have spent a long time trying to figure this out, so I am really happy haha. Thank you so much again!
 
Top