Hoofdcategorieën
Topicacties

C / UNIX realtime key-press detectie

Pagina: 1

Reageer Nieuw Topic
Berichten: 52
Reg. datum: 05 december 2003

Ziehier het volgende C programmaatje voor de unix console. Het dumpt een tekstbestand op het scherm en laat de letters in kleuren knipperen mbv ncurses. Het probleem is dat ik eigenlijk wil dat het programma blijft lopen totdat er op een toets gedrukt wordt. Normaalgesproken kun je getch() gebruiken om letter voor letter toetsenbord input te lezen, maar getch() stopt alles vrolijk en gaat wachten op stdin actie.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <stdio.h>
#include <ncurses.h>

main()
{
  FILE *bestand;
  int Kleur = 0, Regel[1000], Kolom[1000], Tel = 0, RegTel = 0, KolTel = 0, Getal, i;
  char Let = 0, Letter[1000];
  bool Toets = false;

  bestand = fopen ("ascii.txt", "rt");           // letters laden, coords onthouden.
  do
  {
    Let = fgetc(bestand);
    if ( Let != 10 )
    {
      Letter[Tel] = Let;
      Regel[Tel] = RegTel;
      Kolom[Tel]= KolTel;
      KolTel++;
      if ( Let != 32 ) Tel++;
    }
    else
    {
      RegTel++;
      KolTel = 0;
    }
  }
  while (Let != EOF);

  initscr();                                     // start ncurses scherm
  curs_set(0);                                   // hide cursor
  noecho();                                      // geen echo van toetsenbord naar scherm
  start_color();
  cbreak();                                      // niet wachten op enter na toetsenbord input
  for ( i = 0; i <=7; i++) init_pair(i, i, 0);   // curses kleuren init

  while ( ! Toets )
  {
    init_color(rand()%7+1, rand()%1000, rand()%1000,rand()%1000);
    Kleur=rand()%7+1;
    attron(COLOR_PAIR(Kleur));
    Getal = rand()%(Tel-1);
    mvaddch(Regel[Getal],Kolom[Getal],Letter[Getal]);
    attroff(COLOR_PAIR(Kleur));
    refresh();
    usleep(9999); // niet teveel cpu weggeven

//    hier moet iets komen dat kijkt of er op een toets is gedrukt.
//    if ( getch() ) Toets = true  werkt niet, dan stopt het programma om te wachten op toets.

  }
  endwin();
}

Met een shell script constructie kan ik dit waarschijnlijk wel voor elkaar krijgen door tty's te redirecten ofzo, maar das niet de mooie manier.

edit: hee er zaten spaties vooraan. Is daar een opmaak truukje voor? ja dus

blorf wijzigde dit bericht 24-07-2008 16:30 (4%)

You are in a maze of little twisting passages, all different.

Berichten: 683
Reg. datum: 10 juli 2002

Als je de code-tag gebruikt dan gaat de opmaak ook goed. Als je de getch manpage leest staat daar "In no-delay mode, if no input is waiting, the value ERR is returned." Als je googled op no-delay mode en ncurses dan kom je uit op de nodelay functie.
Succes!

Ik heb nog een C64 met spelletjes e.d. en een Sega game gear met spellen liggen. Interesse? Mailadres in mijn profiel.

1. Controleer de kabel!
Berichten: 5.695
Reg. datum: 08 augustus 2000

Met poll / select kijken of er input staat?

lees ook:

http://www.is.pku.edu.cn/~qzy/c/c_faq/c-faq19.txt (unix buffert per regel wat je dus wellicht uit wil zetten)

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.

Berichten: 52
Reg. datum: 05 december 2003

De cbreak() is om dat linebufferen uit te zetten, maar ik ben er uit, springuin had gelijk.
nodelay() werkt, ik wist alleen niet dat ik stdscr moest gebruiken ipv 0
daarom dacht ik dat mijn prog te snel ging om een toets te onderscheppen.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <ncurses.h>
main()
{
  char Toets = ERR;
  initscr();
  noecho();
  cbreak();
  nodelay(stdscr, true);
  addstr ("druk op <esc>...");
  while (Toets != 27)
  {
    usleep(99999);
    addch('.');
    Toets = getch();
  }
  endwin();
}

You are in a maze of little twisting passages, all different.

Human-readable is relatief
Berichten: 184
Reg. datum: 01 september 2007

Hmm. Bedoel je niet dat je geowon wilt lezen "wanneer je het wilt" ?
oftewel: Non-blocking ? Ik weet niet of het kan met stdin, maar je kan proberen dit op non-blocking te setten. Dan wordt er niet geblockt op je call

Vind jij dat ook niet ?

Pagina: 1



VNU Media logo Powered by True

© 1998 - 2008 Tweakers.net - Alle rechten voorbehouden

Uitgever van: