Keyboard input handling changed from 4.1.18 to 4.2.0 ??
tobing

I've not posted for some time, but now I have started to put my Allegro game 'The Next Train' from 4.1.18 to 4.2.0, but now there's one little change of behavior I have observed: Keypresses are no longer immediately recognized and cannot be handled properly. This leads to missing key strokes or multiple keypresses if the key is held for a little while. It might be that there's something changed with the thread priorities internally? The application code is unchanged and it's the main loop of my 'Game Framework' project in the depot. Here it is:

1 while(true)
2 {
3 bool needsRefresh = false;
4 cur_skip = 0;
5 while( timer_counter > 0 || normal_fps==0 )
6 {
7 cur.advance_cputime -= perf_counter;
8 // handle user input
9 bool have_scrolled = false;
10 if( v_scroll_hndls.size() > 0 )
11 {
12 for( std::vector<ScrollingIfc*>::iterator it = v_scroll_hndls.begin(); it != v_scroll_hndls.end(); ++it )
13 {
14 have_scrolled = (*it)->handle_scroll() || have_scrolled;
15 }
16 }
17 if( ( !have_scrolled && keypressed() ) )
18 {
19 const int scan_code = readkey() >> 8;
20 if( key[KEY_ESC] )
21 {
22 sys_dialog.quit();
23 }
24 if( scan_code == KEY_F10 )
25 sys_dialog.ingame_dialog();
26 const int shift_flags = key_shifts & ( KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG );
27 for( std::vector<KbdHndlIfc*>::iterator it = v_kbd_hndls.begin(); it != v_kbd_hndls.end(); ++it )
28 {
29 (*it)->handle_kbd( scan_code, shift_flags );
30 }
31 }
32 
33 // Book keeping
34 ++cur.logic;
35 if( normal_fps > 0 )
36 --timer_counter;
37 ++cur_skip;
38 {
39 for( std::vector<GameClockIfc*>::iterator it = v_game_clock_hndls.begin(); it != v_game_clock_hndls.end(); ++it )
40 {
41 (*it)->advance_game_time();
42 }
43 }
44 cur.advance_cputime += perf_counter;
45 if( cur_skip >= max_skip )
46 {
47 timer_counter = 0;
48 break;
49 }
50 needsRefresh = true;
51 }
52 if( needsRefresh )
53 {
54 cur.display_cputime -= perf_counter;
55 // draw backbuffer
56 BITMAP*const draw_buffer = display_engine.draw_buffer();
57 display_engine.prepare_draw_buffer();
58 {
59 for( std::vector<ViewPortIfc*>::iterator it = v_viewports.begin(); it != v_viewports.end(); ++it )
60 {
61 (*it)->display( draw_buffer );
62 }
63 }
64 cur.display_cputime += perf_counter;
65 
66 // display backbuffer
67 needsRefresh = false;
68 cur.show_cputime -= perf_counter;
69 display_engine.display_draw_buffer();
70 cur.show_cputime += perf_counter;
71 cur.displayed++;
72 }
73 else
74 {
75 if( rest_dur_ms > 0 )
76 rest( rest_dur_ms );
77 }
78 cur.iteration++;
79 if( fps_counter > 0 )
80 {
81 displayed = cur;
82 displayed.perf_counter_ = perf_counter;
83 cur.logic = cur.iteration = cur.displayed = 0;
84 cur.advance_cputime = cur.display_cputime = cur.show_cputime = 0;
85 fps_counter = 0;
86 perf_counter = 0;
87 }
88 }

Evert

What platform?

As an aside, mixing key[] and keypressed()/readkey() like that is a bit ugly, and not really how they're meant to be used...

tobing

Windows XP Home SP2, and I'm using the MSVC 2003.NET compiler.

Edit: I have changed that to

        if( scan_code == KEY_ESC )

but there's no change of behavior.

Also, I had added alfont 1.9.1, masking 0.80 and lua 5.1.1 to the new version, but didn't use them yet. So I removed the linkage dependencies, again without change of behavior.

Edit: Now I have only linked my object files with allegro 4.1.18 import libraries versus allegro 4.2.0 import libraries. Behavior is OK for 4.1.18, but sluggy as described above with 4.2.0. Debugging didn't show me any differences so far...

Third and last Edit: Got it. My fault...

Some time ago I had requested a change to one structure inside allegro, which was rejected because it can be done using allegro as it is. The problem then was, I couldn't do it that way, so I implemented that change into my 4.1.18. Fine, now as I put the same change into 4.2.0 I didn't make it complete, so that was the reason. Sorry.

Ah, Evert, at this place I could avoid using the key[]-array, but not at another place: Scrolling. I want the program to scroll in 8 directions, using the cursor keys, so pressing two of them at the same time and hold them pressed should move the viewport in the desired direction. This will not work with readkey(), or will it?

Audric

readkey() gets the benefits of "key repetition", but only for one key. That's what the low-level stuff provides directly.

If you want a behavior of :
- delay before key repeat: 500 ms
- interval of repetition: 100 ms
for several keys at once, you need to use the key[] array, and for each important key: keep track of how long it has been kept pressed to trigger the "repeat" event appropriately.

Thread #587629. Printed from Allegro.cc