New KOS Keyboard driver. Testing needed.

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
Post Reply
User avatar
Quzar
Dream Coder
Dream Coder
Posts: 7497
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Wed Jul 31, 2002 12:14 am
Location: Miami, FL
Has thanked: 4 times
Been thanked: 9 times
Contact:

New KOS Keyboard driver. Testing needed.

Post by Quzar »

Last November I started (and finished ...ish) working on a revamped keyboard driver for KOS. I was motivated to do this by a message and patch left on the KOS sourceforge page by Alex Nesemann. He had wanted to add key-repeating functionality to the KOS keyboard driver so that it would behave more like standard PC keyboards do in a text editor. Having never looked at the keyboard driver in any depth I decided to check it out and found it to be extremely inefficient and lacking in features. Here is what I changed:

* Rewrote the algorithm for matching keypresses and debounced keys. Previously it was scanning through a 256 entry list of all possible keys and updating newly pressed vs previously pressed and unpressed keys. Now it keeps the previous key state read from the keyboard, and works on that. It saves about 250B per kb state struct, and is uses somewhere around 10% the time of the old method.
* Added individual queues for each keyboard. There is still a global queue as in the original driver, but now there are also per-keyboard queues so that you can use the queuing system with multiple keyboards at once (as opposed to having to write your own parser).
* keyboard queues may now be turned off by a compile-time define. This would reduce overhead, if they are not being used. (for instance if the keyboard is being used as if a controller)
* Added key repeat
* Fully doxygen'd header.

The problem is that I don't have my DC dev setup running and would also really prefer not to write up a full test program for this thing. I'm sure in the next few months I'd be able to, but I've been sitting on this long enough, so if anyone can give it a look or (even better) a test please do.

This will break anything that used the keyboard via directly accessing the key matrix. Though anything that was doing that probably shouldn't have been.
Attachments
keys.zip
replaces kos/arch/dreamcast/hardware/maple/keyboard.c and kos/arch/dreamcast/include/dc/maple/keyboard.h
(5.55 KiB) Downloaded 84 times
"When you post fewer lines of text than your signature, consider not posting at all." - A Wise Man
Chilly Willy
DC Developer
DC Developer
Posts: 414
Joined: Thu Aug 20, 2009 11:00 am
Has thanked: 0
Been thanked: 2 times

Re: New KOS Keyboard driver. Testing needed.

Post by Chilly Willy »

Quzar wrote:This will break anything that used the keyboard via directly accessing the key matrix. Though anything that was doing that probably shouldn't have been.
You mean like this?

Code: Select all

    // handle regular keys
    for (i=4; i<0x65; i++)
    {
        if (kstate->matrix[i] != 0 && prev_matrix[i] == 0 && key_table[i] != 0)
        {
            event.type = ev_keydown;
            event.data1 = key_table[i];
            D_PostEvent (&event);
        }
        else if (kstate->matrix[i] == 0 && prev_matrix[i] != 0 && key_table[i] != 0)
        {
            event.type = ev_keyup;
            event.data1 = key_table[i];
            D_PostEvent (&event);
        }
    }
    memcpy(prev_matrix, kstate->matrix, 128);
It was really the only way to handle keys in the old code. I'll look if this new code to see if it's suitable.

EDIT: Let's take a look... can't turn off key repeats, and no key up events. Nope! Still not suitable for games. Guess we're still stuck using the matrix. :cry:
User avatar
Quzar
Dream Coder
Dream Coder
Posts: 7497
Joined: Wed Jul 31, 2002 12:14 am
Location: Miami, FL
Has thanked: 4 times
Been thanked: 9 times
Contact:

Re: New KOS Keyboard driver. Testing needed.

Post by Quzar »

You can get key up by taking the difference between the current and last pressed key states. To me this seems just as good as scanning through a matrix (with MUCH less work on the backend). Any key that is not in the set of currently pressed keys is now 'up' as opposed to having to search for every key to see its state. I can see how systems based around a key matrix would not be geared towards that though. Here's how I would rewrite your code above for the new system:

Code: Select all


/* First check for new keys. */
for (i=0; i<MAX_KEYS_PRESSED; i++)
{
	for (j=0; j<MAX_KEYS_PRESSED; j++)
	{
		/* If the key was pressed last cycle and this one, move to the next  */
		if(kstate->last_keys[j] == kstate->cond->keys[i]) break;
	}
	/* If we went through the whole thing, then that means keys[i] is a newly pressed key.  */
	if((j==MAX_KEYS_PRESSED) && (kstate->cond->keys[i] >= 4) (kstate->cond->keys[i] <= 0x65))
	{
	    event.type = ev_keydown;
	    event.data1 = key_table[kstate->cond->keys[i]];
	    D_PostEvent (&event);
	}
}

/* Then check for old keys */
for (i=0; i<MAX_KEYS_PRESSED; i++)
{
	for (j=0; j<MAX_KEYS_PRESSED; j++)
	{
		/* If the key was pressed last cycle and this one, move to the next  */
		if(kstate->last_keys[i] == kstate->cond->keys[j]) break;
	}
	/* If we went through the whole thing, then that means keys[i] is a newly unpressed key.  */
	if((j==MAX_KEYS_PRESSED) && (kstate->last_keys[i] >= 4) (kstate->last_keys[i] <= 0x65))
	{
	    event.type = ev_keyup;
	    event.data1 = key_table[kstate->last_keys[i]];
	    D_PostEvent (&event);
	}
}
I'm sure there are many many ways in which this could be optimized, and it looks like more work, but in total it should be significantly less because MAX_KEYS_PRESSED is hardware limited to 6 and we don't have any need for that memcpy at the end. Not only that, but there is no driver-level processing of that whole key matrix either.

Without any of the changes I made to the driver, you could still use the above code by simply keeping track of your own 'last_keys', the same way you keep track of prev_matrix.

In fact though, I'm not sure why you were keeping a prev_matrix, because the kstate->matrix worked by using 2 for down, 1 for 'up' and 0 for not pressed (recently), so with the driver as is you could have been doing this (unless I'm totally misunderstanding the way your code works):

Code: Select all

    // handle regular keys
    for (i=4; i<0x65; i++)
    {
        /* If this is zero, we're not even processing that key */ 
        if(key_table[i] ==0) continue;

        if (kstate->matrix[i] == 2)
        {
            event.type = ev_keydown;
            event.data1 = key_table[i];
            D_PostEvent (&event);
        }
        else if (kstate->matrix[i] == 1)
        {
            event.type = ev_keyup;
            event.data1 = key_table[i];
            D_PostEvent (&event);
        }
    }    
The biggest potential problem I see with the above is if the polling of the keys is out of sync with how they change, you could quite easily miss key_up triggers whereas by keeping track of the last thing the user code saw, you guarantee only missing entire keypresses and not having random unmatched down/up pairs (so instead of using the driver-provided last_keys in my first example, you'd just track your own).

Thank you for your input. If you have the time, please take another look at both the current code and my modified version. It seems what you were looking at was the key queue system, which isn't very different at all from the old way. Key repeats only impact what is going into the queue. What is different is that there is simply no longer the transformation process from the 'keys' array of currently pressed keys into the matrix.
"When you post fewer lines of text than your signature, consider not posting at all." - A Wise Man
Chilly Willy
DC Developer
DC Developer
Posts: 414
Joined: Thu Aug 20, 2009 11:00 am
Has thanked: 0
Been thanked: 2 times

Re: New KOS Keyboard driver. Testing needed.

Post by Chilly Willy »

Ah - 2 vs 1 vs 0 wasn't explained very well... probably because it was an internal part of the driver and shouldn't be relied on. Yes, I do see how tracking the events would mean less work, but that still leaves us with key repeats. Every game I've seen source to that works with a keyboard turns off the key repeat as part of the startup. I actually don't see why key repeat has ever been kept around - except for cursor keys and the backspace in a text editor/word processor, it's a useless feature that causes more problems than it's worth. Any keyboard driver NEEDS a way to turn it off. In the case of a console, I'd have OFF be the default state.

EDIT: Also, you NEED key up events. If your game doesn't need key ups, you just ignore them; but if your game needs them, you have to jump through hoops to simulate them. That's what my code is doing - checking the matrix to see when a code is no longer down, then sending the simulated key up event.
User avatar
Quzar
Dream Coder
Dream Coder
Posts: 7497
Joined: Wed Jul 31, 2002 12:14 am
Location: Miami, FL
Has thanked: 4 times
Been thanked: 9 times
Contact:

Re: New KOS Keyboard driver. Testing needed.

Post by Quzar »

Chilly Willy wrote:Ah - 2 vs 1 vs 0 wasn't explained very well... probably because it was an internal part of the driver and shouldn't be relied on. Yes, I do see how tracking the events would mean less work, but that still leaves us with key repeats. Every game I've seen source to that works with a keyboard turns off the key repeat as part of the startup. I actually don't see why key repeat has ever been kept around - except for cursor keys and the backspace in a text editor/word processor, it's a useless feature that causes more problems than it's worth. Any keyboard driver NEEDS a way to turn it off. In the case of a console, I'd have OFF be the default state.

EDIT: Also, you NEED key up events. If your game doesn't need key ups, you just ignore them; but if your game needs them, you have to jump through hoops to simulate them. That's what my code is doing - checking the matrix to see when a code is no longer down, then sending the simulated key up event.
Well, either way the DC input system doesn't quite work by generating events (at least in the user-facing side). All it does is internally updates the current state and relies on the user to do the rest.

I understand what you mean about key repeat, and I'll certainly add in accessors functions for it, but again it only works on the key queues which are pretty much useless for games and are completely separate from the keys and last_keys arrays. Those are the current state and last state of the keyboard's list of pressed keys.

Once again, key repeat does *not* impact state->cond->keys nor state->last_keys. The layout of the driver was as follows:

raw from KB HW____|_____________|useful for games|_____________|useful for text input
state->cond->keys |transformed into| state->matrix |transformed into| state->queue

It is now:

raw from KB HW ___| _______|useful for games_| key repeat is here______|useful for text input
state->cond->keys |saved as| state->last_keys|optionally transformed into|state->queue

The basic idea of most of my rewrite is that the keyboard already delivers raw data to KOS in a very easily consumable format, one that would be extremely simple to use for games without key up events (and no more difficult than the matrix system for those without) so why have all this extra processing just to deliver an arbitrarily imposed data structure to the user?

Does the code I posted for a matrix-less setup using my new driver make sense?

Thank you again for your input (no pun intended?). This is something I've been missing.
"When you post fewer lines of text than your signature, consider not posting at all." - A Wise Man
Chilly Willy
DC Developer
DC Developer
Posts: 414
Joined: Thu Aug 20, 2009 11:00 am
Has thanked: 0
Been thanked: 2 times

Re: New KOS Keyboard driver. Testing needed.

Post by Chilly Willy »

Quzar wrote: The basic idea of most of my rewrite is that the keyboard already delivers raw data to KOS in a very easily consumable format, one that would be extremely simple to use for games without key up events (and no more difficult than the matrix system for those without) so why have all this extra processing just to deliver an arbitrarily imposed data structure to the user?

Does the code I posted for a matrix-less setup using my new driver make sense?
Yes, you have some errors in it, but I do see what you were doing there. It's certainly less work - I'll have to try to incorporate that in the game and see how it works.

Thank you again for your input (no pun intended?). This is something I've been missing.
I think most folks just use the controller. It IS a console after all - who would use a keyboard or mouse? :wink: :lol:

Fortunately, I picked up both the keyboard and mouse as I know many people prefer them for FPS controls over a pad. Anyone working on a FPS on a console that has a keyboard or mouse available NEEDS to support them... or put up with a lot of complaints.
User avatar
Anthony817
Insane DCEmu
Insane DCEmu
Posts: 132
Joined: Wed Mar 10, 2010 1:29 am
Location: Fort Worth, Texas
Has thanked: 12 times
Been thanked: 4 times

Re: New KOS Keyboard driver. Testing needed.

Post by Anthony817 »

I just bought myself a new mouse and keyboard when I bought my SD Adapter and card. I figured I might as well get them as I was a big PC gamer and love my FPS games with mouse, and what better way to make use of all the old PC emulators like the Amiga and the Atari ST?

Chilly, Hypertension will also have mouse and KB support as well right?
User avatar
Quzar
Dream Coder
Dream Coder
Posts: 7497
Joined: Wed Jul 31, 2002 12:14 am
Location: Miami, FL
Has thanked: 4 times
Been thanked: 9 times
Contact:

Re: New KOS Keyboard driver. Testing needed.

Post by Quzar »

Chilly Willy wrote:
Quzar wrote: The basic idea of most of my rewrite is that the keyboard already delivers raw data to KOS in a very easily consumable format, one that would be extremely simple to use for games without key up events (and no more difficult than the matrix system for those without) so why have all this extra processing just to deliver an arbitrarily imposed data structure to the user?

Does the code I posted for a matrix-less setup using my new driver make sense?
Yes, you have some errors in it, but I do see what you were doing there. It's certainly less work - I'll have to try to incorporate that in the game and see how it works.
I figured I had plenty of errors, but you get the gist :) . I look forward to a real-world example to test it with.
Thank you again for your input (no pun intended?). This is something I've been missing.
I think most folks just use the controller. It IS a console after all - who would use a keyboard or mouse? :wink: :lol:

Fortunately, I picked up both the keyboard and mouse as I know many people prefer them for FPS controls over a pad. Anyone working on a FPS on a console that has a keyboard or mouse available NEEDS to support them... or put up with a lot of complaints.


Oh, for 'missing' I meant outside input on my code. I figure the underused nature of it (along with the fact that it worked) is why the keyboard driver was in such poor shape. Like Anthony said, this should also be good for old PC system emulators. I'll need to modify SDL though to work with this new driver.
"When you post fewer lines of text than your signature, consider not posting at all." - A Wise Man
Chilly Willy
DC Developer
DC Developer
Posts: 414
Joined: Thu Aug 20, 2009 11:00 am
Has thanked: 0
Been thanked: 2 times

Re: New KOS Keyboard driver. Testing needed.

Post by Chilly Willy »

Anthony817 wrote:I just bought myself a new mouse and keyboard when I bought my SD Adapter and card. I figured I might as well get them as I was a big PC gamer and love my FPS games with mouse, and what better way to make use of all the old PC emulators like the Amiga and the Atari ST?
Or even Atari 8-bit and C64 emulators. There are many good reasons to get a mouse and keyboard. :grin:

Chilly, Hypertension will also have mouse and KB support as well right?
Of course! It would be silly not to have it... go to all the trouble of having a great FPS and then only use a pad? :oops:

Quzar wrote:I figured I had plenty of errors, but you get the gist :) . I look forward to a real-world example to test it with.
Yeah... I guess one more "final" update to my older Doom code, and that's final! :lol:
Post Reply