diff --git a/CrystalPoint.cpp b/CrystalPoint.cpp index cf24833..867a0b6 100644 --- a/CrystalPoint.cpp +++ b/CrystalPoint.cpp @@ -9,6 +9,8 @@ int CrystalPoint::width = 0; int CrystalPoint::height = 0; +SoundSystem CrystalPoint::sound_system; + void CrystalPoint::init() { player = Player::getInstance(); @@ -90,6 +92,8 @@ void CrystalPoint::update() mouseOffset = Vec2f(0, 0); prevKeyboardState = keyboardState; glutPostRedisplay(); + + sound_system.SetListener(player->position, Vec3f(), Vec3f()); } diff --git a/CrystalPoint.h b/CrystalPoint.h index da4a3b8..5437d5c 100644 --- a/CrystalPoint.h +++ b/CrystalPoint.h @@ -1,8 +1,10 @@ #pragma once class WorldHandler; +class SoundSystem; class Player; #include "Vector.h" +#include "SoundSystem.h" class KeyboardState { @@ -33,4 +35,8 @@ public: float lastFrameTime; + static SoundSystem& GetSoundSystem() { return sound_system; } + +private: + static SoundSystem sound_system; }; \ No newline at end of file diff --git a/CrystalPoint.vcxproj b/CrystalPoint.vcxproj index 7784d07..87f744b 100644 --- a/CrystalPoint.vcxproj +++ b/CrystalPoint.vcxproj @@ -89,12 +89,13 @@ Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - freeglut/include + freeglut/include; openAL/include Console true - freeglut/lib + freeglut/lib; openAL/libs/Win32 + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;OpenAL32.lib;%(AdditionalDependencies) @@ -163,7 +164,8 @@ - + + @@ -181,7 +183,8 @@ - + + @@ -196,6 +199,7 @@ + diff --git a/CrystalPoint.vcxproj.filters b/CrystalPoint.vcxproj.filters index 57a4a5b..698daee 100644 --- a/CrystalPoint.vcxproj.filters +++ b/CrystalPoint.vcxproj.filters @@ -69,6 +69,12 @@ Source Files\World + + Source Files + + + Source Files + @@ -119,6 +125,12 @@ Header Files + + Header Files + + + Header Files + @@ -138,5 +150,8 @@ Resource Files + + Resource Files + \ No newline at end of file diff --git a/Enemy.cpp b/Enemy.cpp index ad5243a..61376ea 100644 --- a/Enemy.cpp +++ b/Enemy.cpp @@ -1,8 +1,8 @@ #define _USE_MATH_DEFINES #include -#include "OpenAL.h" #include "Enemy.h" #include "Model.h" +#include "CrystalPoint.h" #include Enemy::Enemy(const std::string &fileName, @@ -19,7 +19,7 @@ Enemy::Enemy(const std::string &fileName, speed = 1; radius = 10; hasTarget = false; -// openal = new OpenAL(); + hit_sound_id = CrystalPoint::GetSoundSystem().LoadSound("WAVE/Sound.wav", false); } @@ -61,14 +61,11 @@ void Enemy::inEyeSight(Vec3f & TargetPosition) bool Enemy::hasCollison(Vec3f &) { - + return false; } void Enemy::update(float delta) { -// if (!openal->isMusicPlaying()) { -// openal->playMusic(); -// } if (hasTarget) { @@ -91,5 +88,12 @@ void Enemy::update(float delta) position.z += dz; } rotation.y = atan2f(dx, dz) * 180 / M_PI; - } + } + + if (false) + { + Sound* sound = CrystalPoint::GetSoundSystem().GetSound(hit_sound_id); + sound->SetPos(position, Vec3f()); + sound->Play(); + } } diff --git a/Enemy.h b/Enemy.h index a92bb13..d7886da 100644 --- a/Enemy.h +++ b/Enemy.h @@ -3,7 +3,6 @@ #include "Entity.h" #include #include "Vector.h" -#include "OpenAL.h" class Enemy : public Entity { @@ -20,5 +19,8 @@ public: void inEyeSight(Vec3f &); bool hasCollison(Vec3f &); + +private: + int hit_sound_id; }; diff --git a/Main.cpp b/Main.cpp index d89aa26..f911678 100644 --- a/Main.cpp +++ b/Main.cpp @@ -54,6 +54,8 @@ int main(int argc, char* argv[]) CrystalPoint::width = GLUT_WINDOW_WIDTH; glutMainLoop(); + + delete app; return 0; } diff --git a/OpenAL.cpp b/OpenAL.cpp deleted file mode 100644 index 613fb7c..0000000 --- a/OpenAL.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include "OpenAL.h" -#include -#include -#include -#include -#include - -SoundSystem::SoundSystem(): - device(nullptr), - context(nullptr) -{ - device = alcOpenDevice(nullptr); - if (!device) - return; - context = alcCreateContext(device, nullptr); - if (!context) - return; - alcMakeContextCurrent(context); -} - -SoundSystem::~SoundSystem() -{ - alcMakeContextCurrent(nullptr); //Make no context current - alcDestroyContext(context); //Destroy the OpenAL Context - alcCloseDevice(device); //Close the OpenAL Device -} - - - - - -void SoundSystem::Play(ESoundID inID) -{ - ALuint buffer; - alGenBuffers(1, &buffer); //Generate one OpenAL Buffer and link to "buffer" - ALuint source; - alGenSources(1, &source); //Generate one OpenAL Source and link to "source" - if (alGetError() != AL_NO_ERROR) return ; //Error during buffer/source generation - - //Figure out the format of the WAVE file - ALenum format = 0; //The audio format (bits per sample, number of channels) - if (bitsPerSample == 8) - { - if (channels == 1) - format = AL_FORMAT_MONO8; - else if (channels == 2) - format = AL_FORMAT_STEREO8; - } - else if (bitsPerSample == 16) - { - if (channels == 1) - format = AL_FORMAT_MONO16; - else if (channels == 2) - format = AL_FORMAT_STEREO16; - } - if (!format) return; //Not valid format - - ALuint frequency = sampleRate; //The Sample Rate of the WAVE file - alBufferData(buffer, format, buf, dataSize, frequency); //Store the sound data in the OpenAL Buffer - if (alGetError() != AL_NO_ERROR) - return EndWithError("Error loading ALBuffer"); //Error during buffer loading - - //Sound setting variables - ALfloat SourcePos[] = { 0.0, 0.0, 0.0 }; //Position of the source sound - ALfloat SourceVel[] = { 0.0, 0.0, 0.0 }; //Velocity of the source sound - ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 }; //Position of the listener - ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 }; //Velocity of the listener - ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; //Orientation of the listener - //First direction vector, then vector pointing up) - //Listener - alListenerfv(AL_POSITION, ListenerPos); //Set position of the listener - alListenerfv(AL_VELOCITY, ListenerVel); //Set velocity of the listener - alListenerfv(AL_ORIENTATION, ListenerOri); //Set orientation of the listener - - //Source - alSourcei(source, AL_BUFFER, buffer); //Link the buffer to the source - alSourcef(source, AL_PITCH, 1.0f); //Set the pitch of the source - alSourcef(source, AL_GAIN, 1.0f); //Set the gain of the source - alSourcefv(source, AL_POSITION, SourcePos); //Set the position of the source - alSourcefv(source, AL_VELOCITY, SourceVel); //Set the velocity of the source - alSourcei(source, AL_LOOPING, AL_FALSE); //Set if source is looping sound - - //PLAY - alSourcePlay(source); //Play the sound buffer linked to the source - if (alGetError() != AL_NO_ERROR) return EndWithError("Error playing sound"); //Error when playing sound - system("PAUSE"); //Pause to let the sound play - - //Clean-up - fclose(fp); //Close the WAVE file - delete[] buf; //Delete the sound data buffer - alDeleteSources(1, &source); //Delete the OpenAL Source - alDeleteBuffers(1, &buffer); //Delete the OpenAL Buffer - - return ; -} - - -void SoundSystem::Pause(ESoundID inID) -{ - -} - - -void SoundSystem::Stop(ESoundID inID) -{ - -} - - - - -const char* SoundSystem::GetWaveFile(ESoundID inID) -{ - -} - -bool SoundSystem::LoadWave(ESoundID inID) -{ - const char* path = GetWaveFile(inID); - - FILE *fp = fopen(path, "rb"); //Open the WAVE file - if (!fp) - return false; // Could not open file - - //Check that the WAVE file is OK - char type[4]; - fread(type, sizeof(char), 4, fp); // Reads the first bytes in the file - if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') // Should be "RIFF" - return false; // Not RIFF - - DWORD size; - fread(&size, sizeof(DWORD), 1, fp); // Continue to read the file - fread(type, sizeof(char), 4, fp); // Continue to read the file - if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') //This part should be "WAVE" - return false; //Not WAVE - - fread(type, sizeof(char), 4, fp); //Continue to read the file - if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') //This part should be "fmt " - return false; //Not fmt - - //Now we know that the file is a acceptable WAVE file - //Info about the WAVE data is now read and stored - DWORD chunkSize; - fread(&chunkSize, sizeof(DWORD), 1, fp); - short formatType; - fread(&formatType, sizeof(short), 1, fp); - short channels; - fread(&channels, sizeof(short), 1, fp); - DWORD sampleRate; - fread(&sampleRate, sizeof(DWORD), 1, fp); - DWORD avgBytesPerSec; - fread(&avgBytesPerSec, sizeof(DWORD), 1, fp); - short bytesPerSample; - fread(&bytesPerSample, sizeof(short), 1, fp); - short bitsPerSample; - fread(&bitsPerSample, sizeof(short), 1, fp); - - fread(type, sizeof(char), 4, fp); - if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a') //This part should be "data" - return false; //not data - - DWORD dataSize; - fread(&dataSize, sizeof(DWORD), 1, fp); //The size of the sound data is read - - //Display the info about the WAVE file - std::cout << "Chunk Size: " << chunkSize << "\n"; - std::cout << "Format Type: " << formatType << "\n"; - std::cout << "Channels: " << channels << "\n"; - std::cout << "Sample Rate: " << sampleRate << "\n"; - std::cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n"; - std::cout << "Bytes Per Sample: " << bytesPerSample << "\n"; - std::cout << "Bits Per Sample: " << bitsPerSample << "\n"; - std::cout << "Data Size: " << dataSize << "\n"; - - unsigned char* buf = new unsigned char[dataSize]; //Allocate memory for the sound data - std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; //Read the sound data and display the - - return true; -} - diff --git a/OpenAL.h b/OpenAL.h deleted file mode 100644 index 35b8953..0000000 --- a/OpenAL.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -struct ALCdevice; -struct ALCcontext; - -class SoundSystem -{ -public: - enum ESoundID - { - ES_Music1, - ES_Music2 - }; - - SoundSystem(); - ~SoundSystem(); - - void Play(ESoundID inID); - void Pause(ESoundID inID); - void Stop(ESoundID inID); - - -private: - const char* GetWaveFile(ESoundID inID); - bool LoadWave(ESoundID inID); - - ALCdevice* device; - ALCcontext* context; -}; diff --git a/Sound.cpp b/Sound.cpp new file mode 100644 index 0000000..cc990da --- /dev/null +++ b/Sound.cpp @@ -0,0 +1,139 @@ +#include "Sound.h" + +#include +#include +#include + +Sound::Sound(const char* inWavPath, bool inLooping): + buffer_id(0), + source_id(0), + is_looping(inLooping) + +{ + const char* path = inWavPath; + + FILE *fp = fopen(path, "rb"); // Open the WAVE file + if (!fp) + return; // Could not open file + + // Check that the WAVE file is OK + char type[4]; + fread(type, sizeof(char), 4, fp); // Reads the first bytes in the file + if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F') // Should be "RIFF" + return; // Not RIFF + + DWORD size; + fread(&size, sizeof(DWORD), 1, fp); // Continue to read the file + fread(type, sizeof(char), 4, fp); // Continue to read the file + if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E') // This part should be "WAVE" + return; // Not WAVE + + fread(type, sizeof(char), 4, fp); // Continue to read the file + if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ') // This part should be "fmt " + return; // Not fmt + + // Now we know that the file is a acceptable WAVE file + // Info about the WAVE data is now read and stored + DWORD chunkSize; + fread(&chunkSize, sizeof(DWORD), 1, fp); + short formatType; + fread(&formatType, sizeof(short), 1, fp); + short channels; + fread(&channels, sizeof(short), 1, fp); + DWORD sampleRate; + fread(&sampleRate, sizeof(DWORD), 1, fp); + DWORD avgBytesPerSec; + fread(&avgBytesPerSec, sizeof(DWORD), 1, fp); + short bytesPerSample; + fread(&bytesPerSample, sizeof(short), 1, fp); + short bitsPerSample; + fread(&bitsPerSample, sizeof(short), 1, fp); + ALenum format = 0; // The audio format (bits per sample, number of channels) + if (bitsPerSample == 8) + { + if (channels == 1) + format = AL_FORMAT_MONO8; + else if (channels == 2) + format = AL_FORMAT_STEREO8; + } + else if (bitsPerSample == 16) + { + if (channels == 1) + format = AL_FORMAT_MONO16; + else if (channels == 2) + format = AL_FORMAT_STEREO16; + } + if (!format) + return; // Not valid format + + fread(type, sizeof(char), 4, fp); + if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a') // This part should be "data" + return; // not data + + DWORD dataSize; + fread(&dataSize, sizeof(DWORD), 1, fp); // The size of the sound data is read + + // Display the info about the WAVE file + std::cout << "Chunk Size: " << chunkSize << "\n"; + std::cout << "Format Type: " << formatType << "\n"; + std::cout << "Channels: " << channels << "\n"; + std::cout << "Sample Rate: " << sampleRate << "\n"; + std::cout << "Average Bytes Per Second: " << avgBytesPerSec << "\n"; + std::cout << "Bytes Per Sample: " << bytesPerSample << "\n"; + std::cout << "Bits Per Sample: " << bitsPerSample << "\n"; + std::cout << "Data Size: " << dataSize << "\n"; + + unsigned char* buf = new unsigned char[dataSize]; // Allocate memory for the sound data + std::cout << fread(buf, sizeof(BYTE), dataSize, fp) << " bytes loaded\n"; // Read the sound data and display the + fclose(fp); + + alGenBuffers(1, &buffer_id); // Generate one OpenAL Buffer and link to "buffer" + alGenSources(1, &source_id); // Generate one OpenAL Source and link to "source" + if (alGetError() != AL_NO_ERROR) + return; // Error during buffer/source generation + + alBufferData(buffer_id, format, buf, dataSize, sampleRate); // Store the sound data in the OpenAL Buffer + if (alGetError() != AL_NO_ERROR) + return; // Error during buffer loading + + delete[] buf; // Delete the sound data buffer +} + + +Sound::~Sound() +{ + alSourceStop(source_id); + alDeleteSources(1, &source_id); // Delete the OpenAL Source + alDeleteBuffers(1, &buffer_id); // Delete the OpenAL Buffer +} + + +void Sound::SetPos(const Vec3f& inPos, const Vec3f& inVel) +{ + alSourcei(source_id, AL_BUFFER, buffer_id); // Link the buffer to the source + alSourcef(source_id, AL_PITCH, 1.0f); // Set the pitch of the source + alSourcef(source_id, AL_GAIN, 1.0f); // Set the gain of the source + alSourcefv(source_id, AL_POSITION, inPos.v); // Set the position of the source + alSourcefv(source_id, AL_VELOCITY, inVel.v); // Set the velocity of the source + alSourcei(source_id, AL_LOOPING, is_looping ? AL_TRUE : AL_FALSE); // Set if source is looping sound +} + + +void Sound::Play() +{ + alSourcePlay(source_id); + int e = alGetError(); // != AL_NO_ERROR) return; +} + + +void Sound::Pause() +{ + alSourcePause(source_id); +} + + +void Sound::Stop() +{ + alSourceStop(source_id); +} + diff --git a/Sound.h b/Sound.h new file mode 100644 index 0000000..74e2f9f --- /dev/null +++ b/Sound.h @@ -0,0 +1,22 @@ +#pragma once + +#include "vector.h" + +class Sound +{ +public: + Sound(const char* inWavPath, bool inLooping); + ~Sound(); + + void SetPos(const Vec3f& inPos, const Vec3f& inVel); + + void Play(); + void Pause(); + void Stop(); + +private: + unsigned int buffer_id; + unsigned int source_id; + + bool is_looping; +}; \ No newline at end of file diff --git a/SoundSystem.cpp b/SoundSystem.cpp new file mode 100644 index 0000000..bd207be --- /dev/null +++ b/SoundSystem.cpp @@ -0,0 +1,56 @@ +#include "SoundSystem.h" + +#include +#include +#include + + + +SoundSystem::SoundSystem(): + device(nullptr), + context(nullptr) +{ + device = alcOpenDevice(nullptr); + if (!device) + return; + context = alcCreateContext(device, nullptr); + if (!context) + return; + alcMakeContextCurrent(context); +} + + +SoundSystem::~SoundSystem() +{ + for (auto sound : sounds) + delete sound; + alcMakeContextCurrent(nullptr); + alcDestroyContext(context); + alcCloseDevice(device); +} + + +void SoundSystem::SetListener(const Vec3f& inPos, const Vec3f& inVel, const Vec3f& inOri) +{ + ALfloat orientation[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 }; + + alListenerfv(AL_POSITION, inPos.v); + alListenerfv(AL_VELOCITY, inVel.v); + alListenerfv(AL_ORIENTATION, orientation); +} + + +unsigned int SoundSystem::LoadSound(const char* inWavPath, bool inLooping) +{ + Sound* sound = new Sound(inWavPath, inLooping); + sounds.push_back(sound); + return sounds.size() - 1; +} + + +Sound* SoundSystem::GetSound(unsigned int inID) +{ + if (inID > sounds.size()) + return nullptr; + return sounds[inID]; +} diff --git a/SoundSystem.h b/SoundSystem.h new file mode 100644 index 0000000..d6908ce --- /dev/null +++ b/SoundSystem.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include +#include "vector.h" +#include "Sound.h" + + +class SoundSystem +{ +public: + SoundSystem(); + ~SoundSystem(); + + void SetListener(const Vec3f& inPos, const Vec3f& inVel, const Vec3f& inOri); + + unsigned int LoadSound(const char* inWavPath, bool inLooping); + Sound* GetSound(unsigned int inID); + +private: + ALCdevice* device; + ALCcontext* context; + std::vector sounds; +}; diff --git a/WAVE/bond.wav b/WAVE/bond.wav new file mode 100644 index 0000000..c478afe Binary files /dev/null and b/WAVE/bond.wav differ diff --git a/World.cpp b/World.cpp index 57a5347..395a79e 100644 --- a/World.cpp +++ b/World.cpp @@ -7,7 +7,8 @@ #include #include -World::World(const std::string &fileName) +World::World(const std::string &fileName): + music_id(-1) { //Store player instance player = Player::getInstance(); @@ -113,6 +114,15 @@ World::World(const std::string &fileName) enemies.push_back(new Enemy(e["file"].asString(), position, rotation, scale)); } + + if (!v["world"]["music"].isNull()) + { + music_id = CrystalPoint::GetSoundSystem().LoadSound(v["world"]["music"].asString().c_str(), true); + Sound* music = CrystalPoint::GetSoundSystem().GetSound(music_id); + music->SetPos(Vec3f(), Vec3f()); + music->Play(); + } + } diff --git a/World.h b/World.h index 649e2d4..48f9506 100644 --- a/World.h +++ b/World.h @@ -17,6 +17,7 @@ private: Player* player; HeightMap* heightmap; Interface* interface; + int music_id; std::vector entities; std::vector enemies; diff --git a/WorldHandler.cpp b/WorldHandler.cpp index 97fa7a2..4b41fae 100644 --- a/WorldHandler.cpp +++ b/WorldHandler.cpp @@ -97,6 +97,7 @@ bool WorldHandler::isPlayerPositionValid(void) { if(!loadingWorld) return world->isPlayerPositionValid(); + return false; } float WorldHandler::getHeight(float x, float y) diff --git a/worlds/small.json b/worlds/small.json index 466db7c..274e4b6 100644 --- a/worlds/small.json +++ b/worlds/small.json @@ -1,17 +1,18 @@ { - "world": { - "heightmap": "worlds/small.png", - "object-templates": [ - { - "color":100, - "file": "models/boom/Boom.obj", - "collision": false - } - ] - }, - "player": { - "startposition": [ 20, 5, 20 ] - }, - "objects": [], - "enemies": [] + "world": { + "heightmap": "worlds/small.png", + "object-templates": [ + { + "color": 100, + "file": "models/boom/Boom.obj", + "collision": false + } + ], + "music": "WAVE/bond.wav" + }, + "player": { + "startposition": [ 20, 5, 20 ] + }, + "objects": [], + "enemies": [] } \ No newline at end of file