//------------------------------------------------------------------------------
// 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
//------------------------------------------------------------------------------