Jump to content


[C++] switch(), ncurses and arrow keys causing odd behaviour


2 replies to this topic

#1 Hertta

    Member

  • Members
  • PipPip
  • 81 posts

Posted 30 December 2009 - 03:50 AM

EDIT: Got it solved! Solution at the end of the post.

Well, I am working on a roguelike game in which I stumbled upon some odd behaviour from ncurses' side.

Given the following code:
#include <ncurses.h>
#include <string>
#include <sstream>

bool running;
void handle_keyboard();

int main() {
    std::stringstream ss;
    std::string msg;
    initscr();
    raw();
    noecho();
    curs_set(0);
    int loop_no=0;
    running=true;
    while(running) {
    
        handle_keyboard();
        clear;
        ss << "Loop no. " << loop_no;
        msg = ss.str();
        mvprintw(1,1, msg.c_str());
        ss.str("");
        loop_no++;
    
    }
    endwin();
    return 0;

}

void handle_keyboard() {

    static char ch;
    ch = getch();
    switch(ch) {
        case 'q':
            running = false;
            break;
        default:
            break;
    }

}


the problem happens when I press arrow keys(Edit: also includes F1-F12 keys, pg up, pg down, end, home etc. keys). What happens, is that it seems as if the getch() function does not stop the execution for the 4 cycles to come. As in, the next 2 getch() functions do nothing. They are skipped. Which results in "skipped" cycles in the main loop.

The output is something like this:
if using other than arrow keys:
Loop no. 1
Loop no. 2
Loop no. 3
... etc

if using arrow keys:
loop no. 2
loop no. 5
loop no. 8
loop no. 11
loop no. 14
...

I have no clue(Might be related to enabling keypad with keypad() function though, no luck with trial-and-error so far.) why this happens. I have no proper workarounds how to prevent this. (Calling getch() twice after the 'bug' happens does fix it partly, however it adds two key stroke 'delay' to any key presses, so it's not a viable workaround.)

Tested on Linux(ArchLinux with 2.6.31 kernel) with gcc(4.4.2) and ncruses 5.7.20081102.

Any thoughts?

--
Solved it. Solution was to enable keypad after calling initscr(). I tried to do it with "keypad(0, true);", but I had to use "keypad(stdscr, true);" instead. Now it works great.

#2 fireside

    Senior Member

  • Members
  • PipPipPipPip
  • 1589 posts

Posted 30 December 2009 - 05:51 AM

I've never used ncurses, but aren't you printing to the same screen location every time? Aren't those numbers in front of the mvprint argument the screen location? It seems like the output would keep overlapping and you appear to be clearing the screen each time. How can you get the information you describe? But if it is, I would think you would need a debugger and some stops to tell what's going on.

Oh, just noticed the solved it.
Currently using Blender and Unity.

#3 Hertta

    Member

  • Members
  • PipPip
  • 81 posts

Posted 30 December 2009 - 02:44 PM

Actually you're right. I didn't notice it in my test case. However as long as it prints on top of the old text there's no problem with it. :)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users