//------------------------------------------------------------------------------
// Initialisation des fonction OpenGL
// Retourne true si tout s'est bien passé
//------------------------------------------------------------------------------


bool InitGL ( void )
{
    glClearColor ( 0.0f, 0.0f, 0.0f, 0.5f );    // Fond noir
    glClearDepth ( 1.0f );                      // Buffer de la profondeur initialisé

    glEnable ( GL_DEPTH_TEST );                 // Test sur la profondeur activé (évite des bugs d'affichage)
    glDepthFunc ( GL_LEQUAL );                  // Fonction à appliquer : n'afficher que les objets les plus proches (LEQUAL <=)

    glHint ( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // Améliore la perspective
    glShadeModel ( GL_SMOOTH );                 // Lissage des polygones (évite les boules à facettes)
    glEnable ( GL_SMOOTH );
    
    // Récupération des adresses des extensions OpenGL
    glActiveTextureARB       = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
    glMultiTexCoord2fARB     = (PFNGLMULTITEXCOORD2FARBPROC)     wglGetProcAddress("glMultiTexCoord2fARB");
    glClientActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)       wglGetProcAddress("glClientActiveTextureARB");

    // Vérification du support du multitexturing
    if ( !glActiveTextureARB || !glMultiTexCoord2fARB || !glClientActiveTextureARB)
    {
        MessageBox(NULL, "Votre carte 3D ne supporte pas le multitexturing", "Erreur", MB_OK);
        multitexturing = false;
    }

    // Initialisation du son
    // On active le son -> Utilisation de Direct Sound
    FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND);
    // On choisit un driver de carte son ( 0 par défaut )
    FSOUND_SetDriver(0);
    FSOUND_SetMixer(FSOUND_MIXER_AUTODETECT);
    // Son 44 KHz, 32 canaux
    FSOUND_Init(44100, 32, 0);
    
    // Chargement des vaisseaux
    LoadASE ( "models/vaisseau.ase", &vaisseau );
    LoadASE ( "models/sphere.ase", &sphere );
    
    LoadASE ( "models/anneau.ase", &ennemi[0] );
    LoadASE ( "models/vaisseau.ase", &ennemi[1] );
    LoadASE ( "models/carre.ase", &ennemi[2] );
    LoadASE ( "models/etoile.ase", &ennemi[3] );
    LoadASE ( "models/helice.ase", &ennemi[4] );
    LoadASE ( "models/p.ase", &ennemi[5] );
    LoadASE ( "models/sphere.ase", &ennemi[6] );
    LoadASE ( "models/roue.ase", &ennemi[7] );
   
    // Chargement des sons
    snd_intro = FSOUND_Sample_Load(FSOUND_UNMANAGED, "sons/ZeldaMM.wav",  FSOUND_HW2D | FSOUND_STEREO, 0, 0 );
//    snd_niv = FSOUND_Sample_Load(FSOUND_UNMANAGED, "sons/LA BEUSE - alfonse brown.mp3",  FSOUND_HW2D | FSOUND_STEREO, 0, 0 );
    snd_niv = FSOUND_Sample_Load(FSOUND_UNMANAGED, "sons/Xenon - TimeGate2.mp3",  FSOUND_HW2D | FSOUND_STEREO, 0, 0 );
//
    FSOUND_Sample_SetMode(snd_niv, FSOUND_LOOP_NORMAL);
    snd_explode = FSOUND_Sample_Load(FSOUND_UNMANAGED, "sons/explode.wav",  FSOUND_HW2D | FSOUND_STEREO, 0, 0 );
    snd_flip = FSOUND_Sample_Load(FSOUND_UNMANAGED, "sons/flip.wav", FSOUND_HW2D | FSOUND_STEREO, 0, 0 );
    snd_byebye = FSOUND_Sample_Load(FSOUND_UNMANAGED, "sons/byebye.wav", FSOUND_HW2D | FSOUND_STEREO, 0, 0 );
    snd_fire = FSOUND_Sample_Load(FSOUND_UNMANAGED, "sons/fire.wav", FSOUND_HW2D | FSOUND_STEREO, 0, 0 );

    // Initialisation des étoiles
    int i;
    for (i=0; i<maxp; i++) InitEtoile(&etoile[i]);
        
    temps.base = clock ( );                        // initialisation du temps de départ
    temps.tps = clock ( );                            // initialisation du temps de départ
    SetCursorPos ( 320, 200 );                  // On fixe le curseur au milieu de l'écran
    ReSizeGLScene( WIDTH, HEIGHT );             // On initialise l'affiche de la fenêtre OpenGL

    return TRUE;                                        // Initialization Went OK
}


//------------------------------------------------------------------------------
// Redimensionnement et initialisation de la fenêtre OpenGL
// width : largeur de la fenêtre, en pixel
// height : hauteur de la fenêtre, en pixel
//------------------------------------------------------------------------------


void ReSizeGLScene ( int width, int height )
{
    // Pour éviter une prochaine division par zéro
    if ( height == 0 ) height=1;

    glViewport (0, 0, width, height );      // Notre fenêtre est redimensionnée
    glMatrixMode ( GL_PROJECTION );         // Sélection d'une matrice de projection
    glLoadIdentity ( );                     // Initialisation de cette matrice

    // Calcule de l'aspect de la fenêtre ( angle, ratio, z proche, z loin )
    gluPerspective ( 45.0f, ( float ) width / ( float ) height, 0.1f, 300.0f );
    glMatrixMode ( GL_MODELVIEW );          // Sélection d'une matrice modelview
    glLoadIdentity ( );                     // Initialisation de cette matrice
}


//------------------------------------------------------------------------------
// Destruction propre de notre fenêtre OpenGL
//------------------------------------------------------------------------------


void KillGLWindow ( void )
{
    // Si on est en plein écran, on revient au bureau
    if ( fullscreen )
    {
        ChangeDisplaySettings ( NULL, 0 );
        ShowCursor ( true );
    }

    // Si on a un Rendering Context
    if ( hRC )
    {
        // Impossible de supprimer le DC et le RC
        if ( !wglMakeCurrent ( NULL, NULL ) )
            MessageBox ( NULL, "Mauvaise destruction du Device Context et du Rendering Context !", "Fermeture -> Erreur", MB_OK | MB_ICONINFORMATION );

        // Impossible de supprimer le RC
        if ( !wglDeleteContext ( hRC ) )
            MessageBox ( NULL, "Mauvaise destruction du Rendering Context !", "Fermeture -> Erreur", MB_OK | MB_ICONINFORMATION );

        hRC=NULL;                       // On le fixe a NULL
    }

    // Impossible de supprimer le DC
    if ( hDC && !ReleaseDC ( hWnd, hDC ) )
    {
        MessageBox ( NULL, "Mauvaise destruction du Device Context !", "Fermeture -> Erreur", MB_OK | MB_ICONINFORMATION );
        hDC=NULL;                       // On le fixe a NULL
    }

    // Impossible de détruire la fenêtre
    if ( hWnd && !DestroyWindow ( hWnd ) )
    {
        MessageBox ( NULL, "Mauvaise destruction de la fenêtre !", "Fermeture -> Erreur", MB_OK | MB_ICONINFORMATION );
        hWnd=NULL;                       // On le fixe a NULL
    }

    // Impossible de supprimer la classe OpenGL
    if ( !UnregisterClass ( "OpenGL", hInstance ) )
    {
        MessageBox ( NULL, "Mauvaise destruction de la classe OpenGL !", "Fermeture -> Erreur", MB_OK | MB_ICONINFORMATION );
        hInstance=NULL;                  // On le fixe a NULL
    }
}


//------------------------------------------------------------------------------
// Création de notre fenêtre OpenGL
// title  : titre qui apparaitra en haut de notre fenêtre
// width  : largeur de notre fenêtre
// height : hauteur de notre fenêtre
// bits   : nombres de couleurs utilisées
// fullscreenflag : flag permettant de savoir si on est en plein écran (true) ou en mode fenêtré (false)
// Retourne true si tout s'est bien passé
//------------------------------------------------------------------------------


bool CreateGLWindow ( char* title, int width, int height, int bits, bool fullscreenflag )
{
    unsigned int PixelFormat;           // Permet de garder le résultat d'une fonction
    WNDCLASS     wc;                    // Structure d'une classe 'fenêtre'
    DWORD        dwStyle;               // Style d'une fenêtre
    DWORD        dwExStyle;             // Style étendu d'une fenêtre
    RECT         WindowRect;            // Rectangle formé par notre fenêtre (haut gauche / bas droit)

    // Initialisation d'un rectangle, pour notre future fenêtre
    WindowRect.left=(long)0;            // On fixe la valeur à 0
    WindowRect.right=(long)width;       // On indique la largeur
    WindowRect.top=(long)0;             // On fixe la valeur à 0
    WindowRect.bottom=(long)height;     // On indique la hauteur

    fullscreen=fullscreenflag;          // On fixe le flag en global

    hInstance           = GetModuleHandle ( NULL );             // On récupère une instance pour notre fenêtre en globale
    wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;   // Redessine si on redimensionne notre propre DC
    wc.lpfnWndProc      = ( WNDPROC ) WndProc;                  // Handle de nos messages de notre fenêtre
    wc.cbClsExtra       = 0;                                    // Pas de données 'extra' pour la classe
    wc.cbWndExtra       = 0;                                    // Pas de données 'extra' pour la fenêtre
    wc.hInstance        = hInstance;                            // On fixe l'instance de la fenêtre
    wc.hIcon            = LoadIcon ( NULL, IDI_WINLOGO );       // On charge l'icone par défaut
    wc.hCursor          = LoadCursor ( NULL, IDC_ARROW );       // On charge le curseur par défaut
    wc.hbrBackground    = NULL;                                 // OpenGL n'a pas besoin par de fond
    wc.lpszMenuName     = NULL;                                 // Nous n'attendons pas de menu
    wc.lpszClassName    = "OpenGL";                             // On fixe le nom de notre classe

    // Impossible d'enregistrer la classe de la fenêtre
    if ( !RegisterClass ( &wc ) )
    {
        MessageBox ( NULL, "Impossible d'enregistrer la classe de la fenêtre !", "Erreur", MB_OK | MB_ICONEXCLAMATION );
        return false;
    }

    // Si on est en plein écran
    if ( fullscreen )
    {
        DEVMODE dmScreenSettings;                               // Device Mode

        // On s'assure que la mémoire est bien effacée
        memset ( &dmScreenSettings, 0, sizeof ( dmScreenSettings ) );
        dmScreenSettings.dmSize       = sizeof ( dmScreenSettings ); // Taille de la structure
        dmScreenSettings.dmPelsWidth  = width;                  // Largeur
        dmScreenSettings.dmPelsHeight = height;                 // Hauteur
        dmScreenSettings.dmBitsPerPel = bits;                   // Bits Par Pixel
        dmScreenSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

        // On essaie le mode sélectionné et on regarde les résultats, et s'il échoue, on a deux possibilités
        if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
        {
            if ( MessageBox ( NULL, "Le mode Plein Ecran n'est pas supporté par\nvotre carte 3D. Utilisez-vous le mode fenêtré à la place ?", "Problème", MB_YESNO | MB_ICONEXCLAMATION) == IDYES )
                fullscreen=false;        // On passe en mode fenêtré
            else
            {
                MessageBox ( NULL, "le programme va se terminer !", "Erreur", MB_OK | MB_ICONSTOP );
                return false;
            }
        }
    }

    // Le style de la fenêtre est différent selon qu'on soit en plein écran ou non
    if ( fullscreen )
    {
        dwExStyle = WS_EX_APPWINDOW;
        dwStyle   = WS_POPUP;
        ShowCursor ( false );
    }
    else
    {
        dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
        dwStyle   = WS_OVERLAPPEDWINDOW;
    }

    // On ajuste la taille de la fenêtre à la taille désirée
    AdjustWindowRectEx(&WindowRect, dwStyle, false, dwExStyle);

    // On crée véritablement notre fenêtre et on vérifie si tout fonctionne
    if ( !( hWnd = CreateWindowEx (
        dwExStyle,                          // Style étendu de notre fenêtre
        "OpenGL",                           // Nom de notre classe
        title,                              // Titre de la fenêtre
        dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, // Style de la fenêtre
        0, 0,                               // Position de la fenêtre
        WindowRect.right - WindowRect.left, // Calcule de la largeur de la fenêtre
        WindowRect.bottom - WindowRect.top, // Calcule de la hauteur de la fenêtre
        NULL,                               // La fenêtre n'a pas de père
        NULL,                               // La fenêtre n'a pas de menu
        hInstance,                          // Instance de la fenêtre
        NULL ) ) )
    {
        KillGLWindow ( );
        MessageBox ( NULL, "Erreur lors de la création de la fenêtre !", "Erreur", MB_OK | MB_ICONEXCLAMATION);
        return false;
    }

    // pfd indique à la fenêtre comment nous voulons que l'affichage soit
    static PIXELFORMATDESCRIPTOR pfd =
    {
        sizeof ( PIXELFORMATDESCRIPTOR ),   // Taille
        1,                                  // Numéro de version
        PFD_DRAW_TO_WINDOW |                // Le format doit supporté la fenêtre
        PFD_SUPPORT_OPENGL |                // Le format doit supporté OpenGL
        PFD_DOUBLEBUFFER,                   // Le format doit supporté le Double Buffering
        PFD_TYPE_RGBA,                      // Le format des couleurs est le RGBA
        32,                                 // On indique le nombre des couleurs
        0, 0, 0, 0, 0, 0,                   // Ignoré
        0,                                  // Pas d'Alpha Buffer
        0,                                  // Ignoré
        0,                                  // Pas d'Accumulation Buffer
        0, 0, 0, 0,                         // Ignoré
        16,                                 // Z-Buffer de 16 bits (profondeur)
        0,                                  // Pas de Stencil Buffer
        0,                                  // Pas d'Auxiliary Buffer
        PFD_MAIN_PLANE,                     // Couche principale pour l'affichage
        0,                                  // Reservé
        0, 0, 0                             // Ignoré
    };

    if ( !( hDC = GetDC ( hWnd ) ) )
        ERREUR("Impossible de créer un Device Context !");

    if ( !( PixelFormat = ChoosePixelFormat ( hDC, &pfd ) ) )
        ERREUR("Ne trouve pas le bon format de pixel !");

    if ( !SetPixelFormat ( hDC, PixelFormat, &pfd ) )
        ERREUR("Ne peut pas configurer le format de pixel !");

    if ( !( hRC = wglCreateContext ( hDC ) ) )
        ERREUR("Ne peut pas créer un Rendering Context !");

    if( !wglMakeCurrent ( hDC, hRC ) )
        ERREUR("Ne peut pas activer le Rendering Context !");

    ShowWindow ( hWnd, SW_SHOW );               // Affiche la fenêtre
    SetForegroundWindow ( hWnd );               // Priorité plus importante pour notre fenêtre
    SetFocus ( hWnd );                          // Donne la main à notre fenêtre
    ReSizeGLScene ( width, height );            // Initialise l'affichage OpenGL

    if ( !InitGL ( ) )
        ERREUR("Mauvaise initialisation des fonctions OpenGL !");

    return true;
}




//------------------------------------------------------------------------------
// On récupère les messages de la fenêtre
// hWnd   : handle de notre fenêtre
// uMsg   : message a traité
// wParam : information supplémentaire au message
// lParam : information supplémentaire au message
// Retourne ... quelque chose ...
//------------------------------------------------------------------------------


LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    // Selon le type de message reçu
    switch ( uMsg )
    {
        // Activation de la fenêtre
        case WM_ACTIVATE :
        {
            // Fenêtre minimisée ?
            (HIWORD ( wParam )) ? (active=false) : (active=true);
            return 0;
        }

        // Commandes systèmes
        case WM_SYSCOMMAND :
        {
            // quelle commande précisemment ?
            switch (wParam)
            {
                // Démarrage d'un Screensaver
                case SC_SCREENSAVE :
                // Le moniteur s'est éteint pour éconimiser de l'énergie
                case SC_MONITORPOWER :
                return 0;
            }
            break;
        }

        // Fermeture
        case WM_CLOSE :
        {
            FreeASE ( sphere );
            FreeASE ( vaisseau );
            FreeASE ( vaisseau );
            FreeASE ( ennemi[0] );
            FreeASE ( ennemi[1] );
            FreeASE ( ennemi[2] );
            FreeASE ( ennemi[3] );
            FreeASE ( ennemi[4] );
            FreeASE ( ennemi[5] );
            FreeASE ( ennemi[6] );
            FreeASE ( ennemi[7] );
            FSOUND_Sample_Free(snd_intro);
            FSOUND_Sample_Free(snd_niv);
            FSOUND_Sample_Free(snd_explode);
            FSOUND_Sample_Free(snd_flip);
            FSOUND_Sample_Free(snd_byebye);
            FSOUND_Close();
            PostQuitMessage ( 0 );
            return 0;
        }

        // Touche enfoncée
        case WM_KEYDOWN :
        {
            // On met à jour notre tableau de touches
            keys[wParam] = true;
            return 0;
        }

        // Touche relachée
        case WM_KEYUP :
        {
            // On met à jour notre tableau de touches
            keys[wParam] = false;
            return 0;
        }
        
        case WM_LBUTTONDOWN:
        {                                // If we hit the left mouse button
            // souris bouton gauche
            break;
        }

        case WM_RBUTTONDOWN:                                // If we hit the right mouse button
        {
            // souris bouton droit
            break;
        }

        // Redimensionnement
        case WM_SIZE :
        {
            // Largeur : LoWord / Hauteur : HiWord
            ReSizeGLScene ( LOWORD ( lParam ), HIWORD ( lParam ) );
            return 0;
        }
    }

    // On passe tous les autres messages à cette fonction
    return DefWindowProc ( hWnd, uMsg, wParam, lParam );
}

//------------------------------------------------------------------------------
// On récupère les messages de la fenêtre
// hInstance     : notre instance
// hPrevInstance : l'instance précédente
// lpCmdLine     : la ligne de commande
// nCmdShow      : l'état de notre fenêtre
// Retourne ... quelque chose ...
// TimeStep corrigé pour le déplacement du vaisseau (03 février 2004)
//------------------------------------------------------------------------------


int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    MSG     msg;                                    // Structure d'un message
    BOOL    done=false;                             // Passe à true pour qu'on quitte, sinon on boucle

//    if ( MessageBox ( NULL, "Passer en plein écran\nou rester en mode fenêtré ?", "Affichage", MB_YESNO | MB_ICONQUESTION ) == IDNO )
//        fullscreen=false;

    // Initialisation du random
    srand ( time ( NULL ) );

    // Création de notre fenêtre OpenGL
    if ( !CreateGLWindow ( "Estrella", 800, 600, 32, fullscreen ) )
        return 0;

    while ( !done )
    {
        // on vérifie s'il y a un message en attente, sinon on affiche la scène
        if ( PeekMessage ( &msg, NULL, 0, 0, PM_REMOVE ) )
        {
            // doit-on quitter
            if ( msg.message == WM_QUIT )
                done=true;
            // Sinon on traite le message
            else
            {
                TranslateMessage ( &msg );
                DispatchMessage ( &msg );
            }
        }
        else
        {
            // Si on n'affiche rien ou si on appuie sur Echap, on quitte
            if ( ( active && !DrawGLScene ( ) ) || keys[VK_ESCAPE] )
                done=true;
            // Sinon on effectue notre Double Buffering et on met à jour l'affichage
            else
                SwapBuffers(hDC);

            // F1 : basculement plein écran / fenêtre
            /*
            if ( keys[VK_F1] )
            {
                keys[VK_F1]=false;                      // On la désactive
                KillGLWindow ( );                       // On détruit la fenêtre
                fullscreen=!fullscreen;                 // basculement Plein Ecran / Fenêtre
                if ( !CreateGLWindow ( "Estrella", 800, 600, 32, fullscreen ) )
                    return 0;
            }*/
            
            // F2 : mode fil de fer
            if (keys[VK_F2])
            {
                keys[VK_F2]=false;                      // On la désactive
                aff_wireframe = 1 - aff_wireframe;      // On bascule le mode
            }
            
            // Flèche Haut : déplacement du vaisseau vers le haut
            if (keys[VK_UP])
                if ( vaisseau.posy < 5) vaisseau.posy+=0.1f*temps.ecart*100;
                
            // Flèche Bas : déplacement du vaisseau vers le bas
            if (keys[VK_DOWN])                        
                if ( vaisseau.posy > -5) vaisseau.posy-=0.1f*temps.ecart*100;

            // Entrée : différentes fonctionnalités
            if (keys[13])
            {
                keys[13]=false;                         // On la désactive
                if ( playIntro == true )                // Si on est dans l'intro
                {
                    attenteFade ( 0 );                  // On arrête les dégradés
                    playIntro = false;                  // On arrête l'intro
                    playMenu = true;                    // On passe au menu
                }
                else if ( playMenu == true )            // Si on est dans le menu
                    menuEntrer=true;                    // On indique que la touche est activée
                else if ( playOptions == true )         // Si on est dans les options
                    menuEntrer = true;                  // On indique que la touche est activée
                else if ( playJouer == true )           // Si on joue
                {
                    FSOUND_PlaySoundEx(FSOUND_FREE, snd_flip, NULL, FALSE);
                    tonneau = true;                     // On fait un flip, avec le son
                }
            }

            // Flèche gauche : différentes fonctionnalités
            if (keys[VK_LEFT])
            {
                if(playOptions==true)                   // Si on est dans les options
                {
                    keys[VK_LEFT]=false;                // On la désactive
                    if (numero==TEX_VAISSEAU_5) numero=TEX_VAISSEAU_1;
                    else numero++;                      // On change la texture
                }
                else if ((playJouer==true) && ( vaisseau.posx > -5))
                    vaisseau.posx-=0.1f*temps.ecart*100;                // Si on joue, on déplace le vaisseau à gauche
                else  if ( playMenu == true )           // Si on est dans le menu, on rotate les planètes
                    if(rotation_planete==0) rotation_planete=1;
            }

            // Flèche droit : différentes fonctionnalités
            if (keys[VK_RIGHT])
            {
                if(playOptions==true)                   // Si on est dans les options
                {
                    keys[VK_RIGHT]=false;               // On la désactive
                    if (numero==TEX_VAISSEAU_1) numero=TEX_VAISSEAU_5;
                    else numero--;                      // On change la texture
                }
                else if((playJouer==true)&&( vaisseau.posx < 5) )
                    vaisseau.posx+=0.1f*temps.ecart*100;                // Si on joue, on déplace le vaisseau à droite
                else if ( playMenu == true )            // Si on est dans le menu, on rotate les planètes
                    if(rotation_planete==0) rotation_planete=2;
            }

            // P : pause lors du jeu
            if (keys['P'] || keys['p'])
            {
                keys['P']=false;                        // On la désactive
                keys['p']=false;                        // On la désactive
                if ( playJouer == true )                // Si on joue, on passe au menu
                {
                    playMenu = true;
                    playJouer = false;
                    Pause = true;
                }
            }
            
            // Q : quitter la partie
            if (keys['Q'] || keys['q'])
            {
                keys['Q']=false;                        // On la désactive
                keys['q']=false;                        // On la désactive
                if ( playJouer == true )                // Si on joue, on passe au menu
                {
                    playMenu = true;
                    playJouer = false;
                    num_nivo = 1;                       // Réinitialisation du niveau
                    temps.non_ecoule = 0.0f;              // Réinitialisation du temps non écoulé
                    free ( nivo.enn );
                }
            }
            
            // Espace : tire un laser
            if (keys[VK_SPACE])
            {
                keys[VK_SPACE]=false;                      // On la désactive
                laser[nb_laser].x = vaisseau.posx;
                laser[nb_laser].y = vaisseau.posy;
                laser[nb_laser].debz = vaisseau.posz - 3;
                laser[nb_laser].finz = vaisseau.posz - 100;
                laser[nb_laser].vitesse = 50;
                laser[nb_laser].taille = 15;
                laser[nb_laser].affich = true;
                nb_laser ++;
                nb_laser = nb_laser % 10;
                FSOUND_PlaySoundEx ( FSOUND_FREE, snd_fire, NULL, FALSE );
            }
            
            // B : Transparence des vaisseaux
            if (keys['B'] || keys['b'])
            {
                keys['B']=false;                        // On la désactive
                keys['b']=false;                        // On la désactive
                vaisseauTransparence = 1 - vaisseauTransparence;
            }

            // D : Transparence des vaisseaux
            if (keys['D'] || keys['d'])
            {
                keys['D']=false;                        // On la désactive
                keys['d']=false;                        // On la désactive
                char msg[255];
                sprintf ( msg, "Debug : %d", debug);
                MessageBox(NULL,msg, "Debug !", MB_OK|MB_ICONQUESTION);
            }
        }
    }

    KillGLWindow ( );                                   // On détruit la fenêtre dès qu'on sort de la boucle
    return (msg.wParam);                                // On quitte le programme
}


//------------------------------------------------------------------------------
// Fin Du Fichier
//------------------------------------------------------------------------------