#include "pong.h" #include "sounds.h" int Difficulty = 1; SDL_atomic_t Ticks; bool GameGoing = true; char VersionString[256]; SDL_mutex *AudioQueueBeingModified; int AudioQueue[20]; int internal_clock() { const struct timespec Delay = { 0, 20000000 }; struct timespec Remaining; while(GameGoing == true) { SDL_AtomicAdd(&Ticks, 1); nanosleep(&Delay, &Remaining); } return(0); } int audio() { int i; Mix_Init(0); Mix_OpenAudio(48000, MIX_DEFAULT_FORMAT, 2, 1024); Mix_AllocateChannels(64); Mix_Volume(-1, 128); Mix_Chunk *Bounce = Mix_LoadWAV("resources/bounce.wav"); Mix_Chunk *TitleScreen = Mix_LoadWAV("resources/title.wav"); Mix_Chunk *Victory = Mix_LoadWAV("resources/victory.wav"); Mix_Chunk *Defeat = Mix_LoadWAV("resources/defeat.wav"); Mix_Chunk *PlayerScore = Mix_LoadWAV("resources/score_player.wav"); Mix_Chunk *EnemyScore = Mix_LoadWAV("resources/score_enemy.wav"); const struct timespec Delay = { 0, 20000000 }; struct timespec Remaining; while(GameGoing == true) { for(i = 0; i < 20; i++) { if(AudioQueue[i] != -1){ switch(AudioQueue[i]) { case 0: //Play bounce sound. Mix_PlayChannel(-1, Bounce, 0); break; case 1: //Play game over Mix_PlayChannel(-1, Defeat, 0); break; case 2: //Play win Mix_PlayChannel(-1, Victory, 0); break; case 3: //Title Screen Mix_PlayChannel(-1, TitleScreen, 0); break; case 4: //Player Score Mix_PlayChannel(-1, PlayerScore, 0); break; case 5: //Enemy Score Mix_PlayChannel(-1, EnemyScore, 0); break; case 99: //Stop All Sounds Mix_HaltChannel(-1); break; default: break; } SDL_LockMutex(AudioQueueBeingModified); AudioQueue[i] = -1; SDL_UnlockMutex(AudioQueueBeingModified); } } nanosleep(&Delay, &Remaining); } return(0); } bool play_audio(int SoundEffect) { unsigned int i; SDL_LockMutex(AudioQueueBeingModified); for(i = 1; i != 20; i++) { if (AudioQueue[i-1] == -1) { AudioQueue[i-1] = AudioQueue[i]; } } for(i = 0; AudioQueue[i] != -1; i++) { if(i > sizeof(AudioQueue)) { SDL_UnlockMutex(AudioQueueBeingModified); return false; } } AudioQueue[i] = SoundEffect; SDL_UnlockMutex(AudioQueueBeingModified); return true; } int main(int argc, char *argv[]) { //Raylib Init InitWindow(1280, 720, "Pong"); SetTargetFPS(60); SetExitKey(KEY_NULL); Image Icon = LoadImage("resources/ball.png"); SetWindowIcon(Icon); SetWindowState(FLAG_VSYNC_HINT); SetWindowState(FLAG_WINDOW_RESIZABLE); SetWindowMinSize(1280, 720); //SDL Init SDL_Init(SDL_INIT_AUDIO); //Init Variables strncpy(VersionString, "Version 0.2 - AEOLUS", sizeof(VersionString)); //Populate Audio Queue for(unsigned int i = 0; i < 20; i++) { AudioQueue[i] = -1; } AudioQueueBeingModified = SDL_CreateMutex(); // Init Threads SDL_AtomicSet(&Ticks, 0); SDL_Thread *InternalClock = SDL_CreateThread(internal_clock, "Internal Clock", NULL); SDL_Thread *AudioThread = SDL_CreateThread(audio, "Audio", NULL); // Launch Game while (GameGoing == true) { switch(title_screen()) { case 0: //Versus play_audio(STOP_ALL_SOUNDS); versus_main(); break; case 1: //Marathon play_audio(STOP_ALL_SOUNDS); marathon_main(); break; default: break; } } GameGoing = false; // Make sure the game is going to end. SDL_WaitThread(InternalClock, NULL); SDL_WaitThread(AudioThread, NULL); SDL_Quit(); CloseWindow(); return(0); }