Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Problem z kbhit()

Ostatnio zmodyfikowano 2009-09-20 21:18
Autor Wiadomość
Skorek
Temat założony przez niniejszego użytkownika
Problem z kbhit()
» 2009-09-20 16:25:36
Ostatnio napisałem program który ma na celu odtwarzać dźwięki za pomocą PcSpeakera
ale w pewnym momęcie napodkałem problem. Mianowicie gdy wciśniemy jakis klawisz to gra żądany dźwięk, ale po puszczeniu klawisza dźwięk nie chce przestać grać.

Próbowałem odczytywać czy klawisz jest wciśnięty czy nie za pomocą funkcji kbhit(), ale to działa tylko gdy wciśniemy klawisz, po puszczeniu klawisza program nie robi tego co ma.

Miejsce gdzie jest problem :
C/C++
if( !kbhit() ) {
    global_char = 7;
}
Jeżeli zakomentujemy tę część program będzie jakoś działał.

C/C++
#include <iostream>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <ddtconsole.h>

#define czas 60000
#define disp_text "Dzwienki od Q do P\nZmiana oktawy + i -\n"

using namespace ddt::console;
using namespace std;

unsigned short last_key;
unsigned char global_char;
HANDLE opened_th[ 2 ] = { 0, 0 };
short oktawa = 4;
const int notes[ 7 ][ 10 ] = {
    { 0, 33, 37, 41, 44, 49, 55, 62, 65, 73 },
    { 62, 65, 73, 82, 87, 98, 110, 123, 131, 147 },
    { 123, 131, 147, 165, 175, 196, 220, 247, 262, 294 },
    { 247, 262, 294, 330, 349, 392, 440, 494, 523, 587 },
    { 494, 523, 587, 659, 698, 784, 880, 988, 1047, 1175 },
    { 998, 1047, 1175, 1319, 1397, 1568, 1760, 1976, 2093, 2349 },
    { 1976, 2093, 2349, 2637, 2794, 3136, 3520, 3951, 4186, 0 },
};
const string note_symb[ 7 ][ 10 ] = {
    { "Brak", "C1", "D1", "E1", "F1", "G1", "A1", "H1", "C2", "D2" },
    { "H2", "C2", "D2", "E2", "F2", "G2", "A2", "H2", "C3", "D3" },
    { "H2", "C3", "D3", "E3", "F3", "G3", "A3", "H3", "C4", "D4" },
    { "H3", "C4", "D4", "E4", "F4", "G4", "A4", "H4", "C5", "D5" },
    { "H4", "C5", "D5", "E5", "F5", "G5", "A5", "H5", "C6", "D6" },
    { "H5", "C6", "D6", "E6", "F6", "G6", "A6", "H6", "C7", "D7" },
    { "H6", "C7", "D7", "E7", "F7", "G7", "A7", "H7", "C8", "Brak" },
};
const int keys[ 10 ] = { 113, 119, 101, 114, 116, 121, 117, 105, 111, 112 }; //Kody klawiszy. Małe litery.

DWORD WINAPI play_sound( PVOID freq ) {
    Beep( DWORD( freq ), czas );
}

DWORD WINAPI key_radar( PVOID terminate ) {
    do {
        while( kbhit() ) {
            global_char = getch();
        }
        if( !kbhit() ) { //tu jest problem.
            global_char = 7;
        }
    } while( 1 == 1 );
   
}

string check_key( unsigned char key ) {
    //static unsigned char last_key;
   
    if( key == last_key ) {
        for( int i = 0; i <= 10; i++ ) {
            if( int( key ) == keys[ i ] ) {
                return note_symb[ oktawa ][ i ];
            }
        }
    }
   
    if( key == 43 ) {
        oktawa++;
        if( oktawa > 6 ) { oktawa = 6; }
        return "Oktawa +";
    } else if( key == 45 ) {
        oktawa--;
        if( oktawa < 0 ) { oktawa = 0; }
        return "Oktawa -";
    }
   
    if( key != last_key ) {
        DWORD th_id = 0;
        int freq = 0;
        if( opened_th[ 1 ] != NULL ) {
            TerminateThread( opened_th[ 1 ], 0 );
        }
        last_key = key;
        for( int i = 0; i <= 10; i++ ) {
            if( int( key ) == keys[ i ] ) {
                freq = notes[ oktawa ][ i ];
                opened_th[ 1 ] = CreateThread( NULL, 0, play_sound,( PVOID ) freq, 0, & th_id );
                return note_symb[ oktawa ][ i ];
            }
        }
        opened_th[ 1 ] = CreateThread( NULL, 0, play_sound,( PVOID ) freq, 0, & th_id );
        return "Pauza";
    }
    return "";
}

int main() {
    SetConsoleTitleA( "Music Player by Skorek. Rev 3." );
    string info[ 2 ];
    cout << disp_text;
   
    opened_th[ 0 ] = CreateThread( NULL, 0, key_radar,( PVOID ) false, 0, NULL );
   
    while( int( global_char ) != 27 ) {
        info[ 0 ] = check_key( global_char );
        if( info[ 0 ] == "" ) { info[ 0 ] = info[ 1 ]; }
        gotoxy( 1, 1 );
        cout << disp_text << "Oktawa: " << oktawa + 1 << "\nDzwienk: " << info[ 0 ] << "              ";
        gotoxy( 1, 10 );
        info[ 1 ] = info[ 0 ];
        SetConsoleTitleA( "Music Player by Skorek. Rev 3." );
    }
    TerminateThread( opened_th[ 0 ], 0 );
    return 0;
}

Prosze o pomoc.
Może jest jakas inna funkcja do określania tego czy klawisz jest wciśnięty ??

P-10336
malan
» 2009-09-20 17:10:47
Pamiętaj, że kbhit() to nie getch() i nie czeka, aż klawisz zostanie naciśnięty.

Tak na szybko to mi do głowy przyszło coś takiego (tylko nie wiem, czy to zdziała):
C/C++
while( kbhit() == false )
{
    if( kbhit() )
         global_char = getch();
    else
         global_char = 7;
   
}
P-10338
Skorek
Temat założony przez niniejszego użytkownika
» 2009-09-20 18:35:34
Tak też już próbowałem. I nie działa.

Funkcja "key_radar" to osobny wątek i ma za zadanie przez cały czas działania programu aktualizować zmienną global_char gdzie zapisany jest aktualnie wciśnięty przycisk.

global_char = 7 znacza, że jest wciśnięty klawisz o numerze 7 a tego nie ma w tablicy globalnej "keys" czyli nie powinien być odtworzony żaden dźwięk. Zamiast wartości 7 możemy podstawić cokolwiek innego co nie jest kodem klawiszy: (q,w,e,r,t,y,u,i,o,p).

P-10343
Skorek
Temat założony przez niniejszego użytkownika
» 2009-09-20 20:04:16
Teraz próbowałem przerobić program tak żeby kożystał z biblioteki SDL. Czytałem kurs obsługi klawiatury na tej stronie i napotkałem inne problemy.

Teraz funkcja "key_radar" wygląda tak:
C/C++
DWORD WINAPI key_radar( PVOID terminate ) {
    SDL_Event key_event;
    while( SDL_PollEvent( & key_event ) ) {
        if( key_event.type == SDL_KEYDOWN ) {
            while( kbhit() ) {
                global_char = getch();
            }
        } else {
            global_char = 1;
        }
    }
}

Ale występują nastęujące błędy:

  [Linker error] undefined reference to `SDL_PollEvent'
  [Linker error] undefined reference to `WinMain@16'
  ld returned 1 exit status

I już nie wiem co mam robić żeby program działał.

P-10344
steckel
» 2009-09-20 20:13:49
Dodaj to do opcji linkera:
SDL.lib SDLmain.lib
P-10345
Skorek
Temat założony przez niniejszego użytkownika
» 2009-09-20 21:18:19
Dodałem do linkera to co napisałeś i mam kolejne błędy.

Circular main <- main.o dependency dropped.
P-10347
« 1 »
  Strona 1 z 1