/*
This file is part of FallDown - GCN.
FallDown - GCN is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FallDown - GCN is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
http://falldown.forge.games-creators.org/
Developer(s) : TrizoLakai
*/
#include "CMoteur.hh"
#include <fstream>
#include <string>
#include <stdexcept>
#include <iostream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_mixer.h>
#include "eMENU.hh"
#include "eFENETRE.hh"
using namespace std;
bool CMoteur::Menu(eMENU TypeMenu) {
string PathTexture("./Images/Menu");
/* Les Textures a charger en fonction du menu */
switch(TypeMenu){
case eMENU_PERDU : PathTexture += "Perdu.png"; break;
case eMENU_QUITTER : PathTexture += "Quitter.png"; break;
default : throw logic_error("Type Menu non reconnu. Quitte."); break;
}
/* Chargement du Menu */
CSprite Menu(PathTexture);
FallDown_Rect *RectMenu = new FallDown_Rect;
RectMenu->w = eFENETRE_LARGEUR; RectMenu->h = eFENETRE_HAUTEUR;
RectMenu->x = RectMenu->y = 0;
Menu.CopieFallDown_Rect(RectMenu);
/* Chargement des OUI et NON */
CSprite Oui("./Images/Oui.png"), Oui2("./Images/Oui2.png");
CSprite Non("./Images/Non.png"), Non2("./Images/Non2.png");
FallDown_Rect *RectOui = new FallDown_Rect;
RectOui->x = 110; RectOui->y = 280;
RectOui->w = 45; RectOui->h = 25;
Oui.CopieFallDown_Rect(RectOui); Oui2.CopieFallDown_Rect(RectOui);
FallDown_Rect *RectNon = new FallDown_Rect;
RectNon->x = 50; RectNon->y = 280;
RectNon->w = 45; RectNon->h = 25;
Non.CopieFallDown_Rect(RectNon); Non2.CopieFallDown_Rect(RectNon);
SDL_Event event;
int OuiOuNon = 1; // 1 pour a droite -1 pour a gauche
unsigned int CheckTime = SDL_GetTicks(); //On contrôle le temps
while(1){
/* Traitement des evenements */
SDL_EnableKeyRepeat(0,0); //Desactive la répétition des touches
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT: return true; break;
case SDL_KEYDOWN: switch(event.key.keysym.sym) {
case SDLK_ESCAPE : delete RectMenu;
delete RectNon;
delete RectOui;
Non.CopieFallDown_Rect(NULL); Non2.CopieFallDown_Rect(NULL);
Oui.CopieFallDown_Rect(NULL); Oui2.CopieFallDown_Rect(NULL);
return false; break;
case SDLK_LEFT: OuiOuNon *= -1; break;
case SDLK_RIGHT: OuiOuNon *= -1; break;
case SDLK_RETURN: if(OuiOuNon > 0) return true;
else
delete RectMenu;
delete RectNon;
delete RectOui;
Non.CopieFallDown_Rect(NULL); Non2.CopieFallDown_Rect(NULL);
Oui.CopieFallDown_Rect(NULL); Oui2.CopieFallDown_Rect(NULL);
return false; break;
default : break;
} break;
case SDL_KEYUP: switch(event.key.keysym.sym) {
default: break;
} break;
case SDL_MOUSEMOTION : {
default: break;
} break;
}
}
/* Si nous avons déjà affiché trop de fps dans la seconde on arrete */
if(SDL_GetTicks() > (CheckTime + 1000 / eFENETRE_FPS)) {
/* Affichage du niveau */
mNiveau[mNiveauActuel].Afficher();
/* Affichage du menu */
Menu.Afficher();
/* Affichage des oui et non */
if(OuiOuNon > 0){
Oui2.Afficher();
Non.Afficher();
}
else{
Oui.Afficher();
Non2.Afficher();
}
/* Affichage de l'Ecran */
SDL_GL_SwapBuffers();
/* Mise à jour du compteur de fps */
CheckTime = SDL_GetTicks();
}else{SDL_Delay(1);} //Sinon on fait une petite pause pour le processeur.
}
return false;
}
CMoteur::CMoteur() {
/* Initialisations classiques */
mLance = mPerdu = mMenuIG = false;
mNiveau = NULL;
mNombreNiveau = 0;
mNiveauActuel = 0;
}
CMoteur::~CMoteur() {
/* Liberation de mNiveau */
if(mNiveau != NULL){
delete [] mNiveau;
mNiveau = NULL;
}
}
bool CMoteur::Charger(){
/* Initialisation de SDL et OpenGL avec l'Audio */
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0){
string Buffer("Erreur lors de l'initialisation de SDL : ");
Buffer += SDL_GetError();
throw logic_error(Buffer);
}
/* Initialisation de la couche Audio */
CAudio::Initialisation();
/* Decor de la fenetre */
SDL_WM_SetCaption("FallDown - GCN - Initialisation", NULL);
SDL_Surface * Icone = IMG_Load(CreateDataPath("Images/Falldown.png"));
SDL_WM_SetIcon(Icone, NULL);
/* Creation de la Fenetre */
SDL_Surface *Screen = SDL_SetVideoMode(eFENETRE_LARGEUR , eFENETRE_HAUTEUR, 32, SDL_OPENGL | eFENETRE_FULLSCREEN);
if(Screen == NULL){
string Buffer("Erreur lors de la creation de la fenetre SDL : ");
Buffer += SDL_GetError();
throw logic_error(Buffer);
}
/* Paramètrage d'OpenGL pour une utilisation 2D comme SDL */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, eFENETRE_LARGEUR, 0, eFENETRE_HAUTEUR);
/* Libération de la surface de l'écran */
SDL_FreeSurface(Screen);
SDL_WM_SetCaption("FallDown - GCN - Chargement", NULL);
CSprite Chargement(CreateDataPath("Images/Chargement.png"));
FallDown_Rect *ChargementPlacement = new FallDown_Rect;
ChargementPlacement->x = ChargementPlacement->y = 0;
ChargementPlacement->w = eFENETRE_LARGEUR;
ChargementPlacement->h = eFENETRE_HAUTEUR;
Chargement.CopieFallDown_Rect(ChargementPlacement);
Chargement.Afficher();
SDL_GL_SwapBuffers();
string Buffer(""), Buffer2(""), Buffer3("");
/* Vitesse pour le controle de fichier */
int Vitesse = 0;
/* Chargement et Lancement de la musique d'ambiance */
mMusique.Charger(CreateDataPath("Sons/KeopzRueDuPasse.ogg"), false);
mMusique.Jouer();
/* Chargement du fichier scene.config */
ifstream SceneConfig (CreateDataPath("scene.config"), ios::in); //Ouverture du fichier
if(!SceneConfig.is_open()){
throw logic_error("Erreur lors de l'ouverture du fichier de config de la scene : ./scene.config");
}
if(SceneConfig.good()){ //Recherche du nombre de niveau
SceneConfig >> Buffer; Buffer.erase(Buffer.begin());
mNombreNiveau = atoi(Buffer.c_str());
if(mNiveau != NULL)
throw logic_error("Ne peux allouer correctement mNiveau en memoire");
mNiveau = new CNiveau[mNombreNiveau]; //Allocation des niveau
}else throw logic_error("Erreur lors de la lecture de scene.config");
/* Chargement des niveaux */
for(int i = 0; i < mNombreNiveau; ++i){
mNiveau[i].Charger(i + 1);
if(SceneConfig.good())SceneConfig >> Buffer; else throw logic_error("Erreur lors de la lecture de scene.config");
if(SceneConfig.good())SceneConfig >> Buffer; else throw logic_error("Erreur lors de la lecture de scene.config");
mNiveau[i].ChargerFond(Buffer); //Chargement du Fond
if(SceneConfig.good())SceneConfig >> Buffer; else throw logic_error("Erreur lors de la lecture de scene.config");
if(SceneConfig.good())SceneConfig >> Buffer2; else throw logic_error("Erreur lors de la lecture de scene.config");
Buffer2.erase(Buffer2.begin()); Vitesse = atoi(Buffer2.c_str());
mNiveau[i].ChargerBalle(Buffer, Vitesse); //Chargement de la balle
if(SceneConfig.good())SceneConfig >> Buffer; else throw logic_error("Erreur lors de la lecture de scene.config");
if(SceneConfig.good())SceneConfig >> Buffer; else throw logic_error("Erreur lors de la lecture de scene.config");
if(SceneConfig.good())SceneConfig >> Buffer2; else throw logic_error("Erreur lors de la lecture de scene.config");
if(SceneConfig.good())SceneConfig >> Buffer3; else throw logic_error("Erreur lors de la lecture de scene.config");
Buffer3.erase(Buffer3.begin());
mNiveau[i].ChargerBriques(abs(atoi(Buffer.c_str())), Buffer2, atoi(Buffer3.c_str())); //Chargement des briques
/* Controle si les vitesses ne sont pas eccessive */
if(abs(Vitesse) + abs(atoi(Buffer3.c_str())) > eBRIQUE_HAUTEUR)
throw logic_error("Valeurs des vitesses trop grande pour assurer des collisions normales");
}
/* Fermeture du fichier scene.config */
SceneConfig.close();
return true;
}
bool CMoteur::Lancer() {
/* Chargement des Niveau et se qu'ils contiennent */
Charger();
SDL_WM_SetCaption("FallDown - GCN - Jeu", NULL);
mLance = false;
/* Menu prevenant du lancement */
CSprite MenuLancement(CreateDataPath("Images/MenuLancement.jpg)");
FallDown_Rect *RectMenuLancement = new FallDown_Rect;
RectMenuLancement->x = RectMenuLancement->y = 0;
RectMenuLancement->w = eFENETRE_LARGEUR;
RectMenuLancement->h = eFENETRE_HAUTEUR;
MenuLancement.CopieFallDown_Rect(RectMenuLancement);
MenuLancement.Afficher();
SDL_GL_SwapBuffers();
SDL_Event event;
while(!mLance){
SDL_EnableKeyRepeat(0,0); //Desactive la répétition des touches
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT: return eMENU_QUITTER; break;
case SDL_KEYDOWN: switch(event.key.keysym.sym) {
case SDLK_ESCAPE : return true; break;
case SDLK_RETURN : mLance = true; break;
default : break;
} break;
default : break;
}
}
}
/* Chargement du premier niveau */
mNiveau[0].Redemarrer();
/* Lancement du Jeu */
int EtatJeu = 0;
while(mLance){
/* On lance le jeu */
mPerdu = false;
EtatJeu = Jeu();
/* On regarde ce que le jeu nous dis */
switch(EtatJeu){
case eMENU_QUITTER: if(Menu(eMENU_QUITTER)) return true; break;
case eMENU_PERDU: mNiveauActuel = 0;
mNiveau[mNiveauActuel].Redemarrer(true);
if(Menu(eMENU_PERDU)) return true; break;
default : throw logic_error("Jeu() retourne un entier inconnu. Quitte"); break;
}
}
return true;
}
int CMoteur::Jeu(){
SDL_Event event;
unsigned int CheckTime = SDL_GetTicks(); //On contrôle le temps
bool ToucheGauche, ToucheDroite;
ToucheGauche = ToucheDroite = false;
while(1){
/* Traitement des evenements */
SDL_EnableKeyRepeat(0,0); //Desactive la répétition des touches
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT: return eMENU_QUITTER; break;
case SDL_KEYDOWN: switch(event.key.keysym.sym) {
case SDLK_ESCAPE : return eMENU_QUITTER; break;
case SDLK_LEFT: ToucheGauche = true; break;
case SDLK_RIGHT: ToucheDroite = true; break;
default : break;
} break;
case SDL_KEYUP: switch(event.key.keysym.sym) {
case SDLK_LEFT: ToucheGauche = false; break;
case SDLK_RIGHT: ToucheDroite = false; break;
default: break;
} break;
case SDL_MOUSEMOTION : {
default: break;
} break;
}
}
/* Si nous avons déjà affiché trop de fps dans la seconde on arrete */
if(SDL_GetTicks() > (CheckTime + 1000 / eFENETRE_FPS)) {
/* Deplacements Balle */
if(ToucheGauche)mNiveau[mNiveauActuel].BalleDeplacement(-10);
if(ToucheDroite)mNiveau[mNiveauActuel].BalleDeplacement(10);
/* Premiers tests de collisions */
mNiveau[mNiveauActuel].Collisions();
/* Deplacements entitite */
mNiveau[mNiveauActuel].Deplacements();
/* Seconds tests de collisions */
mNiveau[mNiveauActuel].Collisions();
/* Dessine la Fenetre */
if(mNiveau[mNiveauActuel].Afficher() == -1) //Si on a perdu
mPerdu = true;
if(mNiveau[mNiveauActuel].Afficher() == -2){ //Si le niveau est finis
++mNiveauActuel;
if(mNiveauActuel == mNombreNiveau){
mNiveauActuel = 0;
mNiveau[mNiveauActuel].Redemarrer(true);
}
else mNiveau[mNiveauActuel].Redemarrer();
}
/* Affichage de l'Ecran */
SDL_GL_SwapBuffers();
/* Mise à jour du compteur de fps */
CheckTime = SDL_GetTicks();
}else{SDL_Delay(1);} //Sinon on fait une petite pause pour le processeur.
/* Si on a perdu on retourne dans le menu perdu */
if(mPerdu){
return eMENU_PERDU;
}
}
return -1;
}