| 
								
							 | 
							
								/**********************************************************************************************
							 | 
						
						
						
							| 
								
							 | 
							
								*
							 | 
						
						
						
							| 
								
							 | 
							
								*   raylib - Advance Game template
							 | 
						
						
						
							| 
								
							 | 
							
								*
							 | 
						
						
						
							| 
								
							 | 
							
								*   Gameplay Screen Functions Definitions (Init, Update, Draw, Unload)
							 | 
						
						
						
							| 
								
							 | 
							
								*
							 | 
						
						
						
							| 
								
							 | 
							
								*   Copyright (c) 2014 Ramon Santamaria (@raysan5)
							 | 
						
						
						
							| 
								
							 | 
							
								*
							 | 
						
						
						
							| 
								
							 | 
							
								*   This software is provided "as-is", without any express or implied warranty. In no event
							 | 
						
						
						
							| 
								
							 | 
							
								*   will the authors be held liable for any damages arising from the use of this software.
							 | 
						
						
						
							| 
								
							 | 
							
								*
							 | 
						
						
						
							| 
								
							 | 
							
								*   Permission is granted to anyone to use this software for any purpose, including commercial
							 | 
						
						
						
							| 
								
							 | 
							
								*   applications, and to alter it and redistribute it freely, subject to the following restrictions:
							 | 
						
						
						
							| 
								
							 | 
							
								*
							 | 
						
						
						
							| 
								
							 | 
							
								*     1. The origin of this software must not be misrepresented; you must not claim that you
							 | 
						
						
						
							| 
								
							 | 
							
								*     wrote the original software. If you use this software in a product, an acknowledgment
							 | 
						
						
						
							| 
								
							 | 
							
								*     in the product documentation would be appreciated but is not required.
							 | 
						
						
						
							| 
								
							 | 
							
								*
							 | 
						
						
						
							| 
								
							 | 
							
								*     2. Altered source versions must be plainly marked as such, and must not be misrepresented
							 | 
						
						
						
							| 
								
							 | 
							
								*     as being the original software.
							 | 
						
						
						
							| 
								
							 | 
							
								*
							 | 
						
						
						
							| 
								
							 | 
							
								*     3. This notice may not be removed or altered from any source distribution.
							 | 
						
						
						
							| 
								
							 | 
							
								*
							 | 
						
						
						
							| 
								
							 | 
							
								**********************************************************************************************/
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								#include "raylib.h"
							 | 
						
						
						
							| 
								
							 | 
							
								#include "screens.h"
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								#include <stdio.h>
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								#include <stdlib.h>                 // Required for: malloc(), free()
							 | 
						
						
						
							| 
								
							 | 
							
								#include <math.h>                   // Required for: sqrtf(), asinf()
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								#define MAX_SAMPLES_SPEED       7   // Max speed for samples movement
							 | 
						
						
						
							| 
								
							 | 
							
								#define MIN_SAMPLES_SPEED       3   // Min speed for samples movement
							 | 
						
						
						
							| 
								
							 | 
							
								#define SAMPLES_SPACING       100   // Separation between samples in pixels
							 | 
						
						
						
							| 
								
							 | 
							
								#define SAMPLES_MULTIPLIER    700   // Defines sample data scaling value (it would be adjusted to MAX_GAME_HEIGHT)
							 | 
						
						
						
							| 
								
							 | 
							
								#define MAX_GAME_HEIGHT       400   // Defines max possible amplitude between samples (game area)
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								//----------------------------------------------------------------------------------
							 | 
						
						
						
							| 
								
							 | 
							
								// Types and Structures Definition
							 | 
						
						
						
							| 
								
							 | 
							
								//----------------------------------------------------------------------------------
							 | 
						
						
						
							| 
								
							 | 
							
								typedef struct Player {
							 | 
						
						
						
							| 
								
							 | 
							
								    Vector2 position;
							 | 
						
						
						
							| 
								
							 | 
							
								    Vector2 speed;
							 | 
						
						
						
							| 
								
							 | 
							
								    int width;
							 | 
						
						
						
							| 
								
							 | 
							
								    int height;
							 | 
						
						
						
							| 
								
							 | 
							
								    Color color;
							 | 
						
						
						
							| 
								
							 | 
							
								} Player;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								typedef struct Sample {
							 | 
						
						
						
							| 
								
							 | 
							
								    Vector2 position;
							 | 
						
						
						
							| 
								
							 | 
							
								    float value;            // Raw audio sample value (normalized)
							 | 
						
						
						
							| 
								
							 | 
							
								    int radius;
							 | 
						
						
						
							| 
								
							 | 
							
								    bool active;            // Define if sample is active (can be collected)
							 | 
						
						
						
							| 
								
							 | 
							
								    bool collected;         // Define if sample has been collected
							 | 
						
						
						
							| 
								
							 | 
							
								    bool renderable;        // Define if sample should be rendered
							 | 
						
						
						
							| 
								
							 | 
							
								    Color color;
							 | 
						
						
						
							| 
								
							 | 
							
								} Sample;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								//----------------------------------------------------------------------------------
							 | 
						
						
						
							| 
								
							 | 
							
								// Global Variables Definition (local to this module)
							 | 
						
						
						
							| 
								
							 | 
							
								//----------------------------------------------------------------------------------
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								// Gameplay screen global variables
							 | 
						
						
						
							| 
								
							 | 
							
								static int framesCounter;
							 | 
						
						
						
							| 
								
							 | 
							
								static int finishScreen;
							 | 
						
						
						
							| 
								
							 | 
							
								static bool pause;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								// Player variables
							 | 
						
						
						
							| 
								
							 | 
							
								static Player player;
							 | 
						
						
						
							| 
								
							 | 
							
								static Rectangle playerArea;    // Define player movement area (and sample collection limits)
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								static float warpCounter;       // Time warp counter
							 | 
						
						
						
							| 
								
							 | 
							
								static float synchro;           // Calculates collected samples relation [0..1]
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								static int combo;
							 | 
						
						
						
							| 
								
							 | 
							
								static int maxCombo;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								static Rectangle waveRec;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								// Samples variables
							 | 
						
						
						
							| 
								
							 | 
							
								static Sample *samples;         // Game samples
							 | 
						
						
						
							| 
								
							 | 
							
								static int totalSamples;        // Total game samples (proportional to waveData num samples)
							 | 
						
						
						
							| 
								
							 | 
							
								static int collectedSamples;    // Samples collected by player
							 | 
						
						
						
							| 
								
							 | 
							
								static int currentSample;       // Last sample to go through player collect area
							 | 
						
						
						
							| 
								
							 | 
							
								static float samplesSpeed;      // All samples move at the same speed
							 | 
						
						
						
							| 
								
							 | 
							
								static float waveTime;          // Total sample time in ms
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								// Resources variables
							 | 
						
						
						
							| 
								
							 | 
							
								static Texture2D texBackground;
							 | 
						
						
						
							| 
								
							 | 
							
								static Texture2D texPlayer;
							 | 
						
						
						
							| 
								
							 | 
							
								static Texture2D texSampleSmall;
							 | 
						
						
						
							| 
								
							 | 
							
								static Texture2D texSampleMid;
							 | 
						
						
						
							| 
								
							 | 
							
								static Texture2D texSampleBig;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								static RenderTexture2D waveTarget;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								static Sound fxSampleOn;        // Collected sample sound
							 | 
						
						
						
							| 
								
							 | 
							
								static Sound fxSampleOff;       // Miss sample sound
							 | 
						
						
						
							| 
								
							 | 
							
								static Sound fxPause;           // Pause sound
							 | 
						
						
						
							| 
								
							 | 
							
								// Debug variables
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								//------------------------------------------------------------------------------------
							 | 
						
						
						
							| 
								
							 | 
							
								// Module Functions Declaration (local)
							 | 
						
						
						
							| 
								
							 | 
							
								//------------------------------------------------------------------------------------
							 | 
						
						
						
							| 
								
							 | 
							
								static void DrawSamplesMap(Sample *samples, int sampleCount, int playedSamples, Rectangle bounds, Color color);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								//----------------------------------------------------------------------------------
							 | 
						
						
						
							| 
								
							 | 
							
								// Gameplay Screen Functions Definition
							 | 
						
						
						
							| 
								
							 | 
							
								//----------------------------------------------------------------------------------
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								// Gameplay Screen Initialization logic
							 | 
						
						
						
							| 
								
							 | 
							
								void InitGameplayScreen(void)
							 | 
						
						
						
							| 
								
							 | 
							
								{
							 | 
						
						
						
							| 
								
							 | 
							
								    framesCounter = 0;
							 | 
						
						
						
							| 
								
							 | 
							
								    finishScreen = 0;
							 | 
						
						
						
							| 
								
							 | 
							
								    pause = false;
							 | 
						
						
						
							| 
								
							 | 
							
								    endingStatus = 0;
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    // Textures loading
							 | 
						
						
						
							| 
								
							 | 
							
								    texBackground = LoadTexture("resources/textures/background_gameplay.png");
							 | 
						
						
						
							| 
								
							 | 
							
								    texPlayer = LoadTexture("resources/textures/player.png");
							 | 
						
						
						
							| 
								
							 | 
							
								    texSampleSmall = LoadTexture("resources/textures/sample_small.png");
							 | 
						
						
						
							| 
								
							 | 
							
								    texSampleMid = LoadTexture("resources/textures/sample_mid.png");
							 | 
						
						
						
							| 
								
							 | 
							
								    texSampleBig = LoadTexture("resources/textures/sample_big.png");
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    waveRec = (Rectangle){ 32, 32, 1280 - 64, 105 };
							 | 
						
						
						
							| 
								
							 | 
							
								    waveTarget = LoadRenderTexture(waveRec.width, waveRec.height);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Sound loading
							 | 
						
						
						
							| 
								
							 | 
							
								    fxSampleOn = LoadSound("resources/audio/sample_on.wav");
							 | 
						
						
						
							| 
								
							 | 
							
								    fxSampleOff = LoadSound("resources/audio/sample_off.wav");
							 | 
						
						
						
							| 
								
							 | 
							
								    fxPause = LoadSound("resources/audio/pause.wav");
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    SetSoundVolume(fxSampleOn, 0.6f);
							 | 
						
						
						
							| 
								
							 | 
							
								    SetSoundVolume(fxPause, 0.5f);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Initialize player data
							 | 
						
						
						
							| 
								
							 | 
							
								    playerArea = (Rectangle){ 200, 160, 80, 400 };
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    player.width = 20;
							 | 
						
						
						
							| 
								
							 | 
							
								    player.height = 60;
							 | 
						
						
						
							| 
								
							 | 
							
								    player.speed = (Vector2){ 15, 15 };
							 | 
						
						
						
							| 
								
							 | 
							
								    player.color = GOLD;
							 | 
						
						
						
							| 
								
							 | 
							
								    player.position = (Vector2){ playerArea.x + playerArea.width/2 - texPlayer.width/2, 
							 | 
						
						
						
							| 
								
							 | 
							
								                                 playerArea.y + playerArea.height/2 - texPlayer.height/2 };
							 | 
						
						
						
							| 
								
							 | 
							
								                                 
							 | 
						
						
						
							| 
								
							 | 
							
								    warpCounter = 395;
							 | 
						
						
						
							| 
								
							 | 
							
								    synchro = 0.2f;
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    combo = 0;
							 | 
						
						
						
							| 
								
							 | 
							
								    maxCombo = 0;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Initialize wave and samples data
							 | 
						
						
						
							| 
								
							 | 
							
								    Wave wave = LoadWave("resources/audio/wave.ogg");
							 | 
						
						
						
							| 
								
							 | 
							
								    float *waveData = GetWaveData(wave);        // TODO: Be careful with channels!
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    // We calculate the required parameters to adjust audio time to gameplay time
							 | 
						
						
						
							| 
								
							 | 
							
								    // that way samples collected correspond to audio playing
							 | 
						
						
						
							| 
								
							 | 
							
								    // Synchonization is not perfect due to possible rounding issues (float to int)
							 | 
						
						
						
							| 
								
							 | 
							
								    waveTime = wave.sampleCount/wave.sampleRate;     // Total sample time in seconds
							 | 
						
						
						
							| 
								
							 | 
							
								    float requiredSamples = (MAX_SAMPLES_SPEED*waveTime*60 - 1000)/SAMPLES_SPACING;
							 | 
						
						
						
							| 
								
							 | 
							
								    int samplesDivision = (int)(wave.sampleCount/requiredSamples);
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    totalSamples = wave.sampleCount/samplesDivision;
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    // We don't need wave any more (already got waveData)
							 | 
						
						
						
							| 
								
							 | 
							
								    UnloadWave(wave);
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    collectedSamples = 0;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Init samples
							 | 
						
						
						
							| 
								
							 | 
							
								    samples = (Sample *)malloc(totalSamples*sizeof(Sample));
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Normalize wave data (min vs max values) to scale properly
							 | 
						
						
						
							| 
								
							 | 
							
								    float minSampleValue = 0.0f;
							 | 
						
						
						
							| 
								
							 | 
							
								    float maxSampleValue = 0.0f;
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    for (int i = 0; i < totalSamples; i++)
							 | 
						
						
						
							| 
								
							 | 
							
								    {
							 | 
						
						
						
							| 
								
							 | 
							
								        if (waveData[i*samplesDivision] < minSampleValue) minSampleValue = waveData[i*samplesDivision];
							 | 
						
						
						
							| 
								
							 | 
							
								        if (waveData[i*samplesDivision] > maxSampleValue) maxSampleValue = waveData[i*samplesDivision];
							 | 
						
						
						
							| 
								
							 | 
							
								    }
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    float sampleScaleFactor = 1.0f/(maxSampleValue - minSampleValue);  // 400 pixels maximum size
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Initialize samples
							 | 
						
						
						
							| 
								
							 | 
							
								    for (int i = 0; i < totalSamples; i++)
							 | 
						
						
						
							| 
								
							 | 
							
								    {
							 | 
						
						
						
							| 
								
							 | 
							
								        samples[i].value = waveData[i*samplesDivision]*sampleScaleFactor;   // Normalized value [-1.0..1.0]
							 | 
						
						
						
							| 
								
							 | 
							
								        samples[i].position.x = player.position.x + 1000 + i*SAMPLES_SPACING;
							 | 
						
						
						
							| 
								
							 | 
							
								        
							 | 
						
						
						
							| 
								
							 | 
							
								        samples[i].position.y = GetScreenHeight()/2 + samples[i].value*SAMPLES_MULTIPLIER;
							 | 
						
						
						
							| 
								
							 | 
							
								        
							 | 
						
						
						
							| 
								
							 | 
							
								        if (samples[i].position.y > GetScreenHeight()/2 + MAX_GAME_HEIGHT/2) samples[i].position.y = GetScreenHeight()/2 - MAX_GAME_HEIGHT/2;
							 | 
						
						
						
							| 
								
							 | 
							
								        else if (samples[i].position.y < GetScreenHeight()/2 - MAX_GAME_HEIGHT/2) samples[i].position.y = GetScreenHeight()/2 + MAX_GAME_HEIGHT/2;
							 | 
						
						
						
							| 
								
							 | 
							
								        
							 | 
						
						
						
							| 
								
							 | 
							
								        samples[i].radius = 6;
							 | 
						
						
						
							| 
								
							 | 
							
								        samples[i].active = true;
							 | 
						
						
						
							| 
								
							 | 
							
								        samples[i].collected = false;
							 | 
						
						
						
							| 
								
							 | 
							
								        samples[i].color = RED;
							 | 
						
						
						
							| 
								
							 | 
							
								        samples[i].renderable = false;
							 | 
						
						
						
							| 
								
							 | 
							
								    }
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    samplesSpeed = MAX_SAMPLES_SPEED;
							 | 
						
						
						
							| 
								
							 | 
							
								    currentSample = 0;
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    //FILE *samplesFile = fopen("resources/samples.data", "wb");
							 | 
						
						
						
							| 
								
							 | 
							
								    //fwrite(samples, totalSamples*sizeof(Sample), 1, samplesFile);
							 | 
						
						
						
							| 
								
							 | 
							
								    //fclose(samplesFile);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // We already saved the samples we needed for the game, we can free waveData
							 | 
						
						
						
							| 
								
							 | 
							
								    free(waveData);
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    // Load and start playing music
							 | 
						
						
						
							| 
								
							 | 
							
								    // NOTE: Music is loaded in main code base
							 | 
						
						
						
							| 
								
							 | 
							
								    StopMusicStream(music);
							 | 
						
						
						
							| 
								
							 | 
							
								    PlayMusicStream(music);
							 | 
						
						
						
							| 
								
							 | 
							
								}
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								// Gameplay Screen Update logic
							 | 
						
						
						
							| 
								
							 | 
							
								void UpdateGameplayScreen(void)
							 | 
						
						
						
							| 
								
							 | 
							
								{
							 | 
						
						
						
							| 
								
							 | 
							
								    if (IsKeyPressed('P'))
							 | 
						
						
						
							| 
								
							 | 
							
								    {
							 | 
						
						
						
							| 
								
							 | 
							
								        PlaySound(fxPause);
							 | 
						
						
						
							| 
								
							 | 
							
								        pause = !pause;
							 | 
						
						
						
							| 
								
							 | 
							
								        
							 | 
						
						
						
							| 
								
							 | 
							
								        if (pause) PauseMusicStream(music);
							 | 
						
						
						
							| 
								
							 | 
							
								        else ResumeMusicStream(music);
							 | 
						
						
						
							| 
								
							 | 
							
								    }
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    if (!pause)
							 | 
						
						
						
							| 
								
							 | 
							
								    {
							 | 
						
						
						
							| 
								
							 | 
							
								        framesCounter++;        // Time starts counting to awake enemies
							 | 
						
						
						
							| 
								
							 | 
							
								        
							 | 
						
						
						
							| 
								
							 | 
							
								        // Player movement logic (mouse)
							 | 
						
						
						
							| 
								
							 | 
							
								        player.position.y = GetMousePosition().y;
							 | 
						
						
						
							| 
								
							 | 
							
								        
							 | 
						
						
						
							| 
								
							 | 
							
								        // Player movement logic (keyboard)
							 | 
						
						
						
							| 
								
							 | 
							
								        if (IsKeyDown(KEY_W)) player.position.y -= player.speed.y;
							 | 
						
						
						
							| 
								
							 | 
							
								        else if (IsKeyDown(KEY_S)) player.position.y += player.speed.y;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								        // Player movement logic (gamepad)
							 | 
						
						
						
							| 
								
							 | 
							
								        /*
							 | 
						
						
						
							| 
								
							 | 
							
								        if (IsGamepadAvailable(GAMEPAD_PLAYER1))
							 | 
						
						
						
							| 
								
							 | 
							
								        {
							 | 
						
						
						
							| 
								
							 | 
							
								            Vector2 movement = { 0.0f };
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            movement.x = GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_LEFT_X);
							 | 
						
						
						
							| 
								
							 | 
							
								            movement.y = GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_LEFT_Y);
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            player.position.x += movement.x*0.1f;   // Scale gamepad movement value
							 | 
						
						
						
							| 
								
							 | 
							
								            player.position.y += movement.y*0.1f;   // Scale gamepad movement value
							 | 
						
						
						
							| 
								
							 | 
							
								        }
							 | 
						
						
						
							| 
								
							 | 
							
								        */
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								        // Player logic: check player area limits
							 | 
						
						
						
							| 
								
							 | 
							
								        if (player.position.x < playerArea.x) player.position.x = playerArea.x;
							 | 
						
						
						
							| 
								
							 | 
							
								        else if ((player.position.x + player.width) > (playerArea.x + playerArea.width)) player.position.x = playerArea.x + playerArea.width - player.width;
							 | 
						
						
						
							| 
								
							 | 
							
								        
							 | 
						
						
						
							| 
								
							 | 
							
								        if (player.position.y < playerArea.y) player.position.y = playerArea.y;
							 | 
						
						
						
							| 
								
							 | 
							
								        else if ((player.position.y + player.height) > (playerArea.y + playerArea.height)) player.position.y = playerArea.y + playerArea.height - player.height;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								        // Samples logic
							 | 
						
						
						
							| 
								
							 | 
							
								        for (int i = 0; i < totalSamples; i++)
							 | 
						
						
						
							| 
								
							 | 
							
								        {
							 | 
						
						
						
							| 
								
							 | 
							
								            // Samples movement logic
							 | 
						
						
						
							| 
								
							 | 
							
								            samples[i].position.x -= samplesSpeed;
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            if (((samples[i].position.x + samples[i].radius) > -SAMPLES_SPACING) && 
							 | 
						
						
						
							| 
								
							 | 
							
								                ((samples[i].position.x - samples[i].radius) < GetScreenWidth())) samples[i].renderable = true;
							 | 
						
						
						
							| 
								
							 | 
							
								            else samples[i].renderable = false;
							 | 
						
						
						
							| 
								
							 | 
							
								               
							 | 
						
						
						
							| 
								
							 | 
							
								            // Samples catch logic
							 | 
						
						
						
							| 
								
							 | 
							
								            if (!samples[i].collected && CheckCollisionCircleRec(samples[i].position, samples[i].radius, (Rectangle){ (int)player.position.x, (int)player.position.y, player.width, player.height }))
							 | 
						
						
						
							| 
								
							 | 
							
								            {
							 | 
						
						
						
							| 
								
							 | 
							
								                samples[i].collected = true;
							 | 
						
						
						
							| 
								
							 | 
							
								                collectedSamples++;
							 | 
						
						
						
							| 
								
							 | 
							
								                synchro += 0.02;
							 | 
						
						
						
							| 
								
							 | 
							
								                
							 | 
						
						
						
							| 
								
							 | 
							
								                combo++;
							 | 
						
						
						
							| 
								
							 | 
							
								                if (combo > maxCombo) maxCombo = combo;
							 | 
						
						
						
							| 
								
							 | 
							
								                
							 | 
						
						
						
							| 
								
							 | 
							
								                if (synchro >= 1.0f) synchro = 1.0f;
							 | 
						
						
						
							| 
								
							 | 
							
								                
							 | 
						
						
						
							| 
								
							 | 
							
								                // Set sound pitch depending on sample position (base pitch: 1.0f)
							 | 
						
						
						
							| 
								
							 | 
							
								                // NOTE: waveData[i*WAVE_SAMPLES_DIV] is scaled to [0.3..1.7]
							 | 
						
						
						
							| 
								
							 | 
							
								                SetSoundPitch(fxSampleOn, samples[i].value*1.4f + 0.7f);
							 | 
						
						
						
							| 
								
							 | 
							
								                
							 | 
						
						
						
							| 
								
							 | 
							
								                PlaySound(fxSampleOn);
							 | 
						
						
						
							| 
								
							 | 
							
								            }
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            if ((samples[i].position.x - samples[i].radius) < player.position.x)
							 | 
						
						
						
							| 
								
							 | 
							
								            {
							 | 
						
						
						
							| 
								
							 | 
							
								                currentSample = i;  // Register last sample going out range
							 | 
						
						
						
							| 
								
							 | 
							
								                
							 | 
						
						
						
							| 
								
							 | 
							
								                if (samples[i].active)
							 | 
						
						
						
							| 
								
							 | 
							
								                {
							 | 
						
						
						
							| 
								
							 | 
							
								                    samples[i].active = false;
							 | 
						
						
						
							| 
								
							 | 
							
								                    
							 | 
						
						
						
							| 
								
							 | 
							
								                    if (!samples[i].collected)
							 | 
						
						
						
							| 
								
							 | 
							
								                    {
							 | 
						
						
						
							| 
								
							 | 
							
								                        synchro -= 0.05f;
							 | 
						
						
						
							| 
								
							 | 
							
								                        PlaySound(fxSampleOff);
							 | 
						
						
						
							| 
								
							 | 
							
								                        combo = 0;
							 | 
						
						
						
							| 
								
							 | 
							
								                    }
							 | 
						
						
						
							| 
								
							 | 
							
								                }
							 | 
						
						
						
							| 
								
							 | 
							
								            }
							 | 
						
						
						
							| 
								
							 | 
							
								        }
							 | 
						
						
						
							| 
								
							 | 
							
								        
							 | 
						
						
						
							| 
								
							 | 
							
								        if (IsKeyDown(KEY_SPACE) && (warpCounter > 0))
							 | 
						
						
						
							| 
								
							 | 
							
								        {
							 | 
						
						
						
							| 
								
							 | 
							
								            warpCounter--;
							 | 
						
						
						
							| 
								
							 | 
							
								            if (warpCounter < 0) warpCounter = 0;
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            samplesSpeed -= 0.1f;
							 | 
						
						
						
							| 
								
							 | 
							
								            if (samplesSpeed <= MIN_SAMPLES_SPEED) samplesSpeed = MIN_SAMPLES_SPEED;
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            SetMusicPitch(music, samplesSpeed/MAX_SAMPLES_SPEED);
							 | 
						
						
						
							| 
								
							 | 
							
								        }
							 | 
						
						
						
							| 
								
							 | 
							
								        else
							 | 
						
						
						
							| 
								
							 | 
							
								        {
							 | 
						
						
						
							| 
								
							 | 
							
								            warpCounter++;
							 | 
						
						
						
							| 
								
							 | 
							
								            if (warpCounter > 395) warpCounter = 395;
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            samplesSpeed += 0.1f;
							 | 
						
						
						
							| 
								
							 | 
							
								            if (samplesSpeed >= MAX_SAMPLES_SPEED) samplesSpeed = MAX_SAMPLES_SPEED;
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            SetMusicPitch(music, samplesSpeed/MAX_SAMPLES_SPEED);
							 | 
						
						
						
							| 
								
							 | 
							
								        }
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								        // Check ending conditions
							 | 
						
						
						
							| 
								
							 | 
							
								        if (currentSample >= totalSamples - 1)
							 | 
						
						
						
							| 
								
							 | 
							
								        {
							 | 
						
						
						
							| 
								
							 | 
							
								            endingStatus = 1;           // Win
							 | 
						
						
						
							| 
								
							 | 
							
								            finishScreen = 1;
							 | 
						
						
						
							| 
								
							 | 
							
								        }
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								        if (synchro <= 0.0f)
							 | 
						
						
						
							| 
								
							 | 
							
								        {
							 | 
						
						
						
							| 
								
							 | 
							
								            synchro = 0.0f;
							 | 
						
						
						
							| 
								
							 | 
							
								            endingStatus = 2;           // Loose
							 | 
						
						
						
							| 
								
							 | 
							
								            finishScreen = 1;
							 | 
						
						
						
							| 
								
							 | 
							
								        }
							 | 
						
						
						
							| 
								
							 | 
							
								    }
							 | 
						
						
						
							| 
								
							 | 
							
								}
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								// Gameplay Screen Draw logic
							 | 
						
						
						
							| 
								
							 | 
							
								void DrawGameplayScreen(void)
							 | 
						
						
						
							| 
								
							 | 
							
								{
							 | 
						
						
						
							| 
								
							 | 
							
								    // Draw background
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawTexture(texBackground, 0, 0, WHITE);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Screen elements drawing
							 | 
						
						
						
							| 
								
							 | 
							
								    //DrawRectangleLines(playerArea.x, playerArea.y, playerArea.width, playerArea.height, BLUE);
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawRectangle(0, GetScreenHeight()/2 - 1, GetScreenWidth(), 2, Fade(BLUE, 0.3f));
							 | 
						
						
						
							| 
								
							 | 
							
								    //DrawRectangleLines(0, GetScreenHeight()/2 - MAX_GAME_HEIGHT/2, GetScreenWidth(), MAX_GAME_HEIGHT, GRAY);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Draw samples
							 | 
						
						
						
							| 
								
							 | 
							
								    for (int i = 0; i < totalSamples - 1; i++)
							 | 
						
						
						
							| 
								
							 | 
							
								    {
							 | 
						
						
						
							| 
								
							 | 
							
								        if (samples[i].renderable)
							 | 
						
						
						
							| 
								
							 | 
							
								        {
							 | 
						
						
						
							| 
								
							 | 
							
								            Color col = samples[i].color;
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            if (i < (currentSample + 1)) col = Fade(DARKGRAY, 0.5f);
							 | 
						
						
						
							| 
								
							 | 
							
								            else col = WHITE;
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            if (!samples[i].collected) 
							 | 
						
						
						
							| 
								
							 | 
							
								            {
							 | 
						
						
						
							| 
								
							 | 
							
								                //DrawCircleV(samples[i].position, samples[i].radius, col);
							 | 
						
						
						
							| 
								
							 | 
							
								                
							 | 
						
						
						
							| 
								
							 | 
							
								                if (combo > 30) DrawTexture(texSampleSmall, samples[i].position.x - texSampleSmall.width/2, samples[i].position.y - texSampleSmall.height/2, col);
							 | 
						
						
						
							| 
								
							 | 
							
								                else if (combo > 15) DrawTexture(texSampleMid, samples[i].position.x - texSampleMid.width/2, samples[i].position.y - texSampleMid.height/2, col);
							 | 
						
						
						
							| 
								
							 | 
							
								                else DrawTexture(texSampleBig, samples[i].position.x - texSampleBig.width/2, samples[i].position.y - texSampleBig.height/2, col);
							 | 
						
						
						
							| 
								
							 | 
							
								            }
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            if (i < (currentSample + 1)) col = Fade(GRAY, 0.3f);
							 | 
						
						
						
							| 
								
							 | 
							
								            else col = Fade(RED, 0.5f);
							 | 
						
						
						
							| 
								
							 | 
							
								            
							 | 
						
						
						
							| 
								
							 | 
							
								            // Draw line between samples
							 | 
						
						
						
							| 
								
							 | 
							
								            DrawLineEx(samples[i].position, samples[i + 1].position, 3.0f, col);
							 | 
						
						
						
							| 
								
							 | 
							
								        }
							 | 
						
						
						
							| 
								
							 | 
							
								    }
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Draw player
							 | 
						
						
						
							| 
								
							 | 
							
								    //DrawRectangle((int)player.position.x, (int)player.position.y, player.width, player.height, player.color);
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawTexture(texPlayer, player.position.x - 32, player.position.y - 24, WHITE);
							 | 
						
						
						
							| 
								
							 | 
							
								 
							 | 
						
						
						
							| 
								
							 | 
							
								    // Draw pause message
							 | 
						
						
						
							| 
								
							 | 
							
								    if (pause) DrawTextEx(font, "WAVE PAUSED", (Vector2){ 235, 400 }, font.baseSize*2, 0, WHITE);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Draw number of samples
							 | 
						
						
						
							| 
								
							 | 
							
								    //DrawText(FormatText("%05i", collectedSamples), 900, 200, 40, GRAY);
							 | 
						
						
						
							| 
								
							 | 
							
								    //DrawText(FormatText("%05i", totalSamples), 900, 250, 40, GRAY);
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawTextEx(font, FormatText("%05i / %05i", collectedSamples, totalSamples), (Vector2){810, 170}, font.baseSize, -2, SKYBLUE);
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    // Draw combo
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawTextEx(font, FormatText("Combo: %02i [max: %02i]", combo, maxCombo), (Vector2){200, 170}, font.baseSize/2, -2, SKYBLUE);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Draw synchonicity level
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawRectangle(99, 622, 395, 32, Fade(RAYWHITE, 0.8f));
							 | 
						
						
						
							| 
								
							 | 
							
								        
							 | 
						
						
						
							| 
								
							 | 
							
								    if (synchro <= 0.3f) DrawRectangle(99, 622, synchro*395, 32, Fade(RED, 0.8f));
							 | 
						
						
						
							| 
								
							 | 
							
								    else if (synchro <= 0.8f) DrawRectangle(99, 622, synchro*395, 32, Fade(ORANGE,0.8f));
							 | 
						
						
						
							| 
								
							 | 
							
								    else if (synchro < 1.0f) DrawRectangle(99, 622, synchro*395, 32, Fade(LIME,0.8f));
							 | 
						
						
						
							| 
								
							 | 
							
								    else DrawRectangle(99, 622, synchro*395, 32, Fade(GREEN, 0.9f));
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawRectangleLines(99, 622, 395, 32, MAROON);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    if (synchro == 1.0f) DrawTextEx(font, FormatText("%02i%%", (int)(synchro*100)), (Vector2){99 + 390, 600}, font.baseSize, -2, GREEN);
							 | 
						
						
						
							| 
								
							 | 
							
								    else DrawTextEx(font, FormatText("%02i%%", (int)(synchro*100)), (Vector2){99 + 390, 600}, font.baseSize, -2, SKYBLUE);
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    // Draw time warp coool-down bar
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawRectangle(754, 622, 395, 32, Fade(RAYWHITE, 0.8f));
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawRectangle(754, 622, warpCounter, 32, Fade(SKYBLUE, 0.8f));
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawRectangleLines(754, 622, 395, 32, DARKGRAY);
							 | 
						
						
						
							| 
								
							 | 
							
								    //DrawText(FormatText("%02i%%", (int)(synchro*100)), 754 + 410, 628, 20, DARKGRAY);
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawTextEx(font, FormatText("%02i%%", (int)((float)warpCounter/395.0f*100.0f)), (Vector2){754 + 390, 600}, font.baseSize, -2, SKYBLUE);
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    // Draw wave
							 | 
						
						
						
							| 
								
							 | 
							
								    // NOTE: Old drawing method, replaced by rendertarget      
							 | 
						
						
						
							| 
								
							 | 
							
								    //DrawSamplesMap(samples, totalSamples, currentSample, waveRec, MAROON);
							 | 
						
						
						
							| 
								
							 | 
							
								    //DrawRectangle(waveRec.x + (int)currentSample*1240/totalSamples, waveRec.y, 2, 99, DARKGRAY);
							 | 
						
						
						
							| 
								
							 | 
							
								    //DrawRectangleLines(20, 20, 1240, 140, DARKGRAY);
							 | 
						
						
						
							| 
								
							 | 
							
								    //DrawRectangle(20, 150, (float)currentSample/totalSamples*1240, 10, GRAY);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Draw wave using render target
							 | 
						
						
						
							| 
								
							 | 
							
								    ClearBackground(BLANK);
							 | 
						
						
						
							| 
								
							 | 
							
								    BeginTextureMode(waveTarget);
							 | 
						
						
						
							| 
								
							 | 
							
								        DrawSamplesMap(samples, totalSamples, currentSample, (Rectangle){ 0, 0, waveTarget.texture.width, waveTarget.texture.height }, MAROON);
							 | 
						
						
						
							| 
								
							 | 
							
								    EndTextureMode();
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // TODO: Apply antialiasing shader
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawTextureEx(waveTarget.texture, (Vector2){ waveRec.x, waveRec.y }, 0.0f, 1.0f, WHITE);
							 | 
						
						
						
							| 
								
							 | 
							
								    DrawRectangle(waveRec.x + (int)currentSample*1215/totalSamples, waveRec.y, 2, 99, DARKGRAY);
							 | 
						
						
						
							| 
								
							 | 
							
								}
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								// Gameplay Screen Unload logic
							 | 
						
						
						
							| 
								
							 | 
							
								void UnloadGameplayScreen(void)
							 | 
						
						
						
							| 
								
							 | 
							
								{
							 | 
						
						
						
							| 
								
							 | 
							
								    StopMusicStream(music);
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    // Unload textures
							 | 
						
						
						
							| 
								
							 | 
							
								    UnloadTexture(texBackground);
							 | 
						
						
						
							| 
								
							 | 
							
								    UnloadTexture(texPlayer);
							 | 
						
						
						
							| 
								
							 | 
							
								    UnloadTexture(texSampleSmall);
							 | 
						
						
						
							| 
								
							 | 
							
								    UnloadTexture(texSampleMid);
							 | 
						
						
						
							| 
								
							 | 
							
								    UnloadTexture(texSampleBig);
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    UnloadRenderTexture(waveTarget);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    // Unload sounds
							 | 
						
						
						
							| 
								
							 | 
							
								    UnloadSound(fxSampleOn);
							 | 
						
						
						
							| 
								
							 | 
							
								    UnloadSound(fxSampleOff);
							 | 
						
						
						
							| 
								
							 | 
							
								    UnloadSound(fxPause);
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    free(samples);   // Unload game samples
							 | 
						
						
						
							| 
								
							 | 
							
								}
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								// Gameplay Screen should finish?
							 | 
						
						
						
							| 
								
							 | 
							
								int FinishGameplayScreen(void)
							 | 
						
						
						
							| 
								
							 | 
							
								{
							 | 
						
						
						
							| 
								
							 | 
							
								    return finishScreen;
							 | 
						
						
						
							| 
								
							 | 
							
								}
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								//------------------------------------------------------------------------------------
							 | 
						
						
						
							| 
								
							 | 
							
								// Module Functions Definitions (local)
							 | 
						
						
						
							| 
								
							 | 
							
								//------------------------------------------------------------------------------------
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								// Draw samples in wave form (including already played samples in a different color!)
							 | 
						
						
						
							| 
								
							 | 
							
								// NOTE: For proper visualization, MSAA x4 is recommended, alternatively
							 | 
						
						
						
							| 
								
							 | 
							
								// it should be rendered to a bigger texture and then scaled down with 
							 | 
						
						
						
							| 
								
							 | 
							
								// bilinear/trilinear texture filtering
							 | 
						
						
						
							| 
								
							 | 
							
								static void DrawSamplesMap(Sample *samples, int sampleCount, int playedSamples, Rectangle bounds, Color color)
							 | 
						
						
						
							| 
								
							 | 
							
								{
							 | 
						
						
						
							| 
								
							 | 
							
								    // NOTE: We just pick a sample to draw every increment
							 | 
						
						
						
							| 
								
							 | 
							
								    float sampleIncrementX = (float)bounds.width/sampleCount;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								    Color col = color;
							 | 
						
						
						
							| 
								
							 | 
							
								    
							 | 
						
						
						
							| 
								
							 | 
							
								    for (int i = 0; i < sampleCount - 1; i++)
							 | 
						
						
						
							| 
								
							 | 
							
								    {
							 | 
						
						
						
							| 
								
							 | 
							
								        if (i < playedSamples) col = GRAY;
							 | 
						
						
						
							| 
								
							 | 
							
								        else col = color;
							 | 
						
						
						
							| 
								
							 | 
							
								
							 | 
						
						
						
							| 
								
							 | 
							
								        DrawLineV((Vector2){ (float)bounds.x + (float)i*sampleIncrementX, (float)(bounds.y + bounds.height/2) + samples[i].value*bounds.height }, 
							 | 
						
						
						
							| 
								
							 | 
							
								                  (Vector2){ (float)bounds.x + (float)(i + 1)*sampleIncrementX, (float)(bounds.y  + bounds.height/2) + + samples[i + 1].value*bounds.height }, col);
							 | 
						
						
						
							| 
								
							 | 
							
								    }
							 | 
						
						
						
							| 
								
							 | 
							
								}
							 |