C++ Simple Game Beeping Utility












0












$begingroup$


Lately I have been playing a game called Dirty Bomb. I like it very much, and since I was taking a rest of basic C++ OpenGL, i tried to make a simple console utility for it.



What i wanted to achieve is that, when I pressed a key (representing an in-game character) the program would, after a specified delay depending on the key pressed, emit a distinct beeping. So when I see an enemy in-game character use its ability, I would press a key, and then after the cooldown delay of its ability is over(or at least near to get over), I get notified with a beeping, so i know if its a danger to get near him. I also wanted to have a "substracted delay" variable, so I could get notified a little before the enemy's ability is ready.



I wanted to have a review in the code I made, since I'm still a newbie in the world of C++ I want to know if there are ways to improve it and, if you're able, ask some questions I commented in there.



Also I've used pthreads for the beeping and waiting parts, since Beep() sleeps its calling thread and waiting can be easily done with the sleep_for() function.



Here is the code, I've commented each part so you know what each does easily:



main.cpp



#include <iostream>
#include <windows.h> // Question: I'm only using GetAsyncKeyState and Beep functions from windows.h,
// Is there a way so i don't have to include the whole windows header
// and just the ones that have those functions?
#include <thread> // for multithreading :D
#include <chrono>
#include "notes.h" // An util header i wrote to convert music notes to Hertz, so Beep() can actually play something

using namespace std;

// Holders to know which keys are and were pressed. ( so i can handle Pushing, Holding and Releasing keys ( but i just needed pushing, so :P ) )
bool lastAsyncKeyState[ 0xFF ] = {0};
bool asyncKeyState[ 0xFF ] = {0};

// Functions to save the keyboard state every cicle, so the below function can work
void saveAsyncKeyStates() { for ( int i = 0; i < 0xFF; i++ ) lastAsyncKeyState[i] = asyncKeyState[i]; }
void updateAsyncKeyStates() { for ( int i = 0; i < 0xFF; i++ ) asyncKeyState[i] = ( GetAsyncKeyState(i) ); }

// Only detect if a key was Pushed and not if it's being pressed constantly
bool asyncKeyPushed( int key ) {
if ( asyncKeyState[key] && !lastAsyncKeyState[key] ) return true;
return false;
}

const int updatePeriod = 10; // Delay between program updates in milliseconds
const int beepDelay = 1000; // Delay between beeps when this program is ON
int beepCount = 0; // counter for ON beeps
int substractDelay = 5; // How many seconds should the program substract to the original Characters delay
int noteDuration = 200; // Base note duration

bool shouldUpdateConsole = true; // variable to update the console only when needed
bool onSwitch = false; // Program state ( ON/OFF )

// Enums for sound types and delays
enum SoundType {
FRAGGER,
JAVELIN,
STOKER,
SKYHAMMER,
ONSWITCH,
OFFSWITCH,
ON_BEEP
};

enum Delays {
FRAGGER_DELAY = 20,
JAVELIN_DELAY = 30,
STOKER_DELAY = 40,
SKYHAMMER_DELAY = 70
};


void updateConsole() // Does what it says
{
system("CLS"); // I know its evil, but I had no other option

cout << endl;
cout << " Substracted Delay: " << substractDelay << endl << endl;
cout << " [ T ] Wait for FRAGGER ( " << Delays::FRAGGER_DELAY - substractDelay << "s )" << endl;
cout << " [ G ] Wait for JAVELIN ( " << Delays::JAVELIN_DELAY - substractDelay << "s )" << " [ H ] Wait for SKYHAMMER ( " << Delays::SKYHAMMER_DELAY - substractDelay << "s )" << endl;
cout << " [ B ] Wait for STOKER ( " << Delays::STOKER_DELAY - substractDelay << "s )" << endl << endl;
cout << " State: " << ( onSwitch ? "ON" : "OFF" ) << endl << endl;
cout << " Press [END] to exit." << endl;

shouldUpdateConsole = false;
}

// Note types
void playSound( int soundType ) {
switch( soundType ) {
case SoundType::FRAGGER :
Beep( noteHz(Note::A + 6*octave), noteDuration/2 );
Beep( noteHz(Note::A + 6*octave), noteDuration );
break;
case SoundType::JAVELIN :
Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
Beep( noteHz(Note::B + 5*octave), noteDuration );
break;
case SoundType::STOKER :
Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
Beep( noteHz(Note::F + 5*octave), noteDuration );
break;
case SoundType::SKYHAMMER :
Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
Beep( noteHz(Note::A + 5*octave), noteDuration );
break;
case SoundType::ONSWITCH :
Beep( noteHz(Note::A + 7*octave), noteDuration/2 );
Beep( noteHz(Note::B + 7*octave), noteDuration/2 );
break;
case SoundType::OFFSWITCH :
Beep( noteHz(Note::A + 4*octave), noteDuration/2 );
Beep( noteHz(Note::G + 4*octave), noteDuration/2 );
break;
case SoundType::ON_BEEP :
Beep( noteHz(Note::C + 4*octave), noteDuration/4 );
break;
}
}

// Makes the current thread to wait the specified delay and then play the specified Sound
void waitForAndPlaySound( int seconds, int soundType ) {
if ( seconds > 0 ) this_thread::sleep_for( chrono::seconds( seconds ) );
playSound( soundType );
}

// Creates a thread that runs waitForAndPlaySound, with the specified sound and delay
void playSoundProtocol( int soundType, int delay ) {
thread tempThread( waitForAndPlaySound , delay , soundType );
tempThread.detach(); // Error if not detached.
}

// The main loop :D
int main()
{
while ( !GetAsyncKeyState(VK_END) ) { // Program will execute until the END key is pressed
updateAsyncKeyStates(); // Gets the keys that are pressed now, to compare with the keys that were pressed in the last cycle

if ( asyncKeyPushed( VK_INSERT ) ) { // if the INSERT key is pushed, the program will switch to ON/OFF.
onSwitch = !onSwitch;
playSoundProtocol( ( onSwitch ? SoundType::ONSWITCH : SoundType::OFFSWITCH ), 0 );
shouldUpdateConsole = true;
}

if ( asyncKeyPushed( VK_UP ) && substractDelay < 10 ) { substractDelay++; shouldUpdateConsole = true; } // MAX substracted delay is 10
if ( asyncKeyPushed( VK_DOWN ) && substractDelay > 0 ) { substractDelay--; shouldUpdateConsole = true; } // MIN substracted delay is 0

if ( onSwitch ) { // If the program is ON
if ( asyncKeyPushed( 'T' ) ) // T is to wait for the character Fragger in-game ability
playSoundProtocol( SoundType::FRAGGER, Delays::FRAGGER_DELAY - substractDelay );
if ( asyncKeyPushed( 'G' ) ) // G is to wait for the character Javelin in-game ability
playSoundProtocol( SoundType::JAVELIN, Delays::JAVELIN_DELAY - substractDelay );
if ( asyncKeyPushed( 'B' ) ) // B is to wait for the character Stoker in-game ability
playSoundProtocol( SoundType::STOKER, Delays::STOKER_DELAY - substractDelay );
if ( asyncKeyPushed( 'H' ) ) // H is to wait for the character Skyhammer in-game ability
playSoundProtocol( SoundType::SKYHAMMER, Delays::SKYHAMMER_DELAY - substractDelay );

beepCount += updatePeriod; // The program beeps every beepDelay, so the user knows the program is active (ON).
if ( beepCount >= beepDelay ) { beepCount -= beepDelay; playSoundProtocol( SoundType::ON_BEEP, 0 ); }

// Question: is there a way to control the volume of Beep ?

} else { // If the program is OFF
if ( beepCount != 0 ) beepCount = 0;
}

if ( shouldUpdateConsole ) updateConsole(); // If the console should update, it calls the updateConsole func
saveAsyncKeyStates(); // Saves the keys that are pressed now, so the next cycle can use them
this_thread::sleep_for( chrono::milliseconds( updatePeriod ) ); // Sleeps for updatePeriod
}
return 0;
}


notes.h



#ifndef NOTES_H
#define NOTES_H

enum Note{ // Starts from C0
C = -57, // C starts at -57, so A0 ( -48 ) plus 4 octaves ( 48 ) results in 0, so the noteHz function can work properly.
Db,
D,
Eb,
E,
F,
Gb,
G,
Ab,
A,
Bb,
B
};

extern const int octave; // = 12

float noteHz( int );

#endif // NOTES_H


notes.cpp



#include "notes.h"
#include <cmath>

// Note to Hertz constants and stuff, more info on:
// http://pages.mtu.edu/~suits/NoteFreqCalcs.html

const float a = std::pow( 2.0f , 1.0f/12 ); // Question: if someone can tell me how to make this constant "private"
// so only this .cpp can use it i would thank you :)

const int octave = 12; // Quantity of half notes in an octave ( or the length of the Note enum )

// This function transforms musical notes to Hz.
// It works by setting the center note as A4 ( 440 Hz ), then calculating every other Hz note from that point.
float noteHz( int note ) {
return 440.0f * std::pow( a , note );
}









share|improve this question







New contributor




Nikko77 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$

















    0












    $begingroup$


    Lately I have been playing a game called Dirty Bomb. I like it very much, and since I was taking a rest of basic C++ OpenGL, i tried to make a simple console utility for it.



    What i wanted to achieve is that, when I pressed a key (representing an in-game character) the program would, after a specified delay depending on the key pressed, emit a distinct beeping. So when I see an enemy in-game character use its ability, I would press a key, and then after the cooldown delay of its ability is over(or at least near to get over), I get notified with a beeping, so i know if its a danger to get near him. I also wanted to have a "substracted delay" variable, so I could get notified a little before the enemy's ability is ready.



    I wanted to have a review in the code I made, since I'm still a newbie in the world of C++ I want to know if there are ways to improve it and, if you're able, ask some questions I commented in there.



    Also I've used pthreads for the beeping and waiting parts, since Beep() sleeps its calling thread and waiting can be easily done with the sleep_for() function.



    Here is the code, I've commented each part so you know what each does easily:



    main.cpp



    #include <iostream>
    #include <windows.h> // Question: I'm only using GetAsyncKeyState and Beep functions from windows.h,
    // Is there a way so i don't have to include the whole windows header
    // and just the ones that have those functions?
    #include <thread> // for multithreading :D
    #include <chrono>
    #include "notes.h" // An util header i wrote to convert music notes to Hertz, so Beep() can actually play something

    using namespace std;

    // Holders to know which keys are and were pressed. ( so i can handle Pushing, Holding and Releasing keys ( but i just needed pushing, so :P ) )
    bool lastAsyncKeyState[ 0xFF ] = {0};
    bool asyncKeyState[ 0xFF ] = {0};

    // Functions to save the keyboard state every cicle, so the below function can work
    void saveAsyncKeyStates() { for ( int i = 0; i < 0xFF; i++ ) lastAsyncKeyState[i] = asyncKeyState[i]; }
    void updateAsyncKeyStates() { for ( int i = 0; i < 0xFF; i++ ) asyncKeyState[i] = ( GetAsyncKeyState(i) ); }

    // Only detect if a key was Pushed and not if it's being pressed constantly
    bool asyncKeyPushed( int key ) {
    if ( asyncKeyState[key] && !lastAsyncKeyState[key] ) return true;
    return false;
    }

    const int updatePeriod = 10; // Delay between program updates in milliseconds
    const int beepDelay = 1000; // Delay between beeps when this program is ON
    int beepCount = 0; // counter for ON beeps
    int substractDelay = 5; // How many seconds should the program substract to the original Characters delay
    int noteDuration = 200; // Base note duration

    bool shouldUpdateConsole = true; // variable to update the console only when needed
    bool onSwitch = false; // Program state ( ON/OFF )

    // Enums for sound types and delays
    enum SoundType {
    FRAGGER,
    JAVELIN,
    STOKER,
    SKYHAMMER,
    ONSWITCH,
    OFFSWITCH,
    ON_BEEP
    };

    enum Delays {
    FRAGGER_DELAY = 20,
    JAVELIN_DELAY = 30,
    STOKER_DELAY = 40,
    SKYHAMMER_DELAY = 70
    };


    void updateConsole() // Does what it says
    {
    system("CLS"); // I know its evil, but I had no other option

    cout << endl;
    cout << " Substracted Delay: " << substractDelay << endl << endl;
    cout << " [ T ] Wait for FRAGGER ( " << Delays::FRAGGER_DELAY - substractDelay << "s )" << endl;
    cout << " [ G ] Wait for JAVELIN ( " << Delays::JAVELIN_DELAY - substractDelay << "s )" << " [ H ] Wait for SKYHAMMER ( " << Delays::SKYHAMMER_DELAY - substractDelay << "s )" << endl;
    cout << " [ B ] Wait for STOKER ( " << Delays::STOKER_DELAY - substractDelay << "s )" << endl << endl;
    cout << " State: " << ( onSwitch ? "ON" : "OFF" ) << endl << endl;
    cout << " Press [END] to exit." << endl;

    shouldUpdateConsole = false;
    }

    // Note types
    void playSound( int soundType ) {
    switch( soundType ) {
    case SoundType::FRAGGER :
    Beep( noteHz(Note::A + 6*octave), noteDuration/2 );
    Beep( noteHz(Note::A + 6*octave), noteDuration );
    break;
    case SoundType::JAVELIN :
    Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
    Beep( noteHz(Note::B + 5*octave), noteDuration );
    break;
    case SoundType::STOKER :
    Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
    Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
    Beep( noteHz(Note::F + 5*octave), noteDuration );
    break;
    case SoundType::SKYHAMMER :
    Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
    Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
    Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
    Beep( noteHz(Note::A + 5*octave), noteDuration );
    break;
    case SoundType::ONSWITCH :
    Beep( noteHz(Note::A + 7*octave), noteDuration/2 );
    Beep( noteHz(Note::B + 7*octave), noteDuration/2 );
    break;
    case SoundType::OFFSWITCH :
    Beep( noteHz(Note::A + 4*octave), noteDuration/2 );
    Beep( noteHz(Note::G + 4*octave), noteDuration/2 );
    break;
    case SoundType::ON_BEEP :
    Beep( noteHz(Note::C + 4*octave), noteDuration/4 );
    break;
    }
    }

    // Makes the current thread to wait the specified delay and then play the specified Sound
    void waitForAndPlaySound( int seconds, int soundType ) {
    if ( seconds > 0 ) this_thread::sleep_for( chrono::seconds( seconds ) );
    playSound( soundType );
    }

    // Creates a thread that runs waitForAndPlaySound, with the specified sound and delay
    void playSoundProtocol( int soundType, int delay ) {
    thread tempThread( waitForAndPlaySound , delay , soundType );
    tempThread.detach(); // Error if not detached.
    }

    // The main loop :D
    int main()
    {
    while ( !GetAsyncKeyState(VK_END) ) { // Program will execute until the END key is pressed
    updateAsyncKeyStates(); // Gets the keys that are pressed now, to compare with the keys that were pressed in the last cycle

    if ( asyncKeyPushed( VK_INSERT ) ) { // if the INSERT key is pushed, the program will switch to ON/OFF.
    onSwitch = !onSwitch;
    playSoundProtocol( ( onSwitch ? SoundType::ONSWITCH : SoundType::OFFSWITCH ), 0 );
    shouldUpdateConsole = true;
    }

    if ( asyncKeyPushed( VK_UP ) && substractDelay < 10 ) { substractDelay++; shouldUpdateConsole = true; } // MAX substracted delay is 10
    if ( asyncKeyPushed( VK_DOWN ) && substractDelay > 0 ) { substractDelay--; shouldUpdateConsole = true; } // MIN substracted delay is 0

    if ( onSwitch ) { // If the program is ON
    if ( asyncKeyPushed( 'T' ) ) // T is to wait for the character Fragger in-game ability
    playSoundProtocol( SoundType::FRAGGER, Delays::FRAGGER_DELAY - substractDelay );
    if ( asyncKeyPushed( 'G' ) ) // G is to wait for the character Javelin in-game ability
    playSoundProtocol( SoundType::JAVELIN, Delays::JAVELIN_DELAY - substractDelay );
    if ( asyncKeyPushed( 'B' ) ) // B is to wait for the character Stoker in-game ability
    playSoundProtocol( SoundType::STOKER, Delays::STOKER_DELAY - substractDelay );
    if ( asyncKeyPushed( 'H' ) ) // H is to wait for the character Skyhammer in-game ability
    playSoundProtocol( SoundType::SKYHAMMER, Delays::SKYHAMMER_DELAY - substractDelay );

    beepCount += updatePeriod; // The program beeps every beepDelay, so the user knows the program is active (ON).
    if ( beepCount >= beepDelay ) { beepCount -= beepDelay; playSoundProtocol( SoundType::ON_BEEP, 0 ); }

    // Question: is there a way to control the volume of Beep ?

    } else { // If the program is OFF
    if ( beepCount != 0 ) beepCount = 0;
    }

    if ( shouldUpdateConsole ) updateConsole(); // If the console should update, it calls the updateConsole func
    saveAsyncKeyStates(); // Saves the keys that are pressed now, so the next cycle can use them
    this_thread::sleep_for( chrono::milliseconds( updatePeriod ) ); // Sleeps for updatePeriod
    }
    return 0;
    }


    notes.h



    #ifndef NOTES_H
    #define NOTES_H

    enum Note{ // Starts from C0
    C = -57, // C starts at -57, so A0 ( -48 ) plus 4 octaves ( 48 ) results in 0, so the noteHz function can work properly.
    Db,
    D,
    Eb,
    E,
    F,
    Gb,
    G,
    Ab,
    A,
    Bb,
    B
    };

    extern const int octave; // = 12

    float noteHz( int );

    #endif // NOTES_H


    notes.cpp



    #include "notes.h"
    #include <cmath>

    // Note to Hertz constants and stuff, more info on:
    // http://pages.mtu.edu/~suits/NoteFreqCalcs.html

    const float a = std::pow( 2.0f , 1.0f/12 ); // Question: if someone can tell me how to make this constant "private"
    // so only this .cpp can use it i would thank you :)

    const int octave = 12; // Quantity of half notes in an octave ( or the length of the Note enum )

    // This function transforms musical notes to Hz.
    // It works by setting the center note as A4 ( 440 Hz ), then calculating every other Hz note from that point.
    float noteHz( int note ) {
    return 440.0f * std::pow( a , note );
    }









    share|improve this question







    New contributor




    Nikko77 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.







    $endgroup$















      0












      0








      0





      $begingroup$


      Lately I have been playing a game called Dirty Bomb. I like it very much, and since I was taking a rest of basic C++ OpenGL, i tried to make a simple console utility for it.



      What i wanted to achieve is that, when I pressed a key (representing an in-game character) the program would, after a specified delay depending on the key pressed, emit a distinct beeping. So when I see an enemy in-game character use its ability, I would press a key, and then after the cooldown delay of its ability is over(or at least near to get over), I get notified with a beeping, so i know if its a danger to get near him. I also wanted to have a "substracted delay" variable, so I could get notified a little before the enemy's ability is ready.



      I wanted to have a review in the code I made, since I'm still a newbie in the world of C++ I want to know if there are ways to improve it and, if you're able, ask some questions I commented in there.



      Also I've used pthreads for the beeping and waiting parts, since Beep() sleeps its calling thread and waiting can be easily done with the sleep_for() function.



      Here is the code, I've commented each part so you know what each does easily:



      main.cpp



      #include <iostream>
      #include <windows.h> // Question: I'm only using GetAsyncKeyState and Beep functions from windows.h,
      // Is there a way so i don't have to include the whole windows header
      // and just the ones that have those functions?
      #include <thread> // for multithreading :D
      #include <chrono>
      #include "notes.h" // An util header i wrote to convert music notes to Hertz, so Beep() can actually play something

      using namespace std;

      // Holders to know which keys are and were pressed. ( so i can handle Pushing, Holding and Releasing keys ( but i just needed pushing, so :P ) )
      bool lastAsyncKeyState[ 0xFF ] = {0};
      bool asyncKeyState[ 0xFF ] = {0};

      // Functions to save the keyboard state every cicle, so the below function can work
      void saveAsyncKeyStates() { for ( int i = 0; i < 0xFF; i++ ) lastAsyncKeyState[i] = asyncKeyState[i]; }
      void updateAsyncKeyStates() { for ( int i = 0; i < 0xFF; i++ ) asyncKeyState[i] = ( GetAsyncKeyState(i) ); }

      // Only detect if a key was Pushed and not if it's being pressed constantly
      bool asyncKeyPushed( int key ) {
      if ( asyncKeyState[key] && !lastAsyncKeyState[key] ) return true;
      return false;
      }

      const int updatePeriod = 10; // Delay between program updates in milliseconds
      const int beepDelay = 1000; // Delay between beeps when this program is ON
      int beepCount = 0; // counter for ON beeps
      int substractDelay = 5; // How many seconds should the program substract to the original Characters delay
      int noteDuration = 200; // Base note duration

      bool shouldUpdateConsole = true; // variable to update the console only when needed
      bool onSwitch = false; // Program state ( ON/OFF )

      // Enums for sound types and delays
      enum SoundType {
      FRAGGER,
      JAVELIN,
      STOKER,
      SKYHAMMER,
      ONSWITCH,
      OFFSWITCH,
      ON_BEEP
      };

      enum Delays {
      FRAGGER_DELAY = 20,
      JAVELIN_DELAY = 30,
      STOKER_DELAY = 40,
      SKYHAMMER_DELAY = 70
      };


      void updateConsole() // Does what it says
      {
      system("CLS"); // I know its evil, but I had no other option

      cout << endl;
      cout << " Substracted Delay: " << substractDelay << endl << endl;
      cout << " [ T ] Wait for FRAGGER ( " << Delays::FRAGGER_DELAY - substractDelay << "s )" << endl;
      cout << " [ G ] Wait for JAVELIN ( " << Delays::JAVELIN_DELAY - substractDelay << "s )" << " [ H ] Wait for SKYHAMMER ( " << Delays::SKYHAMMER_DELAY - substractDelay << "s )" << endl;
      cout << " [ B ] Wait for STOKER ( " << Delays::STOKER_DELAY - substractDelay << "s )" << endl << endl;
      cout << " State: " << ( onSwitch ? "ON" : "OFF" ) << endl << endl;
      cout << " Press [END] to exit." << endl;

      shouldUpdateConsole = false;
      }

      // Note types
      void playSound( int soundType ) {
      switch( soundType ) {
      case SoundType::FRAGGER :
      Beep( noteHz(Note::A + 6*octave), noteDuration/2 );
      Beep( noteHz(Note::A + 6*octave), noteDuration );
      break;
      case SoundType::JAVELIN :
      Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::B + 5*octave), noteDuration );
      break;
      case SoundType::STOKER :
      Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::F + 5*octave), noteDuration );
      break;
      case SoundType::SKYHAMMER :
      Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::A + 5*octave), noteDuration );
      break;
      case SoundType::ONSWITCH :
      Beep( noteHz(Note::A + 7*octave), noteDuration/2 );
      Beep( noteHz(Note::B + 7*octave), noteDuration/2 );
      break;
      case SoundType::OFFSWITCH :
      Beep( noteHz(Note::A + 4*octave), noteDuration/2 );
      Beep( noteHz(Note::G + 4*octave), noteDuration/2 );
      break;
      case SoundType::ON_BEEP :
      Beep( noteHz(Note::C + 4*octave), noteDuration/4 );
      break;
      }
      }

      // Makes the current thread to wait the specified delay and then play the specified Sound
      void waitForAndPlaySound( int seconds, int soundType ) {
      if ( seconds > 0 ) this_thread::sleep_for( chrono::seconds( seconds ) );
      playSound( soundType );
      }

      // Creates a thread that runs waitForAndPlaySound, with the specified sound and delay
      void playSoundProtocol( int soundType, int delay ) {
      thread tempThread( waitForAndPlaySound , delay , soundType );
      tempThread.detach(); // Error if not detached.
      }

      // The main loop :D
      int main()
      {
      while ( !GetAsyncKeyState(VK_END) ) { // Program will execute until the END key is pressed
      updateAsyncKeyStates(); // Gets the keys that are pressed now, to compare with the keys that were pressed in the last cycle

      if ( asyncKeyPushed( VK_INSERT ) ) { // if the INSERT key is pushed, the program will switch to ON/OFF.
      onSwitch = !onSwitch;
      playSoundProtocol( ( onSwitch ? SoundType::ONSWITCH : SoundType::OFFSWITCH ), 0 );
      shouldUpdateConsole = true;
      }

      if ( asyncKeyPushed( VK_UP ) && substractDelay < 10 ) { substractDelay++; shouldUpdateConsole = true; } // MAX substracted delay is 10
      if ( asyncKeyPushed( VK_DOWN ) && substractDelay > 0 ) { substractDelay--; shouldUpdateConsole = true; } // MIN substracted delay is 0

      if ( onSwitch ) { // If the program is ON
      if ( asyncKeyPushed( 'T' ) ) // T is to wait for the character Fragger in-game ability
      playSoundProtocol( SoundType::FRAGGER, Delays::FRAGGER_DELAY - substractDelay );
      if ( asyncKeyPushed( 'G' ) ) // G is to wait for the character Javelin in-game ability
      playSoundProtocol( SoundType::JAVELIN, Delays::JAVELIN_DELAY - substractDelay );
      if ( asyncKeyPushed( 'B' ) ) // B is to wait for the character Stoker in-game ability
      playSoundProtocol( SoundType::STOKER, Delays::STOKER_DELAY - substractDelay );
      if ( asyncKeyPushed( 'H' ) ) // H is to wait for the character Skyhammer in-game ability
      playSoundProtocol( SoundType::SKYHAMMER, Delays::SKYHAMMER_DELAY - substractDelay );

      beepCount += updatePeriod; // The program beeps every beepDelay, so the user knows the program is active (ON).
      if ( beepCount >= beepDelay ) { beepCount -= beepDelay; playSoundProtocol( SoundType::ON_BEEP, 0 ); }

      // Question: is there a way to control the volume of Beep ?

      } else { // If the program is OFF
      if ( beepCount != 0 ) beepCount = 0;
      }

      if ( shouldUpdateConsole ) updateConsole(); // If the console should update, it calls the updateConsole func
      saveAsyncKeyStates(); // Saves the keys that are pressed now, so the next cycle can use them
      this_thread::sleep_for( chrono::milliseconds( updatePeriod ) ); // Sleeps for updatePeriod
      }
      return 0;
      }


      notes.h



      #ifndef NOTES_H
      #define NOTES_H

      enum Note{ // Starts from C0
      C = -57, // C starts at -57, so A0 ( -48 ) plus 4 octaves ( 48 ) results in 0, so the noteHz function can work properly.
      Db,
      D,
      Eb,
      E,
      F,
      Gb,
      G,
      Ab,
      A,
      Bb,
      B
      };

      extern const int octave; // = 12

      float noteHz( int );

      #endif // NOTES_H


      notes.cpp



      #include "notes.h"
      #include <cmath>

      // Note to Hertz constants and stuff, more info on:
      // http://pages.mtu.edu/~suits/NoteFreqCalcs.html

      const float a = std::pow( 2.0f , 1.0f/12 ); // Question: if someone can tell me how to make this constant "private"
      // so only this .cpp can use it i would thank you :)

      const int octave = 12; // Quantity of half notes in an octave ( or the length of the Note enum )

      // This function transforms musical notes to Hz.
      // It works by setting the center note as A4 ( 440 Hz ), then calculating every other Hz note from that point.
      float noteHz( int note ) {
      return 440.0f * std::pow( a , note );
      }









      share|improve this question







      New contributor




      Nikko77 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.







      $endgroup$




      Lately I have been playing a game called Dirty Bomb. I like it very much, and since I was taking a rest of basic C++ OpenGL, i tried to make a simple console utility for it.



      What i wanted to achieve is that, when I pressed a key (representing an in-game character) the program would, after a specified delay depending on the key pressed, emit a distinct beeping. So when I see an enemy in-game character use its ability, I would press a key, and then after the cooldown delay of its ability is over(or at least near to get over), I get notified with a beeping, so i know if its a danger to get near him. I also wanted to have a "substracted delay" variable, so I could get notified a little before the enemy's ability is ready.



      I wanted to have a review in the code I made, since I'm still a newbie in the world of C++ I want to know if there are ways to improve it and, if you're able, ask some questions I commented in there.



      Also I've used pthreads for the beeping and waiting parts, since Beep() sleeps its calling thread and waiting can be easily done with the sleep_for() function.



      Here is the code, I've commented each part so you know what each does easily:



      main.cpp



      #include <iostream>
      #include <windows.h> // Question: I'm only using GetAsyncKeyState and Beep functions from windows.h,
      // Is there a way so i don't have to include the whole windows header
      // and just the ones that have those functions?
      #include <thread> // for multithreading :D
      #include <chrono>
      #include "notes.h" // An util header i wrote to convert music notes to Hertz, so Beep() can actually play something

      using namespace std;

      // Holders to know which keys are and were pressed. ( so i can handle Pushing, Holding and Releasing keys ( but i just needed pushing, so :P ) )
      bool lastAsyncKeyState[ 0xFF ] = {0};
      bool asyncKeyState[ 0xFF ] = {0};

      // Functions to save the keyboard state every cicle, so the below function can work
      void saveAsyncKeyStates() { for ( int i = 0; i < 0xFF; i++ ) lastAsyncKeyState[i] = asyncKeyState[i]; }
      void updateAsyncKeyStates() { for ( int i = 0; i < 0xFF; i++ ) asyncKeyState[i] = ( GetAsyncKeyState(i) ); }

      // Only detect if a key was Pushed and not if it's being pressed constantly
      bool asyncKeyPushed( int key ) {
      if ( asyncKeyState[key] && !lastAsyncKeyState[key] ) return true;
      return false;
      }

      const int updatePeriod = 10; // Delay between program updates in milliseconds
      const int beepDelay = 1000; // Delay between beeps when this program is ON
      int beepCount = 0; // counter for ON beeps
      int substractDelay = 5; // How many seconds should the program substract to the original Characters delay
      int noteDuration = 200; // Base note duration

      bool shouldUpdateConsole = true; // variable to update the console only when needed
      bool onSwitch = false; // Program state ( ON/OFF )

      // Enums for sound types and delays
      enum SoundType {
      FRAGGER,
      JAVELIN,
      STOKER,
      SKYHAMMER,
      ONSWITCH,
      OFFSWITCH,
      ON_BEEP
      };

      enum Delays {
      FRAGGER_DELAY = 20,
      JAVELIN_DELAY = 30,
      STOKER_DELAY = 40,
      SKYHAMMER_DELAY = 70
      };


      void updateConsole() // Does what it says
      {
      system("CLS"); // I know its evil, but I had no other option

      cout << endl;
      cout << " Substracted Delay: " << substractDelay << endl << endl;
      cout << " [ T ] Wait for FRAGGER ( " << Delays::FRAGGER_DELAY - substractDelay << "s )" << endl;
      cout << " [ G ] Wait for JAVELIN ( " << Delays::JAVELIN_DELAY - substractDelay << "s )" << " [ H ] Wait for SKYHAMMER ( " << Delays::SKYHAMMER_DELAY - substractDelay << "s )" << endl;
      cout << " [ B ] Wait for STOKER ( " << Delays::STOKER_DELAY - substractDelay << "s )" << endl << endl;
      cout << " State: " << ( onSwitch ? "ON" : "OFF" ) << endl << endl;
      cout << " Press [END] to exit." << endl;

      shouldUpdateConsole = false;
      }

      // Note types
      void playSound( int soundType ) {
      switch( soundType ) {
      case SoundType::FRAGGER :
      Beep( noteHz(Note::A + 6*octave), noteDuration/2 );
      Beep( noteHz(Note::A + 6*octave), noteDuration );
      break;
      case SoundType::JAVELIN :
      Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::B + 5*octave), noteDuration );
      break;
      case SoundType::STOKER :
      Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::F + 5*octave), noteDuration );
      break;
      case SoundType::SKYHAMMER :
      Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::A + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::G + 5*octave), noteDuration/2 );
      Beep( noteHz(Note::A + 5*octave), noteDuration );
      break;
      case SoundType::ONSWITCH :
      Beep( noteHz(Note::A + 7*octave), noteDuration/2 );
      Beep( noteHz(Note::B + 7*octave), noteDuration/2 );
      break;
      case SoundType::OFFSWITCH :
      Beep( noteHz(Note::A + 4*octave), noteDuration/2 );
      Beep( noteHz(Note::G + 4*octave), noteDuration/2 );
      break;
      case SoundType::ON_BEEP :
      Beep( noteHz(Note::C + 4*octave), noteDuration/4 );
      break;
      }
      }

      // Makes the current thread to wait the specified delay and then play the specified Sound
      void waitForAndPlaySound( int seconds, int soundType ) {
      if ( seconds > 0 ) this_thread::sleep_for( chrono::seconds( seconds ) );
      playSound( soundType );
      }

      // Creates a thread that runs waitForAndPlaySound, with the specified sound and delay
      void playSoundProtocol( int soundType, int delay ) {
      thread tempThread( waitForAndPlaySound , delay , soundType );
      tempThread.detach(); // Error if not detached.
      }

      // The main loop :D
      int main()
      {
      while ( !GetAsyncKeyState(VK_END) ) { // Program will execute until the END key is pressed
      updateAsyncKeyStates(); // Gets the keys that are pressed now, to compare with the keys that were pressed in the last cycle

      if ( asyncKeyPushed( VK_INSERT ) ) { // if the INSERT key is pushed, the program will switch to ON/OFF.
      onSwitch = !onSwitch;
      playSoundProtocol( ( onSwitch ? SoundType::ONSWITCH : SoundType::OFFSWITCH ), 0 );
      shouldUpdateConsole = true;
      }

      if ( asyncKeyPushed( VK_UP ) && substractDelay < 10 ) { substractDelay++; shouldUpdateConsole = true; } // MAX substracted delay is 10
      if ( asyncKeyPushed( VK_DOWN ) && substractDelay > 0 ) { substractDelay--; shouldUpdateConsole = true; } // MIN substracted delay is 0

      if ( onSwitch ) { // If the program is ON
      if ( asyncKeyPushed( 'T' ) ) // T is to wait for the character Fragger in-game ability
      playSoundProtocol( SoundType::FRAGGER, Delays::FRAGGER_DELAY - substractDelay );
      if ( asyncKeyPushed( 'G' ) ) // G is to wait for the character Javelin in-game ability
      playSoundProtocol( SoundType::JAVELIN, Delays::JAVELIN_DELAY - substractDelay );
      if ( asyncKeyPushed( 'B' ) ) // B is to wait for the character Stoker in-game ability
      playSoundProtocol( SoundType::STOKER, Delays::STOKER_DELAY - substractDelay );
      if ( asyncKeyPushed( 'H' ) ) // H is to wait for the character Skyhammer in-game ability
      playSoundProtocol( SoundType::SKYHAMMER, Delays::SKYHAMMER_DELAY - substractDelay );

      beepCount += updatePeriod; // The program beeps every beepDelay, so the user knows the program is active (ON).
      if ( beepCount >= beepDelay ) { beepCount -= beepDelay; playSoundProtocol( SoundType::ON_BEEP, 0 ); }

      // Question: is there a way to control the volume of Beep ?

      } else { // If the program is OFF
      if ( beepCount != 0 ) beepCount = 0;
      }

      if ( shouldUpdateConsole ) updateConsole(); // If the console should update, it calls the updateConsole func
      saveAsyncKeyStates(); // Saves the keys that are pressed now, so the next cycle can use them
      this_thread::sleep_for( chrono::milliseconds( updatePeriod ) ); // Sleeps for updatePeriod
      }
      return 0;
      }


      notes.h



      #ifndef NOTES_H
      #define NOTES_H

      enum Note{ // Starts from C0
      C = -57, // C starts at -57, so A0 ( -48 ) plus 4 octaves ( 48 ) results in 0, so the noteHz function can work properly.
      Db,
      D,
      Eb,
      E,
      F,
      Gb,
      G,
      Ab,
      A,
      Bb,
      B
      };

      extern const int octave; // = 12

      float noteHz( int );

      #endif // NOTES_H


      notes.cpp



      #include "notes.h"
      #include <cmath>

      // Note to Hertz constants and stuff, more info on:
      // http://pages.mtu.edu/~suits/NoteFreqCalcs.html

      const float a = std::pow( 2.0f , 1.0f/12 ); // Question: if someone can tell me how to make this constant "private"
      // so only this .cpp can use it i would thank you :)

      const int octave = 12; // Quantity of half notes in an octave ( or the length of the Note enum )

      // This function transforms musical notes to Hz.
      // It works by setting the center note as A4 ( 440 Hz ), then calculating every other Hz note from that point.
      float noteHz( int note ) {
      return 440.0f * std::pow( a , note );
      }






      c++ game console windows pthreads






      share|improve this question







      New contributor




      Nikko77 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      Nikko77 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      Nikko77 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 1 hour ago









      Nikko77Nikko77

      11




      11




      New contributor




      Nikko77 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Nikko77 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Nikko77 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          Nikko77 is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214804%2fc-simple-game-beeping-utility%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          Nikko77 is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          Nikko77 is a new contributor. Be nice, and check out our Code of Conduct.













          Nikko77 is a new contributor. Be nice, and check out our Code of Conduct.












          Nikko77 is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214804%2fc-simple-game-beeping-utility%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

          is 'sed' thread safe

          How to make a Squid Proxy server?