public override void Update(GameTime gameTime) { base.Update(gameTime); // Get current keystroke and check if this is a new keystroke or // if it is a repeated one. KeyboardState state = Keyboard.GetState(); VirtualKeyValue[] keystroke = keyboardLayout.ProcessKeys(state); Keys[] filteredStroke = keyboardLayout.FilteredPressedKeys; bool isNewStroke = true; if (previousStroke != null) { // Check scan codes to handle modifier+char to char transitions. // If two or more keys are pressed, the last one is used and when // this key is released, no keystroke is generated. int newKeyIndex = -1; int i; int j = 0; for (i = 0; i < filteredStroke.Length; i++) { // KeyboardLayout.FilteredPressedKeys is sorted while (j < previousStroke.Length && previousStroke[j] < filteredStroke[i]) { j++; } if (j >= previousStroke.Length) { newKeyIndex = i; break; } else if (previousStroke[j] > filteredStroke[i]) { newKeyIndex = i; } } if (newKeyIndex > -1) { isNewStroke = currentKeyValue != keystroke[newKeyIndex]; currentKeyValue = keystroke[newKeyIndex]; } else { isNewStroke = false; if (keystroke.Length == 0) { currentKeyValue = VirtualKeyValue.Empty; } } } for (int i = 0; i < keyStates.Length; i++) { keyStates[i] = KeyStateFlags.Up; } // If the keystroke is a new stroke, reset start time and update // key state flags to notify that the key was just released if (isNewStroke == true) { strokeStartTime = gameTime.TotalGameTime.TotalMilliseconds; repeatTimeCount = -1; if (previousStroke != null) { foreach (Keys key in previousStroke) { keyStates[(int)key] = KeyStateFlags.Released; } } } // Apply delay and repeat-speed to stroke age double dt = gameTime.TotalGameTime.TotalMilliseconds - strokeStartTime; bool doSetString = false; KeyStateFlags newKeyStateFlags = KeyStateFlags.Down; if (dt <= float.Epsilon) { // First stroke doSetString = true; } else if (repeatTimeCount == -1 && delayTime - dt < float.Epsilon) { // Repeat delay time reached doSetString = true; repeatTimeCount = 0; newKeyStateFlags |= KeyStateFlags.Repeat; } else if (repeatTimeCount > -1) { dt -= delayTime; // Count stroke repeats int i; for (i = 0; dt > 0; i++) { dt -= repeatTime; } if (i > repeatTimeCount) { doSetString = true; repeatTimeCount++; } newKeyStateFlags |= KeyStateFlags.Repeat; } // Build the current key strokes output characters = ""; if (doSetString == true && keystroke.Length > 0) { VirtualKeyValue keyValue = currentKeyValue; if (deadKey != null) { char baseChar = keyValue.Characters[0]; if (deadKey.ContainsBaseCharacter(baseChar) == true) { characters = deadKey.GetCombinedCharacter(baseChar).ToString(); } else { characters = String.Format("{0}{1}", deadKey.DeadCharacter, baseChar); } deadKey = null; } else if (keyValue.IsDeadKey == true) { keyboardLayout.DeadKeys.TryGetValue(keyValue.Characters[0], out deadKey); } else if (keyValue.Characters != null && Char.IsControl(keyValue.Characters, 0) == false) { // Add non-control characters only characters = keyValue.Characters; } } if (doSetString == true && filteredStroke.Length > 0) { // Update key state flags foreach (Keys key in filteredStroke) { keyStates[(int)key] = newKeyStateFlags; } } previousStroke = filteredStroke; }