From 03e4e537117605932b5cf06468c46a7becd35374 Mon Sep 17 00:00:00 2001 From: Johnny Jazeix Date: Sun, 31 Dec 2023 15:45:55 +0100 Subject: [PATCH 1/3] add clang-format --- .clang-format | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..7501be1 --- /dev/null +++ b/.clang-format @@ -0,0 +1,16 @@ +--- +Language: Cpp +BasedOnStyle: Webkit +PointerAlignment: Right +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: false +SortIncludes: false +AlignAfterOpenBracket: Align +BreakBeforeBraces: Custom +BraceWrapping: + BeforeElse: true + AfterFunction: true + AfterClass: true + AfterStruct: true +BreakConstructorInitializers: AfterColon +NamespaceIndentation: All From be3f91c6c56542be9176f7e29ac219d5ffc11aec Mon Sep 17 00:00:00 2001 From: Johnny Jazeix Date: Sun, 31 Dec 2023 15:46:25 +0100 Subject: [PATCH 2/3] clang-format all code --- src/audio.cc | 239 ++--- src/audio.h | 59 +- src/editor.cc | 683 +++++++------- src/editor.h | 33 +- src/game.cc | 849 +++++++++-------- src/game.h | 47 +- src/level.cc | 239 ++--- src/level.h | 48 +- src/loco.cc | 1049 +++++++++++---------- src/loco.h | 72 +- src/main.cc | 267 +++--- src/menu.cc | 2346 ++++++++++++++++++++++++---------------------- src/menu.h | 49 +- src/mouse.cc | 169 ++-- src/mouse.h | 49 +- src/preference.h | 76 +- src/screen.cc | 100 +- src/screen.h | 43 +- src/sprite.cc | 701 +++++++------- src/sprite.h | 300 +++--- src/utils.cc | 301 +++--- src/utils.h | 11 +- 22 files changed, 3982 insertions(+), 3748 deletions(-) diff --git a/src/audio.cc b/src/audio.cc index fdf4626..19f6e1a 100644 --- a/src/audio.cc +++ b/src/audio.cc @@ -1,5 +1,5 @@ // (_||_/ -// ( ) +// ( ) // ( o 0 ) //-OOO°--(_)---°OOO--------------------------------------- // Copyright (C) 2006 By Dominique Roux-Serret @@ -36,155 +36,170 @@ extern int Horloge; /*** Constructeur et Destructeur ***/ /***********************************/ -Audio::Audio(void) : N(0), NMus(0), MemoHorloge(0), Son(NULL), Music(NULL) -{ } +Audio::Audio(void) : + N(0), NMus(0), MemoHorloge(0), Son(NULL), Music(NULL) +{ +} Audio::~Audio(void) { - if(N) { - Mix_HaltChannel(-1); - for(int i=0;i2) NMus=1; - LoadMusic(NMus); + NMus++; + if (NMus > 2) + NMus = 1; + LoadMusic(NMus); } /*** Fait la lecture d'un son ***/ /********************************/ -void Audio::Play(eSon So) { - if(!N) return; - - if(So==sClic) { - if(Horloge-MemoHorloge<=120) return; - MemoHorloge=Horloge; - } - - Mix_PlayChannel(-1,Son[So],0); +void Audio::Play(eSon So) +{ + if (!N) + return; + + if (So == sClic) { + if (Horloge - MemoHorloge <= 120) + return; + MemoHorloge = Horloge; + } + + Mix_PlayChannel(-1, Son[So], 0); } /*** Joue la music ***/ /*********************/ -void Audio::PlayMusic(void) { - if(Music && N) { - Mix_PlayMusic(Music,-1); - DoVolume(); - } +void Audio::PlayMusic(void) +{ + if (Music && N) { + Mix_PlayMusic(Music, -1); + DoVolume(); + } } void Audio::PauseMusic(bool Et) { - if(!N) return; + if (!N) + return; - if(Et) Mix_PauseMusic(); - else Mix_ResumeMusic(); + if (Et) + Mix_PauseMusic(); + else + Mix_ResumeMusic(); } /*** Valide les Volumes ***/ /**************************/ void Audio::DoVolume(void) { - if(!N) return; - - Mix_Volume(-1,(int)Pref.Volume); - if(NMus) Mix_VolumeMusic((int)Pref.VolumeM); - else Mix_VolumeMusic((int)Pref.VolumeM/2); + if (!N) + return; + + Mix_Volume(-1, (int)Pref.Volume); + if (NMus) + Mix_VolumeMusic((int)Pref.VolumeM); + else + Mix_VolumeMusic((int)Pref.VolumeM / 2); } diff --git a/src/audio.h b/src/audio.h index 5c4ed5d..6d1fed8 100644 --- a/src/audio.h +++ b/src/audio.h @@ -29,43 +29,44 @@ /*** Enumération des sons ***/ /****************************/ enum eSon { - sClic=0, - sSpeed, - sCrash, - sEnd, - sLose, - sEtire, - sWagon, - sReduit, - sLive, - sFin + sClic = 0, + sSpeed, + sCrash, + sEnd, + sLose, + sEtire, + sWagon, + sReduit, + sLive, + sFin }; /*** Définition de la classe Audio ***/ /*************************************/ -class Audio { - public: - Audio(void); - ~Audio(void); +class Audio +{ +public: + Audio(void); + ~Audio(void); - /*** Fonctions ***/ - bool Init(void); // Initialise et charge les fichiers audio - void LoadMusic(int Num); // Charge une music, 0 = music du menu 1,2,3,4=Jeu - void NextMusic(void); // Passe à la music suivante + /*** Fonctions ***/ + bool Init(void); // Initialise et charge les fichiers audio + void LoadMusic(int Num); // Charge une music, 0 = music du menu 1,2,3,4=Jeu + void NextMusic(void); // Passe à la music suivante - void Play(eSon); // Joue un son - void PlayMusic(void); // Joue la music + void Play(eSon); // Joue un son + void PlayMusic(void); // Joue la music - void PauseMusic(bool Etat); // Met ou no la music en pause + void PauseMusic(bool Etat); // Met ou no la music en pause - void DoVolume(void); // Valide les volumes audio - - /*** Variables ***/ - int N; // Nombre d'échantillon audio - int NMus; // Numéro de la music en cours - int MemoHorloge; // Mémorise l'horloge pour les clics - Mix_Chunk **Son; // Pointe sur les sons - Mix_Music *Music; // Pointe sur les musics + void DoVolume(void); // Valide les volumes audio + + /*** Variables ***/ + int N; // Nombre d'échantillon audio + int NMus; // Numéro de la music en cours + int MemoHorloge; // Mémorise l'horloge pour les clics + Mix_Chunk **Son; // Pointe sur les sons + Mix_Music *Music; // Pointe sur les musics }; #endif diff --git a/src/editor.cc b/src/editor.cc index 4dac345..cc183ff 100644 --- a/src/editor.cc +++ b/src/editor.cc @@ -1,5 +1,5 @@ // (_||_/ -// ( ) +// ( ) // ( o 0 ) //-OOO°--(_)---°OOO--------------------------------------- // Copyright (C) 2006 By Dominique Roux-Serret @@ -45,359 +45,380 @@ extern Level level; extern Mouse mouse; extern Game game; -static int NumRail[]={ 10,10,10,0,10,1,2,3,10,4,5,6,7,8,9,10 }; +static int NumRail[] = { 10, 10, 10, 0, 10, 1, 2, 3, 10, 4, 5, 6, 7, 8, 9, 10 }; /*** Constructeur et Destructeur ***/ /***********************************/ -Editor::Editor() : N(0), NumDeco(0) -{ } +Editor::Editor() : + N(0), NumDeco(0) +{ +} Editor::~Editor() -{ } +{ +} /*** SDL Main ***/ /****************/ eMenu Editor::SDLMain(int NumNiv) { - int PyE; - int cx=0,cy=0; - bool Boutton=false; - int TypeB=-1; - int i,d,dx,dy; - - NumN=NumNiv; - - Affiche(); // Charge le tableau - SDL_RenderPresent(sdlRenderer); - - Horloge=SDL_GetTicks(); // Prend l'horloge - - Option=rail; - - // Initialise la sourie - mouse.Init(NULL); - - // Prend les evenements - do { - SDL_Event event; - while(SDL_PollEvent(&event)) { - mouse.GetEvent(event,PyE); // Prend les evenements de la sourie - switch(event.type) { - case SDL_WINDOWEVENT: - if(event.window.event==SDL_WINDOWEVENT_ENTER) Affiche(); - break; - case SDL_KEYDOWN: - if(event.key.state==SDL_PRESSED) { - if(event.key.keysym.sym==SDLK_ESCAPE) return mMenu; - else PrendTouche(event.key.keysym.sym); - } - break; - case SDL_MOUSEBUTTONDOWN: - if(event.button.state==SDL_PRESSED) { - Boutton=true; - TypeB=-1; - } - break; - case SDL_MOUSEBUTTONUP: - Boutton=false; - if(TypeB!=-1 && Option==deco && cx>=LT) { // Si doit effacer une décoration - level.T[NumN].NDeco--; - } - TypeB=-1; - break; - case SDL_QUIT: - return mQuit; - break; - } - } - - // Gère l'appuis du boutton de la sourie - cx=mouse.Px/D_Case; - cy=mouse.Py/D_Case; - - if(Boutton && cx= LT) { // Si doit effacer une décoration + level.T[NumN].NDeco--; + } + TypeB = -1; + break; + case SDL_QUIT: + return mQuit; + break; + } + } + + // Gère l'appuis du boutton de la sourie + cx = mouse.Px / D_Case; + cy = mouse.Py / D_Case; + + if (Boutton && cx < LT) + switch (Option) { + case deco: + if (TypeB == -1) { // Si première fois que appuis sur la touche + for (i = 0; i < level.T[NumN].NDeco; i++) { // Recherche si décoration proche du clic + dx = level.T[NumN].Deco[i].x - mouse.Px; + dy = level.T[NumN].Deco[i].y - mouse.Py; + d = dx * dx + dy * dy; + if (d <= (D_Case * 2) * (D_Case * 2)) { + TypeB = i; + } + } + if (TypeB == -1) { // Si doit fair un nouveau décor + level.T[NumN].NDeco++; + level.T[NumN].Deco[(level.T[NumN].NDeco - 1)].NumSpr = NumDeco; + level.T[NumN].Deco[(level.T[NumN].NDeco - 1)].x = mouse.Px; + level.T[NumN].Deco[(level.T[NumN].NDeco - 1)].y = mouse.Py; + TypeB = 1; + } + else { // Fait passe la selection au premier plan + level.T[NumN].Deco[level.T[NumN].NDeco].NumSpr = level.T[NumN].Deco[TypeB].NumSpr; + level.T[NumN].Deco[level.T[NumN].NDeco].x = level.T[NumN].Deco[TypeB].x; + level.T[NumN].Deco[level.T[NumN].NDeco].y = level.T[NumN].Deco[TypeB].y; + for (d = TypeB; d < level.T[NumN].NDeco; d++) { + level.T[NumN].Deco[d].NumSpr = level.T[NumN].Deco[d + 1].NumSpr; + level.T[NumN].Deco[d].x = level.T[NumN].Deco[d + 1].x; + level.T[NumN].Deco[d].y = level.T[NumN].Deco[d + 1].y; + } + NumDeco = level.T[NumN].Deco[(level.T[NumN].NDeco - 1)].NumSpr; + } + } + else { // Si pas la première fois remplace + level.T[NumN].Deco[(level.T[NumN].NDeco - 1)].NumSpr = NumDeco; + level.T[NumN].Deco[(level.T[NumN].NDeco - 1)].x = mouse.Px; + level.T[NumN].Deco[(level.T[NumN].NDeco - 1)].y = mouse.Py; + } + break; + case rail: + if (TypeB == -1) { + if (level.T[NumN].T[cy * LT + cx] != C_Rail) + TypeB = C_Rail; + else + TypeB = C_None; + } + level.T[NumN].T[cy * LT + cx] = TypeB; + break; + case wagon: + level.T[NumN].T[cy * LT + cx] = C_Wagon; + break; + case pluslong: + level.T[NumN].T[cy * LT + cx] = C_Allonge; + break; + case pluscourt: + level.T[NumN].T[cy * LT + cx] = C_Reduit; + break; + case vitesse: + level.T[NumN].T[cy * LT + cx] = C_Speed; + break; + case vie: + level.T[NumN].T[cy * LT + cx] = C_Live; + break; + case (e_Sprite)(locomotive + D_Haut): + case (e_Sprite)(locomotive + D_Bas): + case (e_Sprite)(locomotive + D_Gauche): + case (e_Sprite)(locomotive + D_Droite): + level.T[NumN].DepX = cx; + level.T[NumN].DepY = cy; + level.T[NumN].DepDir = (int)(Option) - (int)(locomotive); + break; + default: + break; + } + + // Gère les Horloges et la pose + HorlogeAvant = Horloge; + Horloge = SDL_GetTicks(); + Sleeping(); + + // Fait l'affichage + Affiche(); + SDL_RenderPresent(sdlRenderer); + + } while (true); + + return mQuit; } /*** Charge un tableau ***/ /*************************/ void Editor::Affiche() { - int i,x,y,m,cx,cy; - unsigned char *T; - - // Prend l'adresse du niveau - T=level.T[NumN].T; - - // Fabrique le fond du jeu - Sprites[fond].Affiche(400,300,0); - - // Affiche le circuit - for(i=0;i=C_Rail && T[i]0 && T[i-LT]>=1 && T[i-LT]=1 && T[i+LT]0 && T[i-1]>=1 && T[i-1]=1 && T[i+1]= C_Rail && T[i] < C_Fin) { + y = i / LT * D_Case + D_Case / 2; + x = i % LT * D_Case + D_Case / 2; + + m = 0; + cx = i % LT; + cy = i / LT; + if (cy > 0 && T[i - LT] >= 1 && T[i - LT] < C_Fin) + m += 8; + if (cy < HT - 1 && T[i + LT] >= 1 && T[i + LT] < C_Fin) + m += 4; + if (cx > 0 && T[i - 1] >= 1 && T[i - 1] < C_Fin) + m += 2; + if (cx < LT - 1 && T[i + 1] >= 1 && T[i + 1] < C_Fin) + m += 1; + + Sprites[rail].Affiche(x, y, NumRail[m]); + } + } + + // Affiche les décorations + for (i = 0; i < level.T[NumN].NDeco; i++) + Sprites[deco].Affiche(level.T[NumN].Deco[i].x, level.T[NumN].Deco[i].y, level.T[NumN].Deco[i].NumSpr); + + // Affiche numero du niveau + AfficheChiffre(740, 130, NumN + 1); + + // Affiche les options + for (i = 0; i < LT * HT; i++) { + switch (T[i]) { + case C_Wagon: // Si un loco + Sprites[wagon].Affiche(i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2, 25); + break; + case C_Allonge: // Si plus long + Sprites[pluslong].Affiche(i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2, 25); + break; + case C_Reduit: // Si plus court + Sprites[pluscourt].Affiche(i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2, 25); + break; + case C_Speed: // Si plus vite + Sprites[vitesse].Affiche(i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2, 25); + break; + case C_Live: // Si une vie + Sprites[vie].Affiche(i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2, 25); + break; + } + } + + // Affiche le départ de la locomotive + switch (level.T[NumN].DepDir) { + case D_Haut: + Sprites[locomotive].Affiche(level.T[NumN].DepX * D_Case + D_Case / 2, level.T[NumN].DepY * D_Case + D_Case / 2, 0); + break; + case D_Bas: + Sprites[locomotive].Affiche(level.T[NumN].DepX * D_Case + D_Case / 2, level.T[NumN].DepY * D_Case + D_Case / 2, 40); + break; + case D_Gauche: + Sprites[locomotive].Affiche(level.T[NumN].DepX * D_Case + D_Case / 2, level.T[NumN].DepY * D_Case + D_Case / 2, 80); + break; + case D_Droite: + Sprites[locomotive].Affiche(level.T[NumN].DepX * D_Case + D_Case / 2, level.T[NumN].DepY * D_Case + D_Case / 2, 120); + break; } - } - - // Affiche les décorations - for(i=0;i=Sprites[deco].N) NumDeco=0; - break; - case 'o': - Option=deco; - NumDeco--; - if(NumDeco<0) NumDeco=Sprites[deco].N-1; - break; - case SDLK_INSERT: - level.Ins(NumN); - break; - case SDLK_DELETE: - level.Del(NumN); - break; - case SDLK_UP: - Option=(e_Sprite)(locomotive+D_Haut); - break; - case SDLK_DOWN: - Option=(e_Sprite)(locomotive+D_Bas); - break; - case SDLK_LEFT: - Option=(e_Sprite)(locomotive+D_Gauche); - break; - case SDLK_RIGHT: - Option=(e_Sprite)(locomotive+D_Droite); - break; - case 'c': - level.Clear(NumN); - break; - case '$': - // test si le dernier niveau est vide - for(j=i=0;i= Sprites[deco].N) + NumDeco = 0; + break; + case 'o': + Option = deco; + NumDeco--; + if (NumDeco < 0) + NumDeco = Sprites[deco].N - 1; + break; + case SDLK_INSERT: + level.Ins(NumN); + break; + case SDLK_DELETE: + level.Del(NumN); + break; + case SDLK_UP: + Option = (e_Sprite)(locomotive + D_Haut); + break; + case SDLK_DOWN: + Option = (e_Sprite)(locomotive + D_Bas); + break; + case SDLK_LEFT: + Option = (e_Sprite)(locomotive + D_Gauche); + break; + case SDLK_RIGHT: + Option = (e_Sprite)(locomotive + D_Droite); + break; + case 'c': + level.Clear(NumN); + break; + case '$': + // test si le dernier niveau est vide + for (j = i = 0; i < LT * HT; i++) + j += level.T[level.N - 1].T[i]; + if (j == 0) { + if (NumN < level.N - 1) + level.N--; // Si vide ne le compte pas + } + + // Sauve le niveau + if (level.Save() == false) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error while saving levels"); + exit(-1); + } + + // test le niveau + Pref.Niveau = NumN; + game.SDLMain(); + mouse.Init(NULL); + Affiche(); + break; + case 'a': + Option = rail; + break; + case 'z': + Option = wagon; + break; + case 'e': + Option = pluslong; + break; + case 'r': + Option = pluscourt; + break; + case 't': + Option = vitesse; + break; + case 'y': + Option = vie; + break; } - - // test le niveau - Pref.Niveau=NumN; - game.SDLMain(); - mouse.Init(NULL); - Affiche(); - break; - case 'a': - Option=rail; - break; - case 'z': - Option=wagon; - break; - case 'e': - Option=pluslong; - break; - case 'r': - Option=pluscourt; - break; - case 't': - Option=vitesse; - break; - case 'y': - Option=vie; - break; - } } diff --git a/src/editor.h b/src/editor.h index 6d7b38a..92794de 100644 --- a/src/editor.h +++ b/src/editor.h @@ -29,21 +29,22 @@ /*** Définition de la class ***/ /******************************/ -class Editor { - public: - Editor(void); - ~Editor(void); - - /*** Fonctions ***/ - /*****************/ - eMenu SDLMain(int NumNiveau); // Boucle principale - void Affiche(void); // Charge un tableau - void PrendTouche(int Touche); // Prend les touches enfoncées - - /*** Variables ***/ - int N; // Numero du tableau à éditer - e_Sprite Option; - int NumDeco; - int NumN; +class Editor +{ +public: + Editor(void); + ~Editor(void); + + /*** Fonctions ***/ + /*****************/ + eMenu SDLMain(int NumNiveau); // Boucle principale + void Affiche(void); // Charge un tableau + void PrendTouche(int Touche); // Prend les touches enfoncées + + /*** Variables ***/ + int N; // Numero du tableau à éditer + e_Sprite Option; + int NumDeco; + int NumN; }; #endif diff --git a/src/game.cc b/src/game.cc index 8488e0a..cb3374e 100644 --- a/src/game.cc +++ b/src/game.cc @@ -1,5 +1,5 @@ // (_||_/ -// ( ) +// ( ) // ( o 0 ) //-OOO°--(_)---°OOO--------------------------------------- // Copyright (C) 2006 By Dominique Roux-Serret @@ -48,7 +48,7 @@ extern Menu MainMenu; extern Level level; extern Audio Sons; -static int NumRail[]={ -1,-1,-1,0,-1,1,2,3,-1,4,5,6,7,8,9,10 }; +static int NumRail[] = { -1, -1, -1, 0, -1, 1, 2, 3, -1, 4, 5, 6, 7, 8, 9, 10 }; int MasqueK; // Masque pour les touches de déplacement @@ -56,473 +56,506 @@ int MasqueK; // Masque pour les touches de déplacement /***********************************/ Game::Game() { - NumSS=0; - Touche[0]=D_Haut; - Touche[1]=D_Bas; - Touche[2]=D_Gauche; - Touche[3]=D_Droite; + NumSS = 0; + Touche[0] = D_Haut; + Touche[1] = D_Bas; + Touche[2] = D_Gauche; + Touche[3] = D_Droite; } Game::~Game() -{ } +{ +} /*** SDL Main ***/ /****************/ eMenu Game::SDLMain(void) { - eMenu mRet; - int NumN=Pref.Niveau; - - Help=true; - Load(NumN); // Charge le tableau - SDL_RenderPresent(sdlRenderer); - Ec.CleanSpriteAndScreen(fjeu); - Pause=true; - - Horloge=SDL_GetTicks(); // Prend l'horloge - DureeJeu=0; - Key=0; - - // Met le options de départ du joueur - Pref.NVie=N_VIES_DEP; - Pref.Score=0; - - // Prend les evenements - do { - SDL_RenderClear(sdlRenderer); - SDL_Event event; - while(SDL_PollEvent(&event)) { - switch(event.type) { - case SDL_WINDOWEVENT: - if(event.window.event==SDL_WINDOWEVENT_ENTER) { - } - else if(event.window.event==SDL_WINDOWEVENT_LEAVE) { // Si désactive l'ecran - Pause=true; // Met en Pause - } - break; - case SDL_MOUSEBUTTONDOWN: - if(event.button.state==SDL_PRESSED) { - // Add a Pause event if we click on the top right loco - int Px=event.button.x; - int Py=event.button.y; - if(Px>=680 && Py<=90) { - mRet=MainMenu.SDLMain_InGame(); - if(mRet==mGame) { - DrawLevel(NumN); - SDL_RenderPresent(sdlRenderer); - Pause=true; - } - else return mRet; - } - else if(Pause) { - Pause = false; - } - else { - TourneFleche(); - } - } - break; - case SDL_KEYDOWN: - if(event.key.state==SDL_PRESSED) { - if(event.key.keysym.sym==SDLK_ESCAPE || event.key.keysym.sym==SDLK_AC_BACK) { - mRet=MainMenu.SDLMain_InGame(); - if(mRet==mGame) { - DrawLevel(NumN); - SDL_RenderPresent(sdlRenderer); - Pause=true; - } - else return mRet; - } - else { - Key=event.key.keysym.sym; - switch(Key) { - case SDLK_UP: - MasqueK|=1; - break; - case SDLK_DOWN: - MasqueK|=2; - break; - case SDLK_LEFT: - MasqueK|=4; - break; - case SDLK_RIGHT: - MasqueK|=8; - break; - } - } - } - break; - case SDL_KEYUP: - switch(event.key.keysym.sym) { - case SDLK_UP: - MasqueK&=14; - break; - case SDLK_DOWN: - MasqueK&=13; - break; - case SDLK_LEFT: - MasqueK&=11; - break; - case SDLK_RIGHT: - MasqueK&=7; - break; - default: - break; - } - if(!MasqueK) Key=0; - break; - case SDL_QUIT: - return mQuit; - break; - } - } - - // Gère l'appui des touches - if(Key && Lo.Mort==-1) PrendTouche(Key); - - // Gère les Horloges et la pose - HorlogeAvant=Horloge; - Horloge=SDL_GetTicks(); - Sleeping(); - if(Pause==true || Lo.Mort>Horloge) HorlogeAvant=Horloge; - DureeJeu+=Horloge-HorlogeAvant; - - // Fait avancer la loco - if(Lo.Mort==-1 && Pause==false) Lo.Avance(Horloge-HorlogeAvant,DureeJeu,Touche,T); - - // Fait l'affichage - DrawLevel(NumN); - AfficheEcran(); - SDL_RenderPresent(sdlRenderer); + eMenu mRet; + int NumN = Pref.Niveau; - // Test la fin d'une partie - if(Lo.Mort>-1 && Lo.Mort= 680 && Py <= 90) { + mRet = MainMenu.SDLMain_InGame(); + if (mRet == mGame) { + DrawLevel(NumN); + SDL_RenderPresent(sdlRenderer); + Pause = true; + } + else + return mRet; + } + else if (Pause) { + Pause = false; + } + else { + TourneFleche(); + } + } + break; + case SDL_KEYDOWN: + if (event.key.state == SDL_PRESSED) { + if (event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_AC_BACK) { + mRet = MainMenu.SDLMain_InGame(); + if (mRet == mGame) { + DrawLevel(NumN); + SDL_RenderPresent(sdlRenderer); + Pause = true; + } + else + return mRet; + } + else { + Key = event.key.keysym.sym; + switch (Key) { + case SDLK_UP: + MasqueK |= 1; + break; + case SDLK_DOWN: + MasqueK |= 2; + break; + case SDLK_LEFT: + MasqueK |= 4; + break; + case SDLK_RIGHT: + MasqueK |= 8; + break; + } + } + } + break; + case SDL_KEYUP: + switch (event.key.keysym.sym) { + case SDLK_UP: + MasqueK &= 14; + break; + case SDLK_DOWN: + MasqueK &= 13; + break; + case SDLK_LEFT: + MasqueK &= 11; + break; + case SDLK_RIGHT: + MasqueK &= 7; + break; + default: + break; + } + if (!MasqueK) + Key = 0; + break; + case SDL_QUIT: + return mQuit; + break; + } + } + + // Gère l'appui des touches + if (Key && Lo.Mort == -1) + PrendTouche(Key); + + // Gère les Horloges et la pose + HorlogeAvant = Horloge; + Horloge = SDL_GetTicks(); + Sleeping(); + if (Pause == true || Lo.Mort > Horloge) + HorlogeAvant = Horloge; + DureeJeu += Horloge - HorlogeAvant; + + // Fait avancer la loco + if (Lo.Mort == -1 && Pause == false) + Lo.Avance(Horloge - HorlogeAvant, DureeJeu, Touche, T); + + // Fait l'affichage + DrawLevel(NumN); + AfficheEcran(); + SDL_RenderPresent(sdlRenderer); + + // Test la fin d'une partie + if (Lo.Mort > -1 && Lo.Mort < Horloge) { // Si est Mort test si doit continuer ou quitter + if (Pref.NVie < 0) + return mScoreEdit; // Si mort fini + if (Lo.Gagne) { #ifndef DCHILDREN - if(MainMenu.SDLMain_HR()==mQuit) return mQuit; + if (MainMenu.SDLMain_HR() == mQuit) + return mQuit; #endif - NumN++; - if(level.N==NumN) { - Pref.Score+=Pref.NVie*100; - return mScoreEdit; - } - if(Pref.NiveauMax=C_Rail && T[i]0 && T[i-LT]>=C_Rail && T[i-LT]=C_Rail && T[i+LT]0 && T[i-1]>=C_Rail && T[i-1]<=C_Fin) m+=2; - if(cx=C_Rail && T[i+1]<=C_Fin) m+=1; - - Sprites[rail].Affiche(x,y,NumRail[m],Sprites[fjeu].Image[0]); + int i, x, y, m, cx, cy; + + // Fabrique le fond du jeu + Sprites[fond].Affiche(400, 300, 0, Sprites[fjeu].Image[0]); + + // Affiche le circuit + for (i = 0; i < LT * HT; i++) { + if (T[i] >= C_Rail && T[i] < C_Fin) { + y = i / LT * D_Case + D_Case / 2; + x = i % LT * D_Case + D_Case / 2; + + m = 0; + cx = i % LT; + cy = i / LT; + if (cy > 0 && T[i - LT] >= C_Rail && T[i - LT] < C_Fin) + m += 8; + if (cy < HT - 1 && T[i + LT] >= C_Rail && T[i + LT] < C_Fin) + m += 4; + if (cx > 0 && T[i - 1] >= C_Rail && T[i - 1] <= C_Fin) + m += 2; + if (cx < LT - 1 && T[i + 1] >= C_Rail && T[i + 1] <= C_Fin) + m += 1; + + Sprites[rail].Affiche(x, y, NumRail[m], Sprites[fjeu].Image[0]); + } } - } - // Affiche les décorations + // Affiche les décorations #ifndef DCHILDREN - for(i=0;i=32) && TouSDLK_F15) ) - Tou=(int)(' '); // Press any key! - - switch(Tou) { - case SDLK_UP: - BufTouche(D_Haut); - break; - case SDLK_DOWN: - BufTouche(D_Bas); - break; - case SDLK_LEFT: - BufTouche(D_Gauche); - break; - case SDLK_RIGHT: - BufTouche(D_Droite); - break; - case SDLK_F12: // Sauve un screenshot - sprintf(NomSS,"screenshot%i.bmp",NumSS); - NumSS++; - //TODO SDL_SaveBMP(sdlVideo,NomSS); - break; - case 'p': - case 'P': - if(Pause==false) Pause=true; - break; - case ' ': - if(Pause) Pause=false; - break; - case 'h': - case 'H': - if(Help) Help=false; - else Help=true; - break; - } + char NomSS[40]; + + if (Pause == true && (Tou == SDLK_RETURN || Tou >= 32) && Tou < SDLK_RALT && (Tou < SDLK_F12 || Tou > SDLK_F15)) + Tou = (int)(' '); // Press any key! + + switch (Tou) { + case SDLK_UP: + BufTouche(D_Haut); + break; + case SDLK_DOWN: + BufTouche(D_Bas); + break; + case SDLK_LEFT: + BufTouche(D_Gauche); + break; + case SDLK_RIGHT: + BufTouche(D_Droite); + break; + case SDLK_F12: // Sauve un screenshot + sprintf(NomSS, "screenshot%i.bmp", NumSS); + NumSS++; + // TODO SDL_SaveBMP(sdlVideo,NomSS); + break; + case 'p': + case 'P': + if (Pause == false) + Pause = true; + break; + case ' ': + if (Pause) + Pause = false; + break; + case 'h': + case 'H': + if (Help) + Help = false; + else + Help = true; + break; + } } /*** Fait tourner la fleche d'une simple touche ***/ /**************************************************/ void Game::TourneFleche(void) { - int To=Touche[0]; - bool Cherche=false; - int x=Lo.PInter%LT; - int y=Lo.PInter/LT; - - do { - // Fait toucher la direction dans le sens des aiguilles d'une montre - // et test si la nouvelle direction est possible - switch(To) { - case D_Haut: - To=D_Droite; - if(Lo.PEntree!=D_Droite && x+10 && T[Lo.PInter-1]!=0) Cherche=true; - break; - case D_Gauche: - To=D_Haut; - if(Lo.PEntree!=D_Haut && y>0 && T[Lo.PInter-LT]!=0) Cherche=true; - break; - } - } - while(Cherche==false); - - BufTouche(To); // Mémorise la nouvelle touche par defaut. + int To = Touche[0]; + bool Cherche = false; + int x = Lo.PInter % LT; + int y = Lo.PInter / LT; + + do { + // Fait toucher la direction dans le sens des aiguilles d'une montre + // et test si la nouvelle direction est possible + switch (To) { + case D_Haut: + To = D_Droite; + if (Lo.PEntree != D_Droite && x + 1 < LT && T[Lo.PInter + 1] != 0) + Cherche = true; + break; + case D_Droite: + To = D_Bas; + if (Lo.PEntree != D_Bas && y + 1 < HT && T[Lo.PInter + LT] != 0) + Cherche = true; + break; + case D_Bas: + To = D_Gauche; + if (Lo.PEntree != D_Gauche && x > 0 && T[Lo.PInter - 1] != 0) + Cherche = true; + break; + case D_Gauche: + To = D_Haut; + if (Lo.PEntree != D_Haut && y > 0 && T[Lo.PInter - LT] != 0) + Cherche = true; + break; + } + } while (Cherche == false); + + BufTouche(To); // Mémorise la nouvelle touche par defaut. } - + /*** Mémorise une touche dans le buffet des touches ***/ /******************************************************/ void Game::BufTouche(int Tou) { - int n=0; - - // Favorise la touche - while(Touche[n]!=Tou) n++; // Prend position de la touche + int n = 0; + + // Favorise la touche + while (Touche[n] != Tou) + n++; // Prend position de la touche + + if (n) { // Si changement doit faire un décalage + while (n) { + Touche[n] = Touche[n - 1]; + n--; + } + Touche[0] = Tou; // Mémorise la touche + } - if(n) { // Si changement doit faire un décalage - while(n) { - Touche[n]=Touche[n-1]; - n--; + // Cherche son oposé + switch (Tou) { + case D_Haut: + Tou = D_Bas; + break; + case D_Bas: + Tou = D_Haut; + break; + case D_Gauche: + Tou = D_Droite; + break; + case D_Droite: + Tou = D_Gauche; + break; } - Touche[0]=Tou; // Mémorise la touche - } - - // Cherche son oposé - switch(Tou) { - case D_Haut: - Tou=D_Bas; - break; - case D_Bas: - Tou=D_Haut; - break; - case D_Gauche: - Tou=D_Droite; - break; - case D_Droite: - Tou=D_Gauche; - break; - } - - // Défavorise son oposé. - n=3; - while(Touche[n]!=Tou) n--; // Prend position de la touche - - if(n<3) { // Si changement doit faire un décalage - while(n<3) { - Touche[n]=Touche[n+1]; - n++; + + // Défavorise son oposé. + n = 3; + while (Touche[n] != Tou) + n--; // Prend position de la touche + + if (n < 3) { // Si changement doit faire un décalage + while (n < 3) { + Touche[n] = Touche[n + 1]; + n++; + } + Touche[3] = Tou; // Mémorise la touche } - Touche[3]=Tou; // Mémorise la touche - } } /*** Test les directions possibles pour les fleches ***/ /******************************************************/ -int Game::TestFleche(int Haut,int Bas,int Gauche,int Droite) +int Game::TestFleche(int Haut, int Bas, int Gauche, int Droite) { - int i; - int x=Lo.PInter%LT; - int y=Lo.PInter/LT; - - for(i=0;i<4;i++) { - switch(Touche[i]) { - case D_Haut: - if(y>0 && Haut!=-1 && T[Lo.PInter-LT]!=0) return Haut; - break; - case D_Bas: - if(y+10 && Gauche!=-1 && T[Lo.PInter-1]!=0) return Gauche; - break; - case D_Droite: - if(x+1 0 && Haut != -1 && T[Lo.PInter - LT] != 0) + return Haut; + break; + case D_Bas: + if (y + 1 < HT && Bas != -1 && T[Lo.PInter + LT] != 0) + return Bas; + break; + case D_Gauche: + if (x > 0 && Gauche != -1 && T[Lo.PInter - 1] != 0) + return Gauche; + break; + case D_Droite: + if (x + 1 < LT && Droite != -1 && T[Lo.PInter + 1] != 0) + return Droite; + break; + } } - } - return 0; + return 0; } /*** Affiche un ecran du jeu ***/ /*******************************/ void Game::AfficheEcran(void) { - int i; - int ndir=0; - - // Prépare pour nouvelle Affichage - Ec.ClearSprite(fjeu); - - // Fait nouvelle Affichage - Lo.Display(Ec); // Affiche la loco - - if(Lo.PInter!=-1 && Help) { // Affiche la fleche sur la futur intersection - switch(Lo.PEntree) { - case D_Gauche: - ndir=TestFleche(0,2,-1,1); - break; - case D_Droite: - ndir=TestFleche(8,6,7,-1); - break; - case D_Haut: - ndir=TestFleche(-1,4,5,3); - break; - case D_Bas: - ndir=TestFleche(10,-1,9,11); - break; + int i; + int ndir = 0; + + // Prépare pour nouvelle Affichage + Ec.ClearSprite(fjeu); + + // Fait nouvelle Affichage + Lo.Display(Ec); // Affiche la loco + + if (Lo.PInter != -1 && Help) { // Affiche la fleche sur la futur intersection + switch (Lo.PEntree) { + case D_Gauche: + ndir = TestFleche(0, 2, -1, 1); + break; + case D_Droite: + ndir = TestFleche(8, 6, 7, -1); + break; + case D_Haut: + ndir = TestFleche(-1, 4, 5, 3); + break; + case D_Bas: + ndir = TestFleche(10, -1, 9, 11); + break; + } + + Ec.PrintSprite(dir, ndir, (Lo.PInter % LT) * D_Case + D_Case / 2, (Lo.PInter / LT) * D_Case + D_Case / 2); } - Ec.PrintSprite(dir,ndir,(Lo.PInter%LT)*D_Case+D_Case/2,(Lo.PInter/LT)*D_Case+D_Case/2); - } - - // Affiche les options - for(i=0;iECARTWAGON_MOY) Ec.PrintSprite(pluslong,(DureeJeu*40/1000)%50,715,295); - if(Pref.VitesseMoy>Pref.Vitesse) Ec.PrintSprite(vitesse,(DureeJeu*40/1000+7)%50,765,295); + // Si en pose demande une touche + if (Pause) + Ec.PrintText(T_press_any_key, LT * D_Case / 2, 300); + + // Affiche tableau de bord + Ec.PrintOptions(Pref.NVie, Pref.Score); + if (Pref.EcartWagon < ECARTWAGON_MOY) + Ec.PrintSprite(pluscourt, (DureeJeu * 40 / 1000) % 50, 715, 295); + if (Pref.EcartWagon > ECARTWAGON_MOY) + Ec.PrintSprite(pluslong, (DureeJeu * 40 / 1000) % 50, 715, 295); + if (Pref.VitesseMoy > Pref.Vitesse) + Ec.PrintSprite(vitesse, (DureeJeu * 40 / 1000 + 7) % 50, 765, 295); } diff --git a/src/game.h b/src/game.h index 1279045..1da1083 100644 --- a/src/game.h +++ b/src/game.h @@ -29,35 +29,36 @@ /*** Définition de la class ***/ /******************************/ -class Game { - public: - Game(void); - ~Game(void); +class Game +{ +public: + Game(void); + ~Game(void); - /*** Fonctions ***/ - /*****************/ - eMenu SDLMain(void); // Boucle principale - bool Load(int NiveauN); // Charge un tableau - bool DrawLevel(int NiveauN); // Dessine le niveau - void PrendTouche(int Touche); // Prend les touches enfoncées + /*** Fonctions ***/ + /*****************/ + eMenu SDLMain(void); // Boucle principale + bool Load(int NiveauN); // Charge un tableau + bool DrawLevel(int NiveauN); // Dessine le niveau + void PrendTouche(int Touche); // Prend les touches enfoncées - void TourneFleche(void); // Fait tourner la fleche d'un simple clic. - void BufTouche(int Touche); // Met une nouvelle touche dans le buffet - int TestFleche(int Haut,int Bas,int Gauche,int Droite); // Test la direction de sortie de la fleche - void AfficheEcran(void); // Fait l'affichage d'un ecran de jeu + void TourneFleche(void); // Fait tourner la fleche d'un simple clic. + void BufTouche(int Touche); // Met une nouvelle touche dans le buffet + int TestFleche(int Haut, int Bas, int Gauche, int Droite); // Test la direction de sortie de la fleche + void AfficheEcran(void); // Fait l'affichage d'un ecran de jeu - /*** Variables ***/ - bool Pause; // Si en pose + /*** Variables ***/ + bool Pause; // Si en pose - long DureeJeu; // Horloge de durée du jeu + long DureeJeu; // Horloge de durée du jeu - int Key; // Mémorise la touche enfoncée - int Touche[4]; // Direction demandée - int T[LT*HT]; // Pointe sur le tableau + int Key; // Mémorise la touche enfoncée + int Touche[4]; // Direction demandée + int T[LT * HT]; // Pointe sur le tableau - Loco Lo; // Gère la locomotive + Loco Lo; // Gère la locomotive - int NumSS; // Numéro du Screen shot - bool Help; // Si doit affiche les fleches d'aide + int NumSS; // Numéro du Screen shot + bool Help; // Si doit affiche les fleches d'aide }; #endif diff --git a/src/level.cc b/src/level.cc index ebc0dae..7f59fe5 100644 --- a/src/level.cc +++ b/src/level.cc @@ -1,5 +1,5 @@ // (_||_/ -// ( ) +// ( ) // ( o 0 ) //-OOO°--(_)---°OOO--------------------------------------- // Copyright (C) 2006 By Dominique Roux-Serret @@ -28,10 +28,12 @@ /*** Constructeurs ***/ /*********************/ -Level::Level(void) : N(0) +Level::Level(void) : + N(0) { - int i; - for(i=0;iNum;i--) { - for(j=0;j Num; i--) { + for (j = 0; j < LT * HT; j++) + T[i].T[j] = T[i - 1].T[j]; + T[i].DepX = T[i - 1].DepX; + T[i].DepY = T[i - 1].DepY; + T[i].DepDir = T[i - 1].DepDir; + T[i].NDeco = T[i - 1].NDeco; + for (j = 0; j < T[i].NDeco; j++) { + T[i].Deco[j].x = T[i - 1].Deco[j].x; + T[i].Deco[j].y = T[i - 1].Deco[j].y; + T[i].Deco[j].NumSpr = T[i - 1].Deco[j].NumSpr; + } + } + + Clear(Num); + N++; } - - Clear(Num); - N++; - } } /*** Vide un tableau ***/ /***********************/ void Level::Clear(int Num) { - int i; + int i; - for(i=0;i0) { // Si doit afficher les cables - // Calcule le point d'accroche en sortie - cdx=x1-(int)(sin(ar)*lv); - cdy=y1-(int)(cos(ar)*lv); - - // Affiche le cable - Ec.PrintCable(cdx,cdy,cfx,cfy); + float ltrain = 0; + float p1, p2, a, ar, vx, vy; + int x1, x2, y1, y2; + int i, ns = 0; + int cdx, cdy, cfx = 0, cfy = 0; // Points d'accroche des cables + float lv; + + // Affiche tous les wagons + for (i = 0; i < NWagon; i++) { + // Cherche les points du wagons + switch (Wagon[i]) { + case charbon: + p1 = ltrain + 11; + p2 = ltrain + 36 - 11; + ltrain += 36.0; + lv = 18; + break; + default: + p1 = ltrain + 11; + p2 = ltrain + 40 - 11; + ltrain += 40.0; + lv = 20; + } + + // Calcule la position des points + FindPoint(D - p1, x1, y1); + FindPoint(D - p2, x2, y2); + + PosWagon[i].dx = x1; // Sauve la position des points pour test de colision futur + PosWagon[i].dy = y1; + PosWagon[i].fx = x2; + PosWagon[i].fy = y2; + + // Calcule l'angle de rotation de la loco et le N° du Sprite + if (x1 <= x2) { // Angle 0 à 180 compris + vy = (float)(x2 - x1); + vx = (float)(y2 - y1); + if (vx != 0) + a = atan(vy / vx) * 180.0 / M_PI; + else + a = 90.0; + if (vx < 0) + a = 180.0 + a; + } + else { // Angle 180.001 à 359.999 + vy = (float)(x1 - x2); + vx = (float)(y1 - y2); + if (vx != 0) + a = atan(vy / vx) * 180.0 / M_PI + 180.0; + else + a = 270.0; + if (vx < 0) + a = 180.0 + a; + } + ar = a * M_PI / 180.0; + + // Prend le centre du sprite + x1 = (x1 + x2) / 2; + y1 = (y1 + y2) / 2; + + // Affiche les cables de liaison + if (i > 0) { // Si doit afficher les cables + // Calcule le point d'accroche en sortie + cdx = x1 - (int)(sin(ar) * lv); + cdy = y1 - (int)(cos(ar) * lv); + + // Affiche le cable + Ec.PrintCable(cdx, cdy, cfx, cfy); + } + // Calcule le crocher de fin pour le prochaine wagon + cfx = x1 - (int)(sin(ar + M_PI) * lv); + cfy = y1 - (int)(cos(ar + M_PI) * lv); + + // Cherche le N° du Sprite + switch ((int)a) { + case 0: // En haut + ns = (int)(y1 + D_Case / 2) % (int)D_Case; + break; + case 180: // En bas + ns = (int)(y1 + D_Case / 2) % (int)D_Case + 40; + break; + case 90: // Gauche + ns = (int)(x1 + D_Case / 2) % (int)D_Case + 80; + break; + case 270: // Droite + ns = (int)(x1 + D_Case / 2) % (int)D_Case + 120; + break; + default: + ns = (int)(a * 160.0 / 360.0); + if (ns >= 160) + ns = 0; + ns += 160; + } + + Ec.PrintSprite(Wagon[i], ns, x1, y1); + + // Si pas fini la sequence d'affiche de départ du wagon + if (PosWagon[i].SprStart < N_SPR_START) { + PosWagon[i].SprStart += MemoDuree * N_SPR_START / 750.0; + if (PosWagon[i].SprStart < N_SPR_START) + Ec.PrintSprite(nouveau_wagon, (int)(PosWagon[i].SprStart), x1, y1); + } + + // Met l'ecart entre les wagons + ltrain += Pref.EcartWagon; } - // Calcule le crocher de fin pour le prochaine wagon - cfx=x1-(int)(sin(ar+M_PI)*lv); - cfy=y1-(int)(cos(ar+M_PI)*lv); - - // Cherche le N° du Sprite - switch( (int)a ) { - case 0: // En haut - ns=(int)(y1+D_Case/2)%(int)D_Case; - break; - case 180: // En bas - ns=(int)(y1+D_Case/2)%(int)D_Case+40; - break; - case 90: // Gauche - ns=(int)(x1+D_Case/2)%(int)D_Case+80; - break; - case 270: // Droite - ns=(int)(x1+D_Case/2)%(int)D_Case+120; - break; - default: - ns=(int)(a*160.0/360.0); - if(ns>=160) ns=0; - ns+=160; - } - - Ec.PrintSprite(Wagon[i],ns,x1,y1); - - // Si pas fini la sequence d'affiche de départ du wagon - if(PosWagon[i].SprStart=DMoy) { - // Test si sur une option - switch(Tableau[T[PLoco].P]) { - case C_Wagon: // Une nouvelle loco - Sons.Play(sWagon); - Tableau[T[PLoco].P]=1; // efface l'option - Pref.Score+=5; - AddLoco(); // Ajoute une loco au azard - - Gagne=true; // Test si la dernière loco - for(i=0;iDureeJeu) Reduit=DureeJeu-1; - else Alonge=DureeJeu+DUREE_ALONGE; - break; - case C_Reduit: // Si réduit la loco - Sons.Play(sReduit); - Tableau[T[PLoco].P]=1; // efface l'option - if(Alonge>DureeJeu) Alonge=DureeJeu-1; - else Reduit=DureeJeu+DUREE_REDUIT; - break; - case C_Speed: // Si Vitesse - Sons.Play(sSpeed); - Tableau[T[PLoco].P]=1; // efface l'option - Pref.Score+=30; - Vitesse=DureeJeu+DUREE_VITESSE; - break; - case C_Live: // Si Vie - Sons.Play(sLive); - Tableau[T[PLoco].P]=1; // efface l'option - Pref.NVie++; - break; - } - - // Test de colision avec un autre Wagon - for(i=1;i= DMoy) { + // Test si sur une option + switch (Tableau[T[PLoco].P]) { + case C_Wagon: // Une nouvelle loco + Sons.Play(sWagon); + Tableau[T[PLoco].P] = 1; // efface l'option + Pref.Score += 5; + AddLoco(); // Ajoute une loco au azard + + Gagne = true; // Test si la dernière loco + for (i = 0; i < LT * HT; i++) + if (Tableau[i] == C_Wagon) + Gagne = false; + if (Gagne) { + Mort = Horloge + DUREE_PAUSE; + Sons.Play(sEnd); + } + break; + case C_Allonge: // Alonge la loco + Sons.Play(sEtire); + Tableau[T[PLoco].P] = 1; // efface l'option + Pref.Score += 20; + if (Reduit > DureeJeu) + Reduit = DureeJeu - 1; + else + Alonge = DureeJeu + DUREE_ALONGE; + break; + case C_Reduit: // Si réduit la loco + Sons.Play(sReduit); + Tableau[T[PLoco].P] = 1; // efface l'option + if (Alonge > DureeJeu) + Alonge = DureeJeu - 1; + else + Reduit = DureeJeu + DUREE_REDUIT; + break; + case C_Speed: // Si Vitesse + Sons.Play(sSpeed); + Tableau[T[PLoco].P] = 1; // efface l'option + Pref.Score += 30; + Vitesse = DureeJeu + DUREE_VITESSE; + break; + case C_Live: // Si Vie + Sons.Play(sLive); + Tableau[T[PLoco].P] = 1; // efface l'option + Pref.NVie++; + break; + } + + // Test de colision avec un autre Wagon + for (i = 1; i < NWagon; i++) { + vx = (float)(PosWagon[i].dx - PosWagon[0].dx); + vy = (float)(PosWagon[i].dy - PosWagon[0].dy); + Ec1 = vx * vx + vy * vy; + vx = (float)(PosWagon[i].fx - PosWagon[0].dx); + vy = (float)(PosWagon[i].fy - PosWagon[0].dy); + Ec2 = vx * vx + vy * vy; + + // Si colition le signale + if (Mort < Horloge && (Ec1 < RAYON_TOUCHE || Ec2 <= RAYON_TOUCHE)) { + Sons.Play(sCrash); + Pref.NVie--; + Mort = Horloge + DUREE_PAUSE; + } + } } - } } /*** Fait Avancer la locomotive ***/ /**********************************/ -void Loco::Avance(int Duree,long DureeJeu,int *Touche,int *Tableau) +void Loco::Avance(int Duree, long DureeJeu, int *Touche, int *Tableau) { - int i; - float Dist=Pref.VitesseMoy*(float)(Duree)/1000.0; - - - MemoDuree=(float)(Duree); - - TestCase(Dist,DureeJeu,Tableau); - - // Test si doit Réduire le wagon - if(Reduit>DureeJeu) { - if(Pref.EcartWagon>ECARTWAGON_MIN) { // Si doit réduire - Pref.EcartWagon-=(float)(Duree)*(Pref.VitesseMoy*0.8/(float)(NWagon-1))/1000.0; - if(Pref.EcartWagon DureeJeu) { + if (Pref.EcartWagon > ECARTWAGON_MIN) { // Si doit réduire + Pref.EcartWagon -= (float)(Duree) * (Pref.VitesseMoy * 0.8 / (float)(NWagon - 1)) / 1000.0; + if (Pref.EcartWagon < ECARTWAGON_MIN) + Pref.EcartWagon = ECARTWAGON_MIN; + } } - } - else { // Si temps est passé - if(Pref.EcartWagonECARTWAGON_MOY) Pref.EcartWagon=ECARTWAGON_MOY; + else { // Si temps est passé + if (Pref.EcartWagon < ECARTWAGON_MOY) { // Si doit ralonger le wagon + Pref.EcartWagon += (float)(Duree) * (Pref.VitesseMoy * 0.8 / (float)(NWagon)) / 1000.0; + if (Pref.EcartWagon > ECARTWAGON_MOY) + Pref.EcartWagon = ECARTWAGON_MOY; + } } - } - - // Test si doit Ralonger le wagon - if(Alonge>DureeJeu) { - if(Pref.EcartWagonECARTWAGON_MAX) Pref.EcartWagon=ECARTWAGON_MAX; + + // Test si doit Ralonger le wagon + if (Alonge > DureeJeu) { + if (Pref.EcartWagon < ECARTWAGON_MAX) { // Si doit Ralonger + Pref.EcartWagon += (float)(Duree) * (Pref.VitesseMoy * 0.8 / (float)(NWagon)) / 1000.0; + if (Pref.EcartWagon > ECARTWAGON_MAX) + Pref.EcartWagon = ECARTWAGON_MAX; + } } - } - else { // Si temps est passé - if(Pref.EcartWagon>ECARTWAGON_MOY) { // Si doit ralonger le wagon - Pref.EcartWagon-=(float)(Duree)*(Pref.VitesseMoy*0.8/(float)(NWagon-1))/1000.0; - if(Pref.EcartWagon ECARTWAGON_MOY) { // Si doit ralonger le wagon + Pref.EcartWagon -= (float)(Duree) * (Pref.VitesseMoy * 0.8 / (float)(NWagon - 1)) / 1000.0; + if (Pref.EcartWagon < ECARTWAGON_MOY) + Pref.EcartWagon = ECARTWAGON_MOY; + } } - } - // Test si doit modifier la vitesse de la loco - if(Vitesse>DureeJeu) { - if(Pref.VitesseMoyPref.Vitesse*2) Pref.VitesseMoy=Pref.Vitesse*2; + // Test si doit modifier la vitesse de la loco + if (Vitesse > DureeJeu) { + if (Pref.VitesseMoy < Pref.Vitesse * 2) { // Si doit accelerer + Pref.VitesseMoy += (float)(Duree) / 40.0; + if (Pref.VitesseMoy > Pref.Vitesse * 2) + Pref.VitesseMoy = Pref.Vitesse * 2; + } } - } - else { - if(Pref.VitesseMoy>Pref.Vitesse) { // Si doit ralentir - Pref.VitesseMoy-=(float)(Duree)/40.0; - if(Pref.VitesseMoy Pref.Vitesse) { // Si doit ralentir + Pref.VitesseMoy -= (float)(Duree) / 40.0; + if (Pref.VitesseMoy < Pref.Vitesse) + Pref.VitesseMoy = Pref.Vitesse; + } } - } - - // Tand que dépasse la case en distante - while(D+Dist>T[PLoco].D) { - Dist-=T[PLoco].D-D; // Enleve la distance restant à parcourir - D=T[PLoco].D; - - i=0; // Cherche la direction possible - while(TestDir(Touche[i],Tableau)==false) i++; - - Go(Touche[i]); // Fait avancer le loco suivant le désir du joueur - - DoFleche(Tableau,Touche); // Recherche la position de la futur intersection - - TestCase(Dist,DureeJeu,Tableau); // Test la case au cas ou le jeu est vraiment lent - - } - - D+=Dist; // Met à la bonne position finale - - if(PInter==-1) DoFleche(Tableau,Touche); -} -/*** Recherche la position de la futur intersection ***/ -/******************************************************/ -void Loco::DoFleche(int *Tableau,int *Touche) -{ - int Sortie=T[PLoco].Sortie; - int MemoS; - int NVoie; - int x,y,Tou; - int i=0; + // Tand que dépasse la case en distante + while (D + Dist > T[PLoco].D) { + Dist -= T[PLoco].D - D; // Enleve la distance restant à parcourir + D = T[PLoco].D; - if(T[PLoco].P!=PInter && PInter!=-1) return; // Si pas encore arrivé sur la case de croisement + i = 0; // Cherche la direction possible + while (TestDir(Touche[i], Tableau) == false) + i++; - PInter=T[PLoco].P; // Prend la position de la loco + Go(Touche[i]); // Fait avancer le loco suivant le désir du joueur - do { - // Vas à la nouvelle case - switch(Sortie) { - case D_Haut: - PInter-=LT; - PEntree=D_Bas; - break; - case D_Gauche: - PInter--; - PEntree=D_Droite; - break; - case D_Bas: - PInter+=LT; - PEntree=D_Haut; - break; - case D_Droite: - PInter++; - PEntree=D_Gauche; - break; - } + DoFleche(Tableau, Touche); // Recherche la position de la futur intersection - // Compte les voies disponibles. - MemoS=Sortie; - x=PInter%LT; - y=PInter/LT; - NVoie=0; - if(y>0 && PEntree!=D_Haut && Tableau[PInter-LT]!=0) { - Sortie=D_Haut; - NVoie++; - } - if(y+10 && PEntree!=D_Gauche && Tableau[PInter-1]!=0) { - Sortie=D_Gauche; - NVoie++; - } - if(x+10 && !MasqueK) { // Prend la direction de la loco comme direction par defaut - Tou=Touche[i]; - while(i) { - Touche[i]=Touche[i-1]; - i--; + + D += Dist; // Met à la bonne position finale + + if (PInter == -1) + DoFleche(Tableau, Touche); +} + +/*** Recherche la position de la futur intersection ***/ +/******************************************************/ +void Loco::DoFleche(int *Tableau, int *Touche) +{ + int Sortie = T[PLoco].Sortie; + int MemoS; + int NVoie; + int x, y, Tou; + int i = 0; + + if (T[PLoco].P != PInter && PInter != -1) + return; // Si pas encore arrivé sur la case de croisement + + PInter = T[PLoco].P; // Prend la position de la loco + + do { + // Vas à la nouvelle case + switch (Sortie) { + case D_Haut: + PInter -= LT; + PEntree = D_Bas; + break; + case D_Gauche: + PInter--; + PEntree = D_Droite; + break; + case D_Bas: + PInter += LT; + PEntree = D_Haut; + break; + case D_Droite: + PInter++; + PEntree = D_Gauche; + break; + } + + // Compte les voies disponibles. + MemoS = Sortie; + x = PInter % LT; + y = PInter / LT; + NVoie = 0; + if (y > 0 && PEntree != D_Haut && Tableau[PInter - LT] != 0) { + Sortie = D_Haut; + NVoie++; + } + if (y + 1 < HT && PEntree != D_Bas && Tableau[PInter + LT] != 0) { + Sortie = D_Bas; + NVoie++; + } + if (x > 0 && PEntree != D_Gauche && Tableau[PInter - 1] != 0) { + Sortie = D_Gauche; + NVoie++; + } + if (x + 1 < LT && PEntree != D_Droite && Tableau[PInter + 1] != 0) { + Sortie = D_Droite; + NVoie++; + } + + } while (NVoie == 1); + + // Prend la direction de sortie comme direction par defaut + while (Touche[i] != MemoS) + i++; + if (i > 0 && !MasqueK) { // Prend la direction de la loco comme direction par defaut + Tou = Touche[i]; + while (i) { + Touche[i] = Touche[i - 1]; + i--; + } + Touche[0] = Tou; // Mémorise la touche } - Touche[0]=Tou; // Mémorise la touche - } - } /*** Test si une direction est possible ***/ /******************************************/ -bool Loco::TestDir(int FDir,int *Tableau) +bool Loco::TestDir(int FDir, int *Tableau) { - int PAvant=T[PLoco].P; - int x,y; - - // Test si les directions ne sont pas opposées - if(T[PLoco].Sortie==D_Haut && FDir==D_Bas) return false; - if(T[PLoco].Sortie==D_Bas && FDir==D_Haut) return false; - if(T[PLoco].Sortie==D_Gauche && FDir==D_Droite) return false; - if(T[PLoco].Sortie==D_Droite && FDir==D_Gauche) return false; - - PAvant+=AddDir[(T[PLoco].Sortie)]; // Position dans virage - - // Test si un bord - x=PAvant%LT; - y=PAvant/LT; - if(FDir==D_Haut && y==0) return false; - if(FDir==D_Bas && y+1==HT) return false; - if(FDir==D_Gauche && x==0) return false; - if(FDir==D_Droite && x+1==LT) return false; - - PAvant+=AddDir[FDir]; // Position futur - - if(Tableau[PAvant]==0) return false; // Test si il y a un rail - - return true; + int PAvant = T[PLoco].P; + int x, y; + + // Test si les directions ne sont pas opposées + if (T[PLoco].Sortie == D_Haut && FDir == D_Bas) + return false; + if (T[PLoco].Sortie == D_Bas && FDir == D_Haut) + return false; + if (T[PLoco].Sortie == D_Gauche && FDir == D_Droite) + return false; + if (T[PLoco].Sortie == D_Droite && FDir == D_Gauche) + return false; + + PAvant += AddDir[(T[PLoco].Sortie)]; // Position dans virage + + // Test si un bord + x = PAvant % LT; + y = PAvant / LT; + if (FDir == D_Haut && y == 0) + return false; + if (FDir == D_Bas && y + 1 == HT) + return false; + if (FDir == D_Gauche && x == 0) + return false; + if (FDir == D_Droite && x + 1 == LT) + return false; + + PAvant += AddDir[FDir]; // Position futur + + if (Tableau[PAvant] == 0) + return false; // Test si il y a un rail + + return true; } /*** Deplace la locomotive ***/ /*****************************/ bool Loco::Go(int FuturDir) { - int PTab=T[PLoco].P; - int Dir=T[PLoco].Sortie; - int Mask; - int i; - - // Test si risque de dépassement et enleve une bonne partie - if(PLoco==255) { - for(i=0;i<256-50;i++) { - T[i].P=T[i+50].P; - T[i].D=T[i+50].D; - T[i].Arrive=T[i+50].Arrive; - T[i].Sortie=T[i+50].Sortie; + int PTab = T[PLoco].P; + int Dir = T[PLoco].Sortie; + int Mask; + int i; + + // Test si risque de dépassement et enleve une bonne partie + if (PLoco == 255) { + for (i = 0; i < 256 - 50; i++) { + T[i].P = T[i + 50].P; + T[i].D = T[i + 50].D; + T[i].Arrive = T[i + 50].Arrive; + T[i].Sortie = T[i + 50].Sortie; + } + PLoco -= 50; + } + + // Mémorise la prochaine case + PLoco++; // Passe à la case suivante + + switch (Dir) { + case D_Haut: + PTab -= LT; + T[PLoco].Arrive = D_Bas; + break; + case D_Bas: + PTab += LT; + T[PLoco].Arrive = D_Haut; + break; + case D_Gauche: + PTab--; + T[PLoco].Arrive = D_Droite; + break; + default: + PTab++; + T[PLoco].Arrive = D_Gauche; + } + + // Donne futur direction et N° case avant + T[PLoco].P = PTab; + T[PLoco].Sortie = FuturDir; + + // Calcule la distance + Mask = T[PLoco].Arrive * 4 + T[PLoco].Sortie; + switch (Mask) { + case (D_Gauche * 4 + D_Droite): // Si vas tous droit + case (D_Droite * 4 + D_Gauche): + case (D_Haut * 4 + D_Bas): + case (D_Bas * 4 + D_Haut): + T[PLoco].D = T[PLoco - 1].D + D_Case; + break; + default: + T[PLoco].D = T[PLoco - 1].D + D_CaseR; + return true; } - PLoco-=50; - } - - // Mémorise la prochaine case - PLoco++; // Passe à la case suivante - - switch(Dir) { - case D_Haut: - PTab-=LT; - T[PLoco].Arrive=D_Bas; - break; - case D_Bas: - PTab+=LT; - T[PLoco].Arrive=D_Haut; - break; - case D_Gauche: - PTab--; - T[PLoco].Arrive=D_Droite; - break; - default: - PTab++; - T[PLoco].Arrive=D_Gauche; - } - - // Donne futur direction et N° case avant - T[PLoco].P=PTab; - T[PLoco].Sortie=FuturDir; - - // Calcule la distance - Mask=T[PLoco].Arrive*4+T[PLoco].Sortie; - switch(Mask) { - case (D_Gauche*4+D_Droite): // Si vas tous droit - case (D_Droite*4+D_Gauche): - case (D_Haut*4+D_Bas): - case (D_Bas*4+D_Haut): - T[PLoco].D=T[PLoco-1].D+D_Case; - break; - default: - T[PLoco].D=T[PLoco-1].D+D_CaseR; - return true; - } - return false; + return false; } - + /*** Recherche un point sur le parcour ***/ /*****************************************/ -void Loco::FindPoint(float Dist,int &x,int &y) +void Loco::FindPoint(float Dist, int &x, int &y) { - int NP=PLoco; - int P; - float D_Rest; - - // Recherche la case d'avant - while(T[NP-1].D>Dist) NP--; - P=T[NP].P; - - // Calcule les coordonnée suivant la direction - D_Rest=T[NP].D-Dist; - if(D_Rest==0) D_Rest=D_Case/1000.0; // Evite les erreurs de division - - switch(T[NP].Arrive*4+T[NP].Sortie) { - case (D_Gauche*4+D_Droite): - y=int(P/LT*D_Case+D_Case/2); - x=int(P%LT*D_Case+D_Case-D_Rest); - break; - case (D_Gauche*4+D_Haut): - x=int(P%LT*D_Case+cos(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - y=int(P/LT*D_Case+sin(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - break; - case (D_Gauche*4+D_Bas): - x=int(P%LT*D_Case+cos(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - y=int(P/LT*D_Case+D_Case-sin(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - break; - - case (D_Droite*4+D_Gauche): - y=int(P/LT*D_Case+D_Case/2); - x=int(P%LT*D_Case+D_Rest); - break; - case (D_Droite*4+D_Haut): - x=int(P%LT*D_Case+D_Case-cos(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - y=int(P/LT*D_Case+sin(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - break; - case (D_Droite*4+D_Bas): - x=int(P%LT*D_Case+D_Case-cos(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - y=int(P/LT*D_Case+D_Case-sin(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - break; - - case (D_Bas*4+D_Haut): - x=int(P%LT*D_Case+D_Case/2); - y=int(P/LT*D_Case+D_Rest); - break; - case (D_Bas*4+D_Gauche): - x=int(P%LT*D_Case+sin(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - y=int(P/LT*D_Case+D_Case-cos(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - break; - case (D_Bas*4+D_Droite): - x=int(P%LT*D_Case+D_Case-sin(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - y=int(P/LT*D_Case+D_Case-cos(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - break; - - case (D_Haut*4+D_Bas): - x=int(P%LT*D_Case+D_Case/2); - y=int(P/LT*D_Case+D_Case-D_Rest); - break; - case (D_Haut*4+D_Gauche): - x=int(P%LT*D_Case+sin(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - y=int(P/LT*D_Case+cos(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - break; - case (D_Haut*4+D_Droite): - x=int(P%LT*D_Case+D_Case-sin(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - y=int(P/LT*D_Case+cos(D_Rest*PIQ/D_CaseR)*(D_Case/2.0)); - break; - } + int NP = PLoco; + int P; + float D_Rest; + + // Recherche la case d'avant + while (T[NP - 1].D > Dist) + NP--; + P = T[NP].P; + + // Calcule les coordonnée suivant la direction + D_Rest = T[NP].D - Dist; + if (D_Rest == 0) + D_Rest = D_Case / 1000.0; // Evite les erreurs de division + + switch (T[NP].Arrive * 4 + T[NP].Sortie) { + case (D_Gauche * 4 + D_Droite): + y = int(P / LT * D_Case + D_Case / 2); + x = int(P % LT * D_Case + D_Case - D_Rest); + break; + case (D_Gauche * 4 + D_Haut): + x = int(P % LT * D_Case + cos(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + y = int(P / LT * D_Case + sin(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + break; + case (D_Gauche * 4 + D_Bas): + x = int(P % LT * D_Case + cos(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + y = int(P / LT * D_Case + D_Case - sin(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + break; + + case (D_Droite * 4 + D_Gauche): + y = int(P / LT * D_Case + D_Case / 2); + x = int(P % LT * D_Case + D_Rest); + break; + case (D_Droite * 4 + D_Haut): + x = int(P % LT * D_Case + D_Case - cos(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + y = int(P / LT * D_Case + sin(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + break; + case (D_Droite * 4 + D_Bas): + x = int(P % LT * D_Case + D_Case - cos(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + y = int(P / LT * D_Case + D_Case - sin(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + break; + + case (D_Bas * 4 + D_Haut): + x = int(P % LT * D_Case + D_Case / 2); + y = int(P / LT * D_Case + D_Rest); + break; + case (D_Bas * 4 + D_Gauche): + x = int(P % LT * D_Case + sin(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + y = int(P / LT * D_Case + D_Case - cos(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + break; + case (D_Bas * 4 + D_Droite): + x = int(P % LT * D_Case + D_Case - sin(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + y = int(P / LT * D_Case + D_Case - cos(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + break; + + case (D_Haut * 4 + D_Bas): + x = int(P % LT * D_Case + D_Case / 2); + y = int(P / LT * D_Case + D_Case - D_Rest); + break; + case (D_Haut * 4 + D_Gauche): + x = int(P % LT * D_Case + sin(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + y = int(P / LT * D_Case + cos(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + break; + case (D_Haut * 4 + D_Droite): + x = int(P % LT * D_Case + D_Case - sin(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + y = int(P / LT * D_Case + cos(D_Rest * PIQ / D_CaseR) * (D_Case / 2.0)); + break; + } } /*** Ajoute une loco au azrard ***/ /*********************************/ void Loco::AddLoco(void) { - Wagon[NWagon]=(e_Sprite)(rand()%(wagon-buches)+buches); - if(Wagon[NWagon]==Wagon[NWagon-1]) { // Evite 2 fois le meme wagon - if(Wagon[NWagon]+1==wagon) Wagon[NWagon]=buches; - else Wagon[NWagon]=(e_Sprite)(Wagon[NWagon]+1); - } - PosWagon[NWagon].dx=PosWagon[NWagon].dy=-10; - PosWagon[NWagon].fx=PosWagon[NWagon].fy=-10; - NWagon++; + Wagon[NWagon] = (e_Sprite)(rand() % (wagon - buches) + buches); + if (Wagon[NWagon] == Wagon[NWagon - 1]) { // Evite 2 fois le meme wagon + if (Wagon[NWagon] + 1 == wagon) + Wagon[NWagon] = buches; + else + Wagon[NWagon] = (e_Sprite)(Wagon[NWagon] + 1); + } + PosWagon[NWagon].dx = PosWagon[NWagon].dy = -10; + PosWagon[NWagon].fx = PosWagon[NWagon].fy = -10; + NWagon++; } diff --git a/src/loco.h b/src/loco.h index ddfa769..ea8775d 100644 --- a/src/loco.h +++ b/src/loco.h @@ -30,16 +30,18 @@ class Screen; /*** Definition de la classe qui mémorise les cases ***/ /******************************************************/ -struct s_TLoco { - int P; // Pointe sur le N° de la case - float D; // Distance parcoure (case comprie) - unsigned char Arrive,Sortie; // Direction d'arrivée et de sortie +struct s_TLoco +{ + int P; // Pointe sur le N° de la case + float D; // Distance parcoure (case comprie) + unsigned char Arrive, Sortie; // Direction d'arrivée et de sortie }; -struct s_PosWagon { // Mémorise la position avant et arrière des wagons pour le test de colision - int dx,dy; - int fx,fy; - float SprStart; // Si fini sa sequence d'affiche de départ +struct s_PosWagon +{ // Mémorise la position avant et arrière des wagons pour le test de colision + int dx, dy; + int fx, fy; + float SprStart; // Si fini sa sequence d'affiche de départ }; #define N_SPR_START 50 @@ -47,36 +49,36 @@ struct s_PosWagon { // Mémorise la position avant et arrière des wagons pour l /******************************/ class Loco { - public: - Loco(void); - ~Loco(void); +public: + Loco(void); + ~Loco(void); - /*** Fonctions ***/ - void Init(int Pos,int Direction); // Initialise la loco sur le tableau - void Display(Screen &Ec); // Fait l'affichage de la loco. - void TestCase(float Duree,long DureeJeu,int *Tableau); // Test les options sur la case si passe au centre - void Avance(int Dureems,long DureeJeu,int *Touche,int *Tableau); // Fait avancer la locomotive - void DoFleche(int *Tableau,int *Touche); // Recherche la position de la futur intersection - bool TestDir(int FuturDir,int *Tableau); // Test si une direction est possible - void AddLoco(void); // Ajoute une loco au azard + /*** Fonctions ***/ + void Init(int Pos, int Direction); // Initialise la loco sur le tableau + void Display(Screen &Ec); // Fait l'affichage de la loco. + void TestCase(float Duree, long DureeJeu, int *Tableau); // Test les options sur la case si passe au centre + void Avance(int Dureems, long DureeJeu, int *Touche, int *Tableau); // Fait avancer la locomotive + void DoFleche(int *Tableau, int *Touche); // Recherche la position de la futur intersection + bool TestDir(int FuturDir, int *Tableau); // Test si une direction est possible + void AddLoco(void); // Ajoute une loco au azard - /*** Fonctions privées ***/ - inline bool Go(int FuturDirection); // Fait avancer le tableau (retourne true si tourne) - inline void FindPoint(float Dist,int &x,int &y); // Retourne la position d'un point sur le parcour + /*** Fonctions privées ***/ + inline bool Go(int FuturDirection); // Fait avancer le tableau (retourne true si tourne) + inline void FindPoint(float Dist, int &x, int &y); // Retourne la position d'un point sur le parcour - /*** Variables ***/ - long Reduit,Alonge,Vitesse; // Memorise l'horloge de fin si doit réduire ou alonger le train - int PLoco; // Position de la tête de la loco dans le tableau - int PInter; // Position de la futur intersection pour afficher la fleche - int PEntree; // Entrée le la loco sur une case pour la fleche - int Mort; // Mémorise l'heure + duree pour faire une pause aprés avoir touché un wagon - bool Gagne; // Si a fini le niveau - float D; // Distance parcourue par la loco - struct s_TLoco T[256]; // Mémorise le parcour de la loco maxi = 256 cases - int NWagon; // Mémorise le nombre de wagon - e_Sprite Wagon[256]; // Mémorise les wagons - struct s_PosWagon PosWagon[256]; // Mémorise position des wagons à l'écran pour test de colision - float MemoDuree; // Memorise la precedente durée pour faire avancer les explosions du depart + /*** Variables ***/ + long Reduit, Alonge, Vitesse; // Memorise l'horloge de fin si doit réduire ou alonger le train + int PLoco; // Position de la tête de la loco dans le tableau + int PInter; // Position de la futur intersection pour afficher la fleche + int PEntree; // Entrée le la loco sur une case pour la fleche + int Mort; // Mémorise l'heure + duree pour faire une pause aprés avoir touché un wagon + bool Gagne; // Si a fini le niveau + float D; // Distance parcourue par la loco + struct s_TLoco T[256]; // Mémorise le parcour de la loco maxi = 256 cases + int NWagon; // Mémorise le nombre de wagon + e_Sprite Wagon[256]; // Mémorise les wagons + struct s_PosWagon PosWagon[256]; // Mémorise position des wagons à l'écran pour test de colision + float MemoDuree; // Memorise la precedente durée pour faire avancer les explosions du depart }; #endif diff --git a/src/main.cc b/src/main.cc index 2aab1e3..50cf754 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,5 +1,5 @@ // (_||_/ -// ( ) +// ( ) // ( o 0 ) //-OOO°--(_)---°OOO--------------------------------------- // Copyright (C) 2006 By Dominique Roux-Serret @@ -43,21 +43,21 @@ SDL_Window *sdlWindow; // Pointe sur l'écran video SDL_Renderer *sdlRenderer; // Pointe sur l'écran video -char Titre[]="Li-ri V3.0.1"; +char Titre[] = "Li-ri V3.0.1"; -Sprite *Sprites=NULL; // Pointe sur les sprites -int NSprites=0; // Nombre de sprites en mémoire -Screen Ec; // Pointe sur les 2 buffets vidéo -sPreference Pref; // Tableau des préférences. -Game game; // Gère le jeu -Mouse mouse; // Gère les mouvements de sourie -Menu MainMenu; // Gère les menus -Level level; // Gère les niveaux -Editor Edit; // Gère le menu de l'éditeur -Audio Sons; // Gère les sons +Sprite *Sprites = NULL; // Pointe sur les sprites +int NSprites = 0; // Nombre de sprites en mémoire +Screen Ec; // Pointe sur les 2 buffets vidéo +sPreference Pref; // Tableau des préférences. +Game game; // Gère le jeu +Mouse mouse; // Gère les mouvements de sourie +Menu MainMenu; // Gère les menus +Level level; // Gère les niveaux +Editor Edit; // Gère le menu de l'éditeur +Audio Sons; // Gère les sons -int Horloge=0; // Horloges du jeu -int HorlogeAvant=0; +int Horloge = 0; // Horloges du jeu +int HorlogeAvant = 0; #ifdef __unix__ char DefPath[256]; // Chemin par defaut dans arg @@ -68,132 +68,137 @@ char DefPath[256]; // Chemin par defaut dans arg void InitPref(void) { #ifdef __unix__ - DefPath[0]=0; + DefPath[0] = 0; #endif - Pref.NiveauMax=0; - Pref.FullScreen=false; - Pref.Langue=-1; - Pref.Volume=(float)SDL_MIX_MAXVOLUME; - Pref.VolumeM=(float)SDL_MIX_MAXVOLUME; //*6.0/10.0; - - for(int i=0;i<8;i++) { // Vide les scores - Pref.Sco[i].Score=0; - Pref.Sco[i].Name[0]=0; - } -/* Pref.Sco[0].Score=11425; */ -/* sprintf(Pref.Sco[0].Name,"%s","Dominique"); */ -/* Pref.Sco[1].Score=678; */ -/* sprintf(Pref.Sco[1].Name,"%s","Veronique"); */ - - Utils::LoadPref(); - - Pref.Difficulte=Normal; - Pref.Vitesse=VITESSE_MOY; - Pref.VitesseMoy=VITESSE_MOY; - Pref.NVie=N_VIES_DEP; - Pref.EcartWagon=ECARTWAGON_MOY; + Pref.NiveauMax = 0; + Pref.FullScreen = false; + Pref.Langue = -1; + Pref.Volume = (float)SDL_MIX_MAXVOLUME; + Pref.VolumeM = (float)SDL_MIX_MAXVOLUME; //*6.0/10.0; + + for (int i = 0; i < 8; i++) { // Vide les scores + Pref.Sco[i].Score = 0; + Pref.Sco[i].Name[0] = 0; + } + /* Pref.Sco[0].Score=11425; */ + /* sprintf(Pref.Sco[0].Name,"%s","Dominique"); */ + /* Pref.Sco[1].Score=678; */ + /* sprintf(Pref.Sco[1].Name,"%s","Veronique"); */ + + Utils::LoadPref(); + + Pref.Difficulte = Normal; + Pref.Vitesse = VITESSE_MOY; + Pref.VitesseMoy = VITESSE_MOY; + Pref.NVie = N_VIES_DEP; + Pref.EcartWagon = ECARTWAGON_MOY; } /*** Preogramme principale ***/ /*****************************/ -int main(int narg,char *argv[]) +int main(int narg, char *argv[]) { - int i; - Sprite Spr; - eMenu RetM,RetMenu=mMenu; + int i; + Sprite Spr; + eMenu RetM, RetMenu = mMenu; - // Initialise les préferences - InitPref(); + // Initialise les préferences + InitPref(); #ifdef __unix__ - if(narg>1) strcpy(DefPath,argv[1]); + if (narg > 1) + strcpy(DefPath, argv[1]); #endif - - // Initiliase SDL - if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0 ) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to initialize SDL: %s", SDL_GetError()); - exit(-1); - } - // Ferme le programme correctement quand quit - atexit(SDL_Quit); - - // Demande la resolution Video - int vOption = SDL_WINDOW_RESIZABLE; - if(Pref.FullScreen) vOption|=SDL_WINDOW_FULLSCREEN_DESKTOP; - - sdlWindow = SDL_CreateWindow(Titre, 0, 0, 800, 600, vOption); - sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, 0); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); - SDL_RenderSetLogicalSize(sdlRenderer, 800, 600); - - SDL_ShowCursor(0); // Masque le curseur - - // Chargement des sprites - Sons.Init(); - if(LoadSprites()==false) exit(-1); - if(level.Load()==false) exit(-1); - - Sons.PlayMusic(); - mouse.InitStart(); - - // Initialise l'horloge et le hazard - HorlogeAvant=Horloge=SDL_GetTicks(); - srand(SDL_GetTicks()); - - // Si pas de langues demande la langue - if(Pref.Langue==-1) MainMenu.SDLMain_Language(); - - // Gère les menus - do { - switch(RetMenu) { - case mMenu: - RetM=MainMenu.SDLMain(); - break; - case mLangue: - RetM=MainMenu.SDLMain_Language(); - break; - case mOption: - RetM=MainMenu.SDLMain_Options(); - break; - case mScoreEdit: - RetM=MainMenu.SDLMain_Score(true); - break; - case mScore: - RetM=MainMenu.SDLMain_Score(); - break; - case mMenuSpeed: - RetM=MainMenu.SDLMain_Speed(); - break; - case mMenuNiveau: - RetM=MainMenu.SDLMain_Level(); - break; - case mGame: - Sons.LoadMusic(1); - RetM=game.SDLMain(); - Sons.LoadMusic(0); - break; - case mEdit: - RetM=Edit.SDLMain(0); - break; - default: - RetM=mQuit; + + // Initiliase SDL + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to initialize SDL: %s", SDL_GetError()); + exit(-1); } - RetMenu=RetM; - } while(RetMenu!=mQuit); - - // Ferme proprement le programme - Mix_HaltMusic(); // Arrete la music - Mix_FreeMusic(Sons.Music); // Efface la music - - for(i=0;i 3) + PyE = 0; + break; + case SDLK_F12: // Sauve un screenshot + // TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); + break; + case ' ': + case SDLK_RETURN: + case SDLK_KP_ENTER: + switch (PyE) { + case 0: + return mMenuNiveau; + case 1: + return mScore; + case 2: + return mOption; + case 3: + return mQuit; + } + break; + default: + key = event.key.keysym.sym & 0x7F; // Prend le caracataire correspondant à la touche + if (CharExiste(key) == true) { // Si la caractaire existe bien + for (i = 2; i >= 0; i--) + MCode[i + 1] = MCode[i]; // décale le code + MCode[0] = key; + if (strcmp(MCode, "tide") == 0 || strcmp(MCode, "TIDE") == 0) + return mEdit; // Si editeur de niveau + } + } + } + break; + case SDL_QUIT: + return mQuit; + break; + } + } - // Initialisations Divers - mouse.Init(Menu_Py); // Initialise la sourie - PyE=0; + // Gère les variables + HorlogeAvant = Horloge; + Horloge = SDL_GetTicks(); + Sleeping(); - // Prend les evenements - do { - SDL_RenderClear(sdlRenderer); - // Prend l'image du fond et fait l'affichage - Sprites[fond_menu].Affiche(400,300,0,Sprites[fmenu].Image[0]); - Sprites[menu].Affiche(400,340,0,Sprites[fmenu].Image[0]); - Sprites[titre].Affiche(400,65,0,Sprites[fmenu].Image[0]); - Sprites[copyright].Affiche(400,587,0,Sprites[fmenu].Image[0]); - - AfficheText(400,229,T_play,Sprites[fmenu].Image[0]); - AddBouton(0,T_play,400,229); - AfficheText(400,306,T_scores,Sprites[fmenu].Image[0]); - AddBouton(1,T_scores,400,306); - AfficheText(400,384,T_moptions,Sprites[fmenu].Image[0]); - AddBouton(2,T_moptions,400,384); - AfficheText(400,461,T_quit,Sprites[fmenu].Image[0]); - AddBouton(3,T_quit,400,461); - Menu_Py[4].DepX=-1; - SDL_Event event; - while(SDL_PollEvent(&event)) { - mouse.GetEvent(event,PyE); // Prend les evenements de la sourie - switch(event.type) { - case SDL_WINDOWEVENT: - if(event.window.event==SDL_WINDOWEVENT_ENTER) { - //SDL_RenderPresent(sdlRenderer); - } - break; - case SDL_KEYDOWN: - if(event.key.state==SDL_PRESSED) { - Sons.Play(sClic); - switch(event.key.keysym.sym) { - case SDLK_ESCAPE: - case SDLK_AC_BACK: // Android back button - return mQuit; - case SDLK_UP: - PyE--; - if(PyE<0) PyE=3; - break; - case SDLK_DOWN: - PyE++; - if(PyE>3) PyE=0; - break; - case SDLK_F12: // Sauve un screenshot - //TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); - break; - case ' ': - case SDLK_RETURN: - case SDLK_KP_ENTER: - switch(PyE) { - case 0: - return mMenuNiveau; - case 1: - return mScore; - case 2: - return mOption; - case 3: - return mQuit; - } - break; - default: - key=event.key.keysym.sym&0x7F; // Prend le caracataire correspondant à la touche - if(CharExiste(key)==true) { // Si la caractaire existe bien - for(i=2;i>=0;i--) MCode[i+1]=MCode[i]; // décale le code - MCode[0]=key; - if(strcmp(MCode,"tide")==0 || strcmp(MCode,"TIDE")==0) return mEdit; // Si editeur de niveau - } - } - } - break; - case SDL_QUIT: - return mQuit; - break; - } - } - - // Gère les variables - HorlogeAvant=Horloge; - Horloge=SDL_GetTicks(); - Sleeping(); - - // Gère l'Affichage - Ec.ClearSprite(fmenu); - Print_Main(); - mouse.Print(); - - // Echange les buffets video - SDL_RenderPresent(sdlRenderer); + // Gère l'Affichage + Ec.ClearSprite(fmenu); + Print_Main(); + mouse.Print(); + + // Echange les buffets video + SDL_RenderPresent(sdlRenderer); + + } while (true); - } while(true); - - return mQuit; + return mQuit; } /*** SDL Main Menu Choix de la langue ***/ /****************************************/ eMenu Menu::SDLMain_Language(void) { - int NCol=1; - int NL; - int Ecart; - int i; - int x,y; - int OldLangue=Pref.Langue; - - // Initialisations Divers - mouse.Init(Menu_Py); // Initialise la sourie - PyE=Pref.Langue; - if(PyE==-1) PyE=1; - - SDL_RenderClear(sdlRenderer); - // Prend l'image du fond et fait l'affichage - Sprites[fond_menu].Affiche(400,300,0,Sprites[fmenu].Image[0]); - - // Affiche les langues possibles - NCol=3; - if(Pref.NLangues%NCol==0) NL=Pref.NLangues/NCol; - else NL=Pref.NLangues/NCol+1; - Ecart=600/(NL+1); - - for(i=0;i=Pref.NLangues) PyE=0; - break; - case SDLK_LEFT: - if(PyE-NL>=0) PyE-=NL; - break; - case SDLK_RIGHT: - if(PyE+NL= Pref.NLangues) + PyE = 0; + break; + case SDLK_LEFT: + if (PyE - NL >= 0) + PyE -= NL; + break; + case SDLK_RIGHT: + if (PyE + NL < Pref.NLangues) + PyE += NL; + break; + case SDLK_F12: // Sauve un screenshot + // TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); + break; + case ' ': + case SDLK_RETURN: + case SDLK_KP_ENTER: + Pref.Langue = PyE; + if (Pref.Langue != OldLangue) + LoadLangue(); + return mMenu; + default: + break; + } + } + break; + case SDL_QUIT: + return mQuit; + break; + } + } + + // Gère les variables + HorlogeAvant = Horloge; + Horloge = SDL_GetTicks(); + Sleeping(); + + // Gère l'Affichage + Ec.ClearSprite(fmenu); // Something is done in the Efface that prevents a crash (or maybe more computation)! + Affiche_Main_Centre(); + + mouse.Print(); + + // Echange les buffets video + SDL_RenderPresent(sdlRenderer); + + } while (true); + + return mQuit; } /*** SDL Main Menu Choix des Options ***/ /***************************************/ void Menu::InitMain_Options(void) { - // Initialisations Divers - mouse.Init(Menu_Py); // Initialise la sourie - //PyE=4; - - // Prend l'image du fond et fait l'affichage - Sprites[fond_menu].Affiche(400,300,0,Sprites[fmenu].Image[0]); - Sprites[gmenu].Affiche(400,300,0,Sprites[fmenu].Image[0]); - Sprites[keys].Affiche(610,455,0,Sprites[fmenu].Image[0]); - - AddBouton(0,bruitage,140,110); - AddBouton(1,music,160,200); - - AddBouton(2,fscreen,190,300); - Menu_Py[2].DepX-=40; - Menu_Py[2].FinX=625+40+Sprites[fscreen].Dim[0].L/2; - Sprites[fscreen].Affiche(185,300,0,Sprites[fmenu].Image[0]); - Sprites[window].Affiche(625,300,0,Sprites[fmenu].Image[0]); - - AddBouton(3,monde,180,400); - - // Centre à gauche le text de menu - CentreM=120+Sprites[T_menu].Dim[0].L/2; - AfficheText(CentreM,490,T_menu,Sprites[fmenu].Image[0]); - AddBouton(4,T_menu,CentreM,490); - - // Boutons des bruitages - Sprites[fleches].Affiche(250,110,1,Sprites[fmenu].Image[0]); - Sprites[fleches].Affiche(700,110,4,Sprites[fmenu].Image[0]); - Menu_Py[5].DepX=230; - Menu_Py[5].DepY=70; - Menu_Py[5].FinX=475; - Menu_Py[5].FinY=145; - Menu_Py[5].Py=5; - Menu_Py[5].Valide=true; - - Menu_Py[6].DepX=476; - Menu_Py[6].DepY=70; - Menu_Py[6].FinX=720; - Menu_Py[6].FinY=145; - Menu_Py[6].Py=6; - Menu_Py[6].Valide=true; - - // Boutons de musics - Sprites[fleches].Affiche(250,200,1,Sprites[fmenu].Image[0]); - Sprites[fleches].Affiche(700,200,4,Sprites[fmenu].Image[0]); - Menu_Py[7].DepX=230; - Menu_Py[7].DepY=155; - Menu_Py[7].FinX=475; - Menu_Py[7].FinY=245; - Menu_Py[7].Py=7; - Menu_Py[7].Valide=true; - - Menu_Py[8].DepX=476; - Menu_Py[8].DepY=155; - Menu_Py[8].FinX=720; - Menu_Py[8].FinY=245; - Menu_Py[8].Py=8; - Menu_Py[8].Valide=true; - - Menu_Py[9].DepX=-1; + // Initialisations Divers + mouse.Init(Menu_Py); // Initialise la sourie + // PyE=4; + + // Prend l'image du fond et fait l'affichage + Sprites[fond_menu].Affiche(400, 300, 0, Sprites[fmenu].Image[0]); + Sprites[gmenu].Affiche(400, 300, 0, Sprites[fmenu].Image[0]); + Sprites[keys].Affiche(610, 455, 0, Sprites[fmenu].Image[0]); + + AddBouton(0, bruitage, 140, 110); + AddBouton(1, music, 160, 200); + + AddBouton(2, fscreen, 190, 300); + Menu_Py[2].DepX -= 40; + Menu_Py[2].FinX = 625 + 40 + Sprites[fscreen].Dim[0].L / 2; + Sprites[fscreen].Affiche(185, 300, 0, Sprites[fmenu].Image[0]); + Sprites[window].Affiche(625, 300, 0, Sprites[fmenu].Image[0]); + + AddBouton(3, monde, 180, 400); + + // Centre à gauche le text de menu + CentreM = 120 + Sprites[T_menu].Dim[0].L / 2; + AfficheText(CentreM, 490, T_menu, Sprites[fmenu].Image[0]); + AddBouton(4, T_menu, CentreM, 490); + + // Boutons des bruitages + Sprites[fleches].Affiche(250, 110, 1, Sprites[fmenu].Image[0]); + Sprites[fleches].Affiche(700, 110, 4, Sprites[fmenu].Image[0]); + Menu_Py[5].DepX = 230; + Menu_Py[5].DepY = 70; + Menu_Py[5].FinX = 475; + Menu_Py[5].FinY = 145; + Menu_Py[5].Py = 5; + Menu_Py[5].Valide = true; + + Menu_Py[6].DepX = 476; + Menu_Py[6].DepY = 70; + Menu_Py[6].FinX = 720; + Menu_Py[6].FinY = 145; + Menu_Py[6].Py = 6; + Menu_Py[6].Valide = true; + + // Boutons de musics + Sprites[fleches].Affiche(250, 200, 1, Sprites[fmenu].Image[0]); + Sprites[fleches].Affiche(700, 200, 4, Sprites[fmenu].Image[0]); + Menu_Py[7].DepX = 230; + Menu_Py[7].DepY = 155; + Menu_Py[7].FinX = 475; + Menu_Py[7].FinY = 245; + Menu_Py[7].Py = 7; + Menu_Py[7].Valide = true; + + Menu_Py[8].DepX = 476; + Menu_Py[8].DepY = 155; + Menu_Py[8].FinX = 720; + Menu_Py[8].FinY = 245; + Menu_Py[8].Py = 8; + Menu_Py[8].Valide = true; + + Menu_Py[9].DepX = -1; } - + /*** Gestion du menu Options ***/ /*******************************/ eMenu Menu::SDLMain_Options(void) { - int i,N; - int NumSp; + int i, N; + int NumSp; + + PyE = 4; + // Prend les evenements + do { + Ec.CleanSpriteAndScreen(fmenu); // To not crash... + SDL_RenderClear(sdlRenderer); + InitMain_Options(); // Prépare le menu + SDL_Event event; + while (SDL_PollEvent(&event)) { + mouse.GetEvent(event, PyE); // Prend les evenements de la sourie + switch (event.type) { + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_ENTER) { + SDL_RenderPresent(sdlRenderer); + } + break; + case SDL_KEYDOWN: + if (event.key.state == SDL_PRESSED) { + Sons.Play(sClic); + switch (event.key.keysym.sym) { + case SDLK_ESCAPE: + case SDLK_AC_BACK: // Android back button + return mMenu; + case SDLK_LEFT: + switch (PyE) { + case 2: + if (Pref.FullScreen == false) { + Pref.FullScreen = true; + ChangeVideo(); + PyE = 2; + } + break; + case 0: + case 5: // Diminue volume sons + case 6: + Pref.Volume -= SDL_MIX_MAXVOLUME / 10.0; + if (Pref.Volume < 0) + Pref.Volume = 0; + Sons.DoVolume(); + Sons.Play(sLive); + break; + case 1: + case 7: // Diminue volume music + case 8: + Pref.VolumeM -= SDL_MIX_MAXVOLUME / 10.0; + if (Pref.VolumeM < 0) + Pref.VolumeM = 0; + Sons.DoVolume(); + break; + } + break; + case SDLK_RIGHT: + switch (PyE) { + case 2: + if (Pref.FullScreen == true) { + Pref.FullScreen = false; + ChangeVideo(); + PyE = 2; + } + break; + case 0: + case 5: + case 6: + Pref.Volume += SDL_MIX_MAXVOLUME / 10.0; + if (Pref.Volume > SDL_MIX_MAXVOLUME) + Pref.Volume = SDL_MIX_MAXVOLUME; + Sons.DoVolume(); + Sons.Play(sLive); + break; + case 1: + case 7: + case 8: + Pref.VolumeM += SDL_MIX_MAXVOLUME / 10.0; + if (Pref.VolumeM > SDL_MIX_MAXVOLUME) + Pref.VolumeM = SDL_MIX_MAXVOLUME; + Sons.DoVolume(); + break; + } + break; + case SDLK_UP: + PyE--; + if (PyE < 0) + PyE = 4; + break; + case SDLK_DOWN: + PyE++; + if (PyE >= 5) + PyE = 0; + break; + case SDLK_F12: // Sauve un screenshot + // TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); + break; + case ' ': + case SDLK_RETURN: + case SDLK_KP_ENTER: + switch (PyE) { + case 0: + case 1: + break; + case 2: // Type d'affichage + Pref.FullScreen = (Pref.FullScreen + 1) & 1; + ChangeVideo(); + PyE = 2; + break; + case 3: // Choix de la langue + SDLMain_Language(); + PyE = 3; + break; + case 5: // Diminue volume sons + Pref.Volume -= SDL_MIX_MAXVOLUME / 10.0; + if (Pref.Volume < 0) + Pref.Volume = 0; + Sons.DoVolume(); + Sons.Play(sLive); + break; + case 6: + Pref.Volume += SDL_MIX_MAXVOLUME / 10.0; + if (Pref.Volume > SDL_MIX_MAXVOLUME) + Pref.Volume = SDL_MIX_MAXVOLUME; + Sons.DoVolume(); + Sons.Play(sLive); + break; + case 7: // Diminue volume music + Pref.VolumeM -= SDL_MIX_MAXVOLUME / 10.0; + if (Pref.VolumeM < 0) + Pref.VolumeM = 0; + Sons.DoVolume(); + break; + case 8: + Pref.VolumeM += SDL_MIX_MAXVOLUME / 10.0; + if (Pref.VolumeM > SDL_MIX_MAXVOLUME) + Pref.VolumeM = SDL_MIX_MAXVOLUME; + Sons.DoVolume(); + break; + default: + return mMenu; + } + default: + break; + } + } + break; + case SDL_QUIT: + return mQuit; + break; + } + } - PyE=4; - // Prend les evenements - do { - Ec.CleanSpriteAndScreen(fmenu); // To not crash... - SDL_RenderClear(sdlRenderer); - InitMain_Options(); // Prépare le menu - SDL_Event event; - while(SDL_PollEvent(&event)) { - mouse.GetEvent(event,PyE); // Prend les evenements de la sourie - switch(event.type) { - case SDL_WINDOWEVENT: - if(event.window.event==SDL_WINDOWEVENT_ENTER) { - SDL_RenderPresent(sdlRenderer); - } - break; - case SDL_KEYDOWN: - if(event.key.state==SDL_PRESSED) { - Sons.Play(sClic); - switch(event.key.keysym.sym) { - case SDLK_ESCAPE: - case SDLK_AC_BACK: // Android back button - return mMenu; - case SDLK_LEFT: - switch(PyE) { - case 2: - if(Pref.FullScreen==false) { - Pref.FullScreen=true; - ChangeVideo(); - PyE=2; - } - break; - case 0: - case 5: // Diminue volume sons - case 6: - Pref.Volume-=SDL_MIX_MAXVOLUME/10.0; - if(Pref.Volume<0) Pref.Volume=0; - Sons.DoVolume(); - Sons.Play(sLive); - break; - case 1: - case 7: // Diminue volume music - case 8: - Pref.VolumeM-=SDL_MIX_MAXVOLUME/10.0; - if(Pref.VolumeM<0) Pref.VolumeM=0; - Sons.DoVolume(); - break; - } - break; - case SDLK_RIGHT: - switch(PyE) { - case 2: - if(Pref.FullScreen==true) { - Pref.FullScreen=false; - ChangeVideo(); - PyE=2; - } - break; - case 0: - case 5: - case 6: - Pref.Volume+=SDL_MIX_MAXVOLUME/10.0; - if(Pref.Volume>SDL_MIX_MAXVOLUME) Pref.Volume=SDL_MIX_MAXVOLUME; - Sons.DoVolume(); - Sons.Play(sLive); - break; - case 1: - case 7: - case 8: - Pref.VolumeM+=SDL_MIX_MAXVOLUME/10.0; - if(Pref.VolumeM>SDL_MIX_MAXVOLUME) Pref.VolumeM=SDL_MIX_MAXVOLUME; - Sons.DoVolume(); - break; - } - break; - case SDLK_UP: - PyE--; - if(PyE<0) PyE=4; - break; - case SDLK_DOWN: - PyE++; - if(PyE>=5) PyE=0; - break; - case SDLK_F12: // Sauve un screenshot - //TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); - break; - case ' ': - case SDLK_RETURN: - case SDLK_KP_ENTER: - switch(PyE) { - case 0: - case 1: - break; - case 2: // Type d'affichage - Pref.FullScreen=(Pref.FullScreen+1)&1; - ChangeVideo(); - PyE=2; - break; - case 3: // Choix de la langue - SDLMain_Language(); - PyE=3; - break; - case 5: // Diminue volume sons - Pref.Volume-=SDL_MIX_MAXVOLUME/10.0; - if(Pref.Volume<0) Pref.Volume=0; - Sons.DoVolume(); - Sons.Play(sLive); - break; - case 6: - Pref.Volume+=SDL_MIX_MAXVOLUME/10.0; - if(Pref.Volume>SDL_MIX_MAXVOLUME) Pref.Volume=SDL_MIX_MAXVOLUME; - Sons.DoVolume(); - Sons.Play(sLive); - break; - case 7: // Diminue volume music - Pref.VolumeM-=SDL_MIX_MAXVOLUME/10.0; - if(Pref.VolumeM<0) Pref.VolumeM=0; - Sons.DoVolume(); - break; - case 8: - Pref.VolumeM+=SDL_MIX_MAXVOLUME/10.0; - if(Pref.VolumeM>SDL_MIX_MAXVOLUME) Pref.VolumeM=SDL_MIX_MAXVOLUME; - Sons.DoVolume(); - break; - default: - return mMenu; - } - default: + // SDL_RenderClear(sdlRenderer); + // Gère les variables + HorlogeAvant = Horloge; + Horloge = SDL_GetTicks(); + Sleeping(); + + // Gère l'Affichage + // Ec.Efface(fmenu); + + if (Pref.FullScreen) { + Ec.PrintSprite(fleches, 1, 350, 300); + Ec.PrintSprite(fleches, 3, 450, 300); + } + else { + Ec.PrintSprite(fleches, 0, 350, 300); + Ec.PrintSprite(fleches, 4, 450, 300); + } + + NumSp = (Horloge / 30) % 25; + Ec.PrintSprite(bruitage, NumSp, 150, 110); + NumSp = (Horloge / 30) % 25; + Ec.PrintSprite(music, NumSp, 150, 200); + NumSp = (Horloge / 50) % 50; + Ec.PrintSprite(monde, NumSp, 180, 400); + + N = (int)(Pref.Volume * 10 + 1) / SDL_MIX_MAXVOLUME; + NumSp = (Horloge / 50) % 40 + 120; + for (i = 0; i < N; i++) { + if (i == N - 1) + Ec.PrintSprite(locomotive, NumSp, (690 - 300) / 10 * i + 300, 110); + else + Ec.PrintSprite(buches, NumSp, (690 - 300) / 10 * i + 300, 110); + } + + N = (int)(Pref.VolumeM * 10 + 1) / SDL_MIX_MAXVOLUME; + for (i = 0; i < N; i++) { + if (i == N - 1) + Ec.PrintSprite(locomotive, NumSp, (690 - 300) / 10 * i + 300, 200); + else + Ec.PrintSprite(buches, NumSp, (690 - 300) / 10 * i + 300, 200); + } + + switch (PyE) { + case 3: + Print_Main(180); break; - } - } - break; - case SDL_QUIT: - return mQuit; - break; - } - } - - //SDL_RenderClear(sdlRenderer); - // Gère les variables - HorlogeAvant=Horloge; - Horloge=SDL_GetTicks(); - Sleeping(); - - // Gère l'Affichage - //Ec.Efface(fmenu); - - if(Pref.FullScreen) { - Ec.PrintSprite(fleches,1,350,300); - Ec.PrintSprite(fleches,3,450,300); - } - else { - Ec.PrintSprite(fleches,0,350,300); - Ec.PrintSprite(fleches,4,450,300); - } + case 4: + Print_Main(CentreM); + break; + case 5: + PyE = 0; + Print_Main(); + PyE = 5; + break; + case 6: + PyE = 0; + Print_Main(); + PyE = 6; + break; + case 7: + PyE = 1; + Print_Main(); + PyE = 7; + break; + case 8: + PyE = 1; + Print_Main(); + PyE = 8; + break; + default: + Print_Main(); + } - NumSp=(Horloge/30)%25; - Ec.PrintSprite(bruitage,NumSp,150,110); - NumSp=(Horloge/30)%25; - Ec.PrintSprite(music,NumSp,150,200); - NumSp=(Horloge/50)%50; - Ec.PrintSprite(monde,NumSp,180,400); - - N=(int)(Pref.Volume*10+1)/SDL_MIX_MAXVOLUME; - NumSp=(Horloge/50)%40+120; - for(i=0;i2) PyE=0; - break; - case SDLK_F12: // Sauve un screenshot - //TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); - break; - case ' ': - case SDLK_RETURN: - case SDLK_KP_ENTER: - switch(PyE) { - case 0: - Pref.Difficulte=Easy; - return mGame; - case 1: - Pref.Difficulte=Normal; - return mGame; - case 2: - Pref.Difficulte=Hard; - return mGame; - } - break; - default: - break; - } - } - break; - case SDL_QUIT: - return mQuit; - break; - } - } - - // Gère les variables - HorlogeAvant=Horloge; - Horloge=SDL_GetTicks(); - Sleeping(); - - // Gère l'Affichage - Ec.ClearSprite(fmenu); - Print_Main(); - mouse.Print(); - - // Echange les buffets video - SDL_RenderPresent(sdlRenderer); - - } while(true); - - return mQuit; + // Initialisations Divers + mouse.Init(Menu_Py); // Initialise la sourie + PyE = 1; + + // Prend les evenements + do { + Ec.CleanSpriteAndScreen(fmenu); + SDL_RenderClear(sdlRenderer); + // Prend l'image du fond et fait l'affichage + Sprites[fond_menu].Affiche(400, 300, 0, Sprites[fmenu].Image[0]); + Sprites[menu].Affiche(400, 340, 0, Sprites[fmenu].Image[0]); + Sprites[titre].Affiche(400, 65, 0, Sprites[fmenu].Image[0]); + + AfficheText(400, 225, T_easy, Sprites[fmenu].Image[0]); + AddBouton(0, T_easy, 400, 225); + AfficheText(400, 340, T_normal, Sprites[fmenu].Image[0]); + AddBouton(1, T_normal, 400, 340); + AfficheText(400, 455, T_hard, Sprites[fmenu].Image[0]); + AddBouton(2, T_hard, 400, 455); + Menu_Py[3].DepX = -1; + + SDL_Event event; + while (SDL_PollEvent(&event)) { + mouse.GetEvent(event, PyE); // Prend les evenements de la sourie + switch (event.type) { + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_ENTER) { + SDL_RenderPresent(sdlRenderer); + } + break; + case SDL_KEYDOWN: + if (event.key.state == SDL_PRESSED) { + Sons.Play(sClic); + switch (event.key.keysym.sym) { + case SDLK_ESCAPE: + case SDLK_AC_BACK: // Android back button + return Niv == 0 ? mMenu : mMenuNiveau; + case SDLK_UP: + PyE--; + if (PyE < 0) + PyE = 2; + break; + case SDLK_DOWN: + PyE++; + if (PyE > 2) + PyE = 0; + break; + case SDLK_F12: // Sauve un screenshot + // TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); + break; + case ' ': + case SDLK_RETURN: + case SDLK_KP_ENTER: + switch (PyE) { + case 0: + Pref.Difficulte = Easy; + return mGame; + case 1: + Pref.Difficulte = Normal; + return mGame; + case 2: + Pref.Difficulte = Hard; + return mGame; + } + break; + default: + break; + } + } + break; + case SDL_QUIT: + return mQuit; + break; + } + } + + // Gère les variables + HorlogeAvant = Horloge; + Horloge = SDL_GetTicks(); + Sleeping(); + + // Gère l'Affichage + Ec.ClearSprite(fmenu); + Print_Main(); + mouse.Print(); + + // Echange les buffets video + SDL_RenderPresent(sdlRenderer); + + } while (true); + + return mQuit; } /*** SDL Main Menu Choix du niveau ***/ /*************************************/ eMenu Menu::SDLMain_Level(void) { - // Initialisations Divers - mouse.Init(Menu_Py); // Initialise la sourie - PyE=0; - Niv=Pref.NiveauMax; - Pref.Niveau=0; - - if(Niv==0) return mMenuSpeed; // Inutile si la première fois - - // Prend les evenements - do { - // Efface le fond - SDL_RenderClear(sdlRenderer); - // Prend l'image du fond et fait l'affichage - Sprites[fond_menu].Affiche(400,300,0,Sprites[fmenu].Image[0]); - Sprites[menu].Affiche(400,340,0,Sprites[fmenu].Image[0]); - Sprites[titre].Affiche(400,65,0,Sprites[fmenu].Image[0]); - - AfficheText(400,225,T_new_game,Sprites[fmenu].Image[0]); - AddBouton(0,T_new_game,400,225); - AfficheText(400,320,T_old_level,Sprites[fmenu].Image[0]); - AddBouton(1,T_old_level,400,320); - AfficheText(400,455,T_menu,Sprites[fmenu].Image[0]); - AddBouton(2,T_menu,400,455); - - AddBouton(3,fleches,330,380); - AddBouton(4,fleches,470,380); - - Menu_Py[5].DepX=-1; - - SDL_Event event; - while(SDL_PollEvent(&event)) { - mouse.GetEvent(event,PyE); // Prend les evenements de la sourie - switch(event.type) { - case SDL_WINDOWEVENT: - if(event.window.event==SDL_WINDOWEVENT_ENTER) { - SDL_RenderPresent(sdlRenderer); - } - break; - case SDL_KEYDOWN: - if(event.key.state==SDL_PRESSED) { - Sons.Play(sClic); - switch(event.key.keysym.sym) { - case SDLK_ESCAPE: - case SDLK_AC_BACK: // Android back button - return mMenu; - case SDLK_UP: - PyE--; - if(PyE<0 || PyE>2) PyE=2; - break; - case SDLK_DOWN: - PyE++; - if(PyE>2) PyE=0; - break; - case SDLK_LEFT: - if(Niv>0) Niv--; - PyE=1; - break; - case SDLK_RIGHT: - if(Niv0) Niv--; - break; - case 4: - if(Niv0) { - if(PyE==3) Ec.PrintSprite(fleches,2,330,380); - else Ec.PrintSprite(fleches,1,330,380); - } - else Ec.PrintSprite(fleches,0,330,380); - - if(Niv 2) + PyE = 2; + break; + case SDLK_DOWN: + PyE++; + if (PyE > 2) + PyE = 0; + break; + case SDLK_LEFT: + if (Niv > 0) + Niv--; + PyE = 1; + break; + case SDLK_RIGHT: + if (Niv < Pref.NiveauMax) + Niv++; + PyE = 1; + break; + case SDLK_F12: // Sauve un screenshot + // TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); + break; + case ' ': + case SDLK_RETURN: + case SDLK_KP_ENTER: + switch (PyE) { + case 0: + return mMenuSpeed; + case 1: + Pref.Niveau = Niv; + return mMenuSpeed; + case 2: + return mMenu; + case 3: + if (Niv > 0) + Niv--; + break; + case 4: + if (Niv < Pref.NiveauMax) + Niv++; + break; + } + break; + default: + break; + } + } + break; + case SDL_QUIT: + return mQuit; + break; + } + } + + // Gère les variables + HorlogeAvant = Horloge; + Horloge = SDL_GetTicks(); + Sleeping(); + + // Gère l'Affichage + Ec.ClearSprite(fmenu); + + // Affiche les flèches + if (Niv > 0) { + if (PyE == 3) + Ec.PrintSprite(fleches, 2, 330, 380); + else + Ec.PrintSprite(fleches, 1, 330, 380); + } + else + Ec.PrintSprite(fleches, 0, 330, 380); + + if (Niv < Pref.NiveauMax) { + if (PyE == 4) + Ec.PrintSprite(fleches, 5, 470, 380); + else + Ec.PrintSprite(fleches, 4, 470, 380); + } + else + Ec.PrintSprite(fleches, 3, 470, 380); + + AfficheChiffre(400, 380, Niv + 1); + + if (PyE != 3 && PyE != 4) + Print_Main(); + mouse.Print(); + + // Echange les buffets video + SDL_RenderPresent(sdlRenderer); + + } while (true); + + return mQuit; } /*** SDL Main questions sur les droits de l'homme ***/ @@ -846,194 +892,205 @@ eMenu Menu::SDLMain_Level(void) #ifndef DCHILDREN eMenu Menu::SDLMain_HR(void) { - int Fini=-1; - int N1,N2,Ordre; - SDL_Rect Position; - - // InitialisationsDivers - mouse.Init(Menu_Py); // Initialise la sourie - PyE=rand()%2; - - // Choix de la question N1=reponse - N1=rand()%30; - do { - N2=rand()%30; - } while (N2==N1); - Ordre=rand()%2; // Si 0=bonne ordre, 1=inverse - - // Prend l'image du fond et fait l'affichage - Position.x=Position.y=0; - Position.w=Sprites[fmenu].Dim[0].L; - Position.h=Sprites[fmenu].Dim[0].H; - SDL_RenderCopy(sdlRenderer,Sprites[fmenu].Image[0],&Position,&Position); - - Sprites[menu].Affiche(340,300,0,Sprites[fmenu].Image[0]); - Sprites[fond_hr].Affiche(340,74,0,Sprites[fmenu].Image[0]); - AfficheText(338,70,e_Sprite(T_question),Sprites[fmenu].Image[0]); - - Sprites[locomotive].Affiche(115,110,rand()%320,Sprites[fmenu].Image[0]); - Sprites[deco].Affiche(100,160+(rand()%130),rand()%18,Sprites[fmenu].Image[0]); - Sprites[deco].Affiche(100,470-(rand()%130),rand()%18,Sprites[fmenu].Image[0]); - Sprites[deco].Affiche(580,100+(rand()%130),rand()%18,Sprites[fmenu].Image[0]); - Sprites[deco].Affiche(580,470-(rand()%130),rand()%18,Sprites[fmenu].Image[0]); - - AfficheText(340,300,e_Sprite(T_art1+N1),Sprites[fmenu].Image[0]); - - if(Ordre) { - AddBouton(0,e_Sprite(T_tart1+N1),240,492); - AddBouton(1,e_Sprite(T_tart1+N2),440,492); - } - else { - AddBouton(0,e_Sprite(T_tart1+N1),440,492); - AddBouton(1,e_Sprite(T_tart1+N2),240,492); - } - Menu_Py[0].DepY-=20; - Menu_Py[0].FinY+=20; - Menu_Py[1].DepY-=20; - Menu_Py[1].FinY+=20; - - Menu_Py[2].DepX=-1; - - std::array, 4> posDeco = {std::make_pair(rand()%130, rand()%18), std::make_pair(rand()%130, rand()%18), std::make_pair(rand()%130, rand()%18), std::make_pair(rand()%130, rand()%18)}; - int locoPosition = rand()%320; - - // Prend les evenements - do { - // Efface le fond - SDL_RenderClear(sdlRenderer); - - SDL_RenderCopy(sdlRenderer,Sprites[fmenu].Image[0],&Position,&Position); - - // Sprites[fond].Affiche(400,300,0,Sprites[fjeu].Image[0]); - Sprites[menu].Affiche(340,300,0,Sprites[fmenu].Image[0]); - Sprites[fond_hr].Affiche(340,74,0,Sprites[fmenu].Image[0]); - AfficheText(338,70,e_Sprite(T_question),Sprites[fmenu].Image[0]); - - Sprites[locomotive].Affiche(115,110,locoPosition,Sprites[fmenu].Image[0]); - Sprites[deco].Affiche(100,160+posDeco[0].first,posDeco[0].second,Sprites[fmenu].Image[0]); - Sprites[deco].Affiche(100,470-(posDeco[1].first),posDeco[1].second,Sprites[fmenu].Image[0]); - Sprites[deco].Affiche(580,100+(posDeco[2].first),posDeco[2].second,Sprites[fmenu].Image[0]); - Sprites[deco].Affiche(580,470-(posDeco[3].first),posDeco[3].second,Sprites[fmenu].Image[0]); - - AfficheText(340,300,e_Sprite(T_art1+N1),Sprites[fmenu].Image[0]); - /* - if(Ordre) { - AddBouton(0,e_Sprite(T_tart1+N1),240,492); - AddBouton(1,e_Sprite(T_tart1+N2),440,492); - } - else { - AddBouton(0,e_Sprite(T_tart1+N1),440,492); - AddBouton(1,e_Sprite(T_tart1+N2),240,492); - } - Menu_Py[0].DepY-=20; - Menu_Py[0].FinY+=20; - Menu_Py[1].DepY-=20; - Menu_Py[1].FinY+=20; - - Menu_Py[2].DepX=-1; -*/ - SDL_Event event; - while(SDL_PollEvent(&event)) { - mouse.GetEvent(event,PyE); // Prend les evenements de la sourie - switch(event.type) { - case SDL_WINDOWEVENT: - if(event.window.event==SDL_WINDOWEVENT_ENTER) { - } - break; - case SDL_KEYDOWN: - if(Fini==-1 && event.key.state==SDL_PRESSED) { - Sons.Play(sClic); - switch(event.key.keysym.sym) { - case SDLK_ESCAPE: - case SDLK_AC_BACK: // Android back button - return mGame; - case SDLK_UP: - PyE--; - if(PyE<0) PyE=1; - break; - case SDLK_DOWN: - PyE++; - if(PyE>1) PyE=0; - break; - case SDLK_LEFT: - if(Ordre) PyE=0; - else PyE=1; - break; - case SDLK_RIGHT: - if(Ordre) PyE=1; - else PyE=0; - break; - case SDLK_F12: // Sauve un screenshot - //TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); - break; - case ' ': - case SDLK_RETURN: - case SDLK_KP_ENTER: - switch(PyE) { - case 0: - Sons.Play(sEnd); - Pref.Score+=50; - Fini=Horloge+2000; - break; - case 1: - Sons.Play(sLose); - Fini=Horloge+2000; - break; - } - break; - default: - break; - } - } - break; - case SDL_QUIT: - return mQuit; - break; - } - } - - // Test si fini - if(Fini!=-1 && Fini, 4> posDeco = { std::make_pair(rand() % 130, rand() % 18), std::make_pair(rand() % 130, rand() % 18), std::make_pair(rand() % 130, rand() % 18), std::make_pair(rand() % 130, rand() % 18) }; + int locoPosition = rand() % 320; + + // Prend les evenements + do { + // Efface le fond + SDL_RenderClear(sdlRenderer); + + SDL_RenderCopy(sdlRenderer, Sprites[fmenu].Image[0], &Position, &Position); + + // Sprites[fond].Affiche(400,300,0,Sprites[fjeu].Image[0]); + Sprites[menu].Affiche(340, 300, 0, Sprites[fmenu].Image[0]); + Sprites[fond_hr].Affiche(340, 74, 0, Sprites[fmenu].Image[0]); + AfficheText(338, 70, e_Sprite(T_question), Sprites[fmenu].Image[0]); + + Sprites[locomotive].Affiche(115, 110, locoPosition, Sprites[fmenu].Image[0]); + Sprites[deco].Affiche(100, 160 + posDeco[0].first, posDeco[0].second, Sprites[fmenu].Image[0]); + Sprites[deco].Affiche(100, 470 - (posDeco[1].first), posDeco[1].second, Sprites[fmenu].Image[0]); + Sprites[deco].Affiche(580, 100 + (posDeco[2].first), posDeco[2].second, Sprites[fmenu].Image[0]); + Sprites[deco].Affiche(580, 470 - (posDeco[3].first), posDeco[3].second, Sprites[fmenu].Image[0]); + + AfficheText(340, 300, e_Sprite(T_art1 + N1), Sprites[fmenu].Image[0]); + /* + if(Ordre) { + AddBouton(0,e_Sprite(T_tart1+N1),240,492); + AddBouton(1,e_Sprite(T_tart1+N2),440,492); + } + else { + AddBouton(0,e_Sprite(T_tart1+N1),440,492); + AddBouton(1,e_Sprite(T_tart1+N2),240,492); + } + Menu_Py[0].DepY-=20; + Menu_Py[0].FinY+=20; + Menu_Py[1].DepY-=20; + Menu_Py[1].FinY+=20; + + Menu_Py[2].DepX=-1; + */ + SDL_Event event; + while (SDL_PollEvent(&event)) { + mouse.GetEvent(event, PyE); // Prend les evenements de la sourie + switch (event.type) { + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_ENTER) { + } + break; + case SDL_KEYDOWN: + if (Fini == -1 && event.key.state == SDL_PRESSED) { + Sons.Play(sClic); + switch (event.key.keysym.sym) { + case SDLK_ESCAPE: + case SDLK_AC_BACK: // Android back button + return mGame; + case SDLK_UP: + PyE--; + if (PyE < 0) + PyE = 1; + break; + case SDLK_DOWN: + PyE++; + if (PyE > 1) + PyE = 0; + break; + case SDLK_LEFT: + if (Ordre) + PyE = 0; + else + PyE = 1; + break; + case SDLK_RIGHT: + if (Ordre) + PyE = 1; + else + PyE = 0; + break; + case SDLK_F12: // Sauve un screenshot + // TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); + break; + case ' ': + case SDLK_RETURN: + case SDLK_KP_ENTER: + switch (PyE) { + case 0: + Sons.Play(sEnd); + Pref.Score += 50; + Fini = Horloge + 2000; + break; + case 1: + Sons.Play(sLose); + Fini = Horloge + 2000; + break; + } + break; + default: + break; + } + } + break; + case SDL_QUIT: + return mQuit; + break; + } + } + + // Test si fini + if (Fini != -1 && Fini < Horloge) + return mGame; + + // Gère les variables + HorlogeAvant = Horloge; + Horloge = SDL_GetTicks(); + Sleeping(); + + // Gère l'Affichage + Ec.ClearSprite(fmenu); + + if (Ordre) { + Ec.PrintSprite(fond_hrr, 0, 240, 492); + AfficheText(240, 492, e_Sprite(T_tart1 + N1)); + } + else { + Ec.PrintSprite(fond_hrr, 0, 440, 492); + AfficheText(440, 492, e_Sprite(T_tart1 + N1)); + } + + if (Fini == -1) { + if (Ordre) { + Ec.PrintSprite(fond_hrr, 0, 440, 492); + AfficheText(440, 492, e_Sprite(T_tart1 + N2)); + if (PyE == 0) + Print_Main(240); + else + Print_Main(440); + } + else { + Ec.PrintSprite(fond_hrr, 0, 240, 492); + AfficheText(240, 492, e_Sprite(T_tart1 + N2)); + if (PyE == 1) + Print_Main(240); + else + Print_Main(440); + } + mouse.Print(); + } - return mQuit; + // Echange les buffets video + SDL_RenderPresent(sdlRenderer); + + } while (true); + + return mQuit; } #endif @@ -1041,266 +1098,277 @@ eMenu Menu::SDLMain_HR(void) /*******************************/ void Menu::Print_InGame(void) { - SDL_Rect Position; - - // InitialisationsDivers - mouse.Init(Menu_Py); // Initialise la sourie - //PyE=0; - - // Prend l'image du fond et fait l'affichage - Position.x=Position.y=0; - Position.w=Sprites[fmenu].Dim[0].L; - Position.h=Sprites[fmenu].Dim[0].H; - SDL_RenderCopy(sdlRenderer,Sprites[fmenu].Image[0],&Position,&Position); - - Sprites[menu].Affiche(340,300,0,Sprites[fmenu].Image[0]); - - AfficheText(340,185,T_continue,Sprites[fmenu].Image[0]); - AddBouton(0,T_continue,340,185); - AfficheText(340,300,T_moptions,Sprites[fmenu].Image[0]); - AddBouton(1,T_moptions,340,300); - AfficheText(340,415,T_exit_game,Sprites[fmenu].Image[0]); - AddBouton(2,T_exit_game,340,415); - Menu_Py[3].DepX=-1; + SDL_Rect Position; + + // InitialisationsDivers + mouse.Init(Menu_Py); // Initialise la sourie + // PyE=0; + + // Prend l'image du fond et fait l'affichage + Position.x = Position.y = 0; + Position.w = Sprites[fmenu].Dim[0].L; + Position.h = Sprites[fmenu].Dim[0].H; + SDL_RenderCopy(sdlRenderer, Sprites[fmenu].Image[0], &Position, &Position); + + Sprites[menu].Affiche(340, 300, 0, Sprites[fmenu].Image[0]); + + AfficheText(340, 185, T_continue, Sprites[fmenu].Image[0]); + AddBouton(0, T_continue, 340, 185); + AfficheText(340, 300, T_moptions, Sprites[fmenu].Image[0]); + AddBouton(1, T_moptions, 340, 300); + AfficheText(340, 415, T_exit_game, Sprites[fmenu].Image[0]); + AddBouton(2, T_exit_game, 340, 415); + Menu_Py[3].DepX = -1; } /*** Gestion du menu dans le jeu ***/ /***********************************/ eMenu Menu::SDLMain_InGame(void) { - Print_InGame(); - - // Prend les evenements - do { - SDL_RenderClear(sdlRenderer); - SDL_Event event; - while(SDL_PollEvent(&event)) { - mouse.GetEvent(event,PyE); // Prend les evenements de la sourie - switch(event.type) { - case SDL_WINDOWEVENT: - if(event.window.event==SDL_WINDOWEVENT_ENTER) { - //SDL_RenderPresent(sdlRenderer); - //Ec.Cls(fmenu); - } - break; - case SDL_KEYDOWN: - if(event.key.state==SDL_PRESSED) { - Sons.Play(sClic); - switch(event.key.keysym.sym) { - case SDLK_ESCAPE: - case SDLK_AC_BACK: // Android back button - return mGame; - case SDLK_UP: - PyE--; - if(PyE<0) PyE=2; - break; - case SDLK_DOWN: - PyE++; - if(PyE>2) PyE=0; - break; - case SDLK_F12: // Sauve un screenshot - //TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); - break; - case ' ': - case SDLK_RETURN: - case SDLK_KP_ENTER: - switch(PyE) { - case 0: - return mGame; - case 1: - SDLMain_Options(); - PyE=1; - break; - case 2: - return mScoreEdit; - } - break; - default: - break; - } - } - break; - case SDL_QUIT: - return mQuit; - break; - } - } - - // Gère les variables - HorlogeAvant=Horloge; - Horloge=SDL_GetTicks(); - Sleeping(); - - // Gère l'Affichage - Ec.ClearSprite(fmenu); Print_InGame(); - Print_Main(340); - mouse.Print(); - - // Echange les buffets video - SDL_RenderPresent(sdlRenderer); - - } while(true); - - return mQuit; + + // Prend les evenements + do { + SDL_RenderClear(sdlRenderer); + SDL_Event event; + while (SDL_PollEvent(&event)) { + mouse.GetEvent(event, PyE); // Prend les evenements de la sourie + switch (event.type) { + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_ENTER) { + // SDL_RenderPresent(sdlRenderer); + // Ec.Cls(fmenu); + } + break; + case SDL_KEYDOWN: + if (event.key.state == SDL_PRESSED) { + Sons.Play(sClic); + switch (event.key.keysym.sym) { + case SDLK_ESCAPE: + case SDLK_AC_BACK: // Android back button + return mGame; + case SDLK_UP: + PyE--; + if (PyE < 0) + PyE = 2; + break; + case SDLK_DOWN: + PyE++; + if (PyE > 2) + PyE = 0; + break; + case SDLK_F12: // Sauve un screenshot + // TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); + break; + case ' ': + case SDLK_RETURN: + case SDLK_KP_ENTER: + switch (PyE) { + case 0: + return mGame; + case 1: + SDLMain_Options(); + PyE = 1; + break; + case 2: + return mScoreEdit; + } + break; + default: + break; + } + } + break; + case SDL_QUIT: + return mQuit; + break; + } + } + + // Gère les variables + HorlogeAvant = Horloge; + Horloge = SDL_GetTicks(); + Sleeping(); + + // Gère l'Affichage + Ec.ClearSprite(fmenu); + Print_InGame(); + Print_Main(340); + mouse.Print(); + + // Echange les buffets video + SDL_RenderPresent(sdlRenderer); + + } while (true); + + return mQuit; } /*** SDL Main Menu Choix de la difficulté ***/ /********************************************/ eMenu Menu::SDLMain_Score(bool EditScore) { - int i; - int NEdit=-1; - char Provi[256]; - int PosCur=0; - char key; - - // Cherche le numéro du score à remplacer si edition des scores - if(EditScore) { - for(i=7;i>=0;i--) if(Pref.Sco[i].ScoreNEdit;i--) { - Pref.Sco[i].Score=Pref.Sco[i-1].Score; - strcpy(Pref.Sco[i].Name,Pref.Sco[i-1].Name); - } - - // Efface le nouveau nom et met le score - Pref.Sco[NEdit].Score=Pref.Score; - Pref.Sco[NEdit].Name[0]=0; - } - - // Met la sourie sur tous l'ecran - mouse.Init(Menu_Py); // Initialise la sourie - Menu_Py[0].DepX=0; - Menu_Py[0].DepY=0; - Menu_Py[0].FinX=800; - Menu_Py[0].FinY=600; - Menu_Py[0].Py=0; - Menu_Py[0].Valide=true; - Menu_Py[1].DepX=-1; - - if(EditScore) SDL_StartTextInput(); - - // Prend les evenements - do { - // Efface le fond - Ec.CleanSpriteAndScreen(fmenu); - SDL_RenderClear(sdlRenderer); - // Prend l'image du fond et fait l'affichage - Sprites[fond_menu].Affiche(400,300,0,Sprites[fmenu].Image[0]); - - // Affiche le titre et les commandes - AfficheText(400,50,T_better_scores,Sprites[fmenu].Image[0]); - AfficheText(400,550,T_press_any_key,Sprites[fmenu].Image[0]); - - // Affiche les scores - for(i=0;i<8;i++) { - sprintf(Provi,"%u",i+1); - AfficheString(70,120+i*(360/7),Provi,Sprites[fmenu].Image[0]); - - if(EditScore==false || NEdit!=i) { - if(Pref.Sco[i].Name[0]) AfficheString(140,120+i*(360/7),Pref.Sco[i].Name,Sprites[fmenu].Image[0]); - else AfficheString(140,120+i*(360/7),Points,Sprites[fmenu].Image[0]); - } - - sprintf(Provi,"%i",Pref.Sco[i].Score); - AfficheString(740-LongueurString(Provi),120+i*(360/7),Provi,Sprites[fmenu].Image[0]); + int i; + int NEdit = -1; + char Provi[256]; + int PosCur = 0; + char key; + + // Cherche le numéro du score à remplacer si edition des scores + if (EditScore) { + for (i = 7; i >= 0; i--) + if (Pref.Sco[i].Score < Pref.Score) + NEdit = i; + if (NEdit == -1) + return mMenu; + + if (NEdit < 7) // Si doit fair un décalage + for (i = 7; i > NEdit; i--) { + Pref.Sco[i].Score = Pref.Sco[i - 1].Score; + strcpy(Pref.Sco[i].Name, Pref.Sco[i - 1].Name); + } + + // Efface le nouveau nom et met le score + Pref.Sco[NEdit].Score = Pref.Score; + Pref.Sco[NEdit].Name[0] = 0; } - - // Efface le fond - SDL_Event event; - while(SDL_PollEvent(&event)) { - mouse.GetEvent(event,PyE); // Prend les evenements de la sourie - switch(event.type) { - case SDL_WINDOWEVENT: - if(event.window.event==SDL_WINDOWEVENT_ENTER) { - SDL_RenderPresent(sdlRenderer); - } - break; - case SDL_KEYDOWN: // Prend un touche au clavier - if(event.key.state==SDL_PRESSED) { - Sons.Play(sClic); - if(EditScore==false && event.key.keysym.sym!=SDLK_F12) event.key.keysym.sym=SDLK_RETURN; - switch(event.key.keysym.sym) { - case SDLK_F12: // Sauve un screenshot - //TODO SDL_SaveBMP(sdlVideo,"screenshot.bmp"); - break; - case SDLK_ESCAPE: // Valide l'entrée - case SDLK_RETURN: - case SDLK_KP_ENTER: - if(EditScore) SDL_StopTextInput(); - return mMenu; - case SDLK_BACKSPACE: // Fait un retour de chariot - if(PosCur) { - PosCur--; - Pref.Sco[NEdit].Name[PosCur]=0; - } - break; - default: - break; - } - } - break; - case SDL_TEXTINPUT: - /* Add new text onto the end of our text */ - if(LongueurString(Pref.Sco[NEdit].Name)=tPy[i].DepX && Px<=tPy[i].FinX && Py>=tPy[i].DepY && Py<=tPy[i].FinY) - if(pPy!=tPy[i].Py) { - pPy=tPy[i].Py; - Sons.Play(sClic); - } - i++; - }; - } - break; - case SDL_MOUSEBUTTONDOWN: - if(event.button.state==SDL_PRESSED) { - Px=event.button.x; - Py=event.button.y; - - // regarde si doit valider un enter - if(tPy) { // Si bien une table - i=0; - while(tPy[i].DepX!=-1) { // Fait toutes les coordonnées - if(Px>=tPy[i].DepX && Px<=tPy[i].FinX && Py>=tPy[i].DepY && Py<=tPy[i].FinY) - if(tPy[i].Valide==true) { - event.type=SDL_KEYDOWN; - event.key.state=SDL_PRESSED; - event.key.keysym.sym=SDLK_RETURN; - } - i++; - }; - } - - // Fait la gestion des bouttons - if(Bo) { // Si bien une table - i=0; - while(Bo[i].DepX!=-1) { // Fait toutes les coordonnées - if(Px>=Bo[i].DepX && Px<=Bo[i].FinX && Py>=Bo[i].DepY && Py<=Bo[i].FinY) { - if(Bo[i].Adr==NULL) { // Si doit fair une touche - event.type=SDL_KEYDOWN; - event.key.state=SDL_PRESSED; - event.key.keysym.sym=(SDL_Keycode)Bo[i].Valeur; - } - else { // Si doit changer une variable - *(Bo[i].Adr)=Bo[i].Valeur; - } - } - i++; - }; - } - break; + int i; + + switch (event.type) { + case SDL_MOUSEMOTION: // Si mouvement de la sourie + Px = event.motion.x; + Py = event.motion.y; + // regarde si doit bouger la position de Py + if (tPy) { // Si bien une table + i = 0; + while (tPy[i].DepX != -1) { // Fait toutes les coordonnées + if (Px >= tPy[i].DepX && Px <= tPy[i].FinX && Py >= tPy[i].DepY && Py <= tPy[i].FinY) + if (pPy != tPy[i].Py) { + pPy = tPy[i].Py; + Sons.Play(sClic); + } + i++; + }; + } + break; + case SDL_MOUSEBUTTONDOWN: + if (event.button.state == SDL_PRESSED) { + Px = event.button.x; + Py = event.button.y; + + // regarde si doit valider un enter + if (tPy) { // Si bien une table + i = 0; + while (tPy[i].DepX != -1) { // Fait toutes les coordonnées + if (Px >= tPy[i].DepX && Px <= tPy[i].FinX && Py >= tPy[i].DepY && Py <= tPy[i].FinY) + if (tPy[i].Valide == true) { + event.type = SDL_KEYDOWN; + event.key.state = SDL_PRESSED; + event.key.keysym.sym = SDLK_RETURN; + } + i++; + }; + } + + // Fait la gestion des bouttons + if (Bo) { // Si bien une table + i = 0; + while (Bo[i].DepX != -1) { // Fait toutes les coordonnées + if (Px >= Bo[i].DepX && Px <= Bo[i].FinX && Py >= Bo[i].DepY && Py <= Bo[i].FinY) { + if (Bo[i].Adr == NULL) { // Si doit fair une touche + event.type = SDL_KEYDOWN; + event.key.state = SDL_PRESSED; + event.key.keysym.sym = (SDL_Keycode)Bo[i].Valeur; + } + else { // Si doit changer une variable + *(Bo[i].Adr) = Bo[i].Valeur; + } + } + i++; + }; + } + break; + } } - } - } /*** Affiche le curseur ***/ /**************************/ void Mouse::Print() { - int X=Px,Y=Py; - int NumSp=(Horloge/50)%20; - - // Corrige la position du curseur au cas ou déborde de l'écran - if(X<5) X=5; - if(X>=800-38) X=800-39; - if(Y<10) Y=10; - if(Y>=600-35) Y=600-36; - + int X = Px, Y = Py; + int NumSp = (Horloge / 50) % 20; + + // Corrige la position du curseur au cas ou déborde de l'écran + if (X < 5) + X = 5; + if (X >= 800 - 38) + X = 800 - 39; + if (Y < 10) + Y = 10; + if (Y >= 600 - 35) + Y = 600 - 36; + #ifndef ANDROID - // Affiche le curseur - Ec.PrintSprite(curseur,NumSp,X,Y); + // Affiche le curseur + Ec.PrintSprite(curseur, NumSp, X, Y); #endif } diff --git a/src/mouse.h b/src/mouse.h index 838fa22..b20b413 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -28,35 +28,38 @@ /*** Structure pour la position dans le menu Py ***/ /**************************************************/ -struct mPy { // DepX==-1 si derniere entrée - int DepX,DepY; - int FinX,FinY; - int Py; - bool Valide; // Si doit valider un enter quand click de la sourie +struct mPy +{ // DepX==-1 si derniere entrée + int DepX, DepY; + int FinX, FinY; + int Py; + bool Valide; // Si doit valider un enter quand click de la sourie }; -struct mButton { // DepX=-1 si derniere entrée - int DepX,DepY; - int FinX,FinY; - int Valeur; - int *Adr; +struct mButton +{ // DepX=-1 si derniere entrée + int DepX, DepY; + int FinX, FinY; + int Valeur; + int *Adr; }; /*** Définition de la class Tableau ***/ /**************************************/ -class Mouse { - public: - Mouse(void); - ~Mouse(void); - - void InitStart(void); // Initialise les coordonnées de la sourie - void Init(struct mPy *tPy,struct mButton *B=NULL); // Initialise la sourie - void GetEvent(SDL_Event &event,int &Py); // Prend les evenements - void Print(); // Affiche le curseur - - int Px,Py; // Position réel de la sourie - struct mPy *tPy; // Pointe sur coordonées pour Py - struct mButton *Bo; // Pointe sur les coordonnées des bouttons +class Mouse +{ +public: + Mouse(void); + ~Mouse(void); + + void InitStart(void); // Initialise les coordonnées de la sourie + void Init(struct mPy *tPy, struct mButton *B = NULL); // Initialise la sourie + void GetEvent(SDL_Event &event, int &Py); // Prend les evenements + void Print(); // Affiche le curseur + + int Px, Py; // Position réel de la sourie + struct mPy *tPy; // Pointe sur coordonées pour Py + struct mButton *Bo; // Pointe sur les coordonnées des bouttons }; #endif diff --git a/src/preference.h b/src/preference.h index d44cda0..79552ef 100644 --- a/src/preference.h +++ b/src/preference.h @@ -28,19 +28,19 @@ #define VITESSE_MAX 180.0 #define VITESSE_MOY 120.0 #define VITESSE_MIN 80.0 -#define DUREE_VITESSE (10*1000) +#define DUREE_VITESSE (10 * 1000) -#define DUREE_PAUSE (3*1000) +#define DUREE_PAUSE (3 * 1000) -#define DUREE_REDUIT (10*1000) -#define DUREE_ALONGE (10*1000) +#define DUREE_REDUIT (10 * 1000) +#define DUREE_ALONGE (10 * 1000) #define ECARTWAGON_MAX 27.0 #define ECARTWAGON_MOY 13.0 #define ECARTWAGON_MIN 4.0 #define N_VIES_DEP 3 -#define RAYON_TOUCHE (32*32) +#define RAYON_TOUCHE (32 * 32) #define LT 17 #define HT 15 @@ -66,50 +66,52 @@ /*** Difficultées possible ***/ enum e_Difficulte { - Easy, - Normal, - Hard + Easy, + Normal, + Hard }; /*** Mémorise un score ***/ #define LSCOREMAX 460 -struct sScore { - int Score; - char Name[80]; +struct sScore +{ + int Score; + char Name[80]; }; /*** Structure des preferences Générales ***/ -struct sPreference { - e_Difficulte Difficulte; // Difficulté de la partie (Vitesse) - int Niveau; // Niveau du joueur - int NVie; // Nombre de vie du joueur - int Score; // Score du joueur - double Vitesse; // Vitesse suivant le niveau - double VitesseMoy; // Vitesse en cours de la loco - float EcartWagon; // ecart en pixels entre 2 wagons - int NiveauMax; - int FullScreen; - int Langue; // Langue à afficher - int NLangues; // Nombre de langues disponible - float Volume; // Volumes audio - float VolumeM; // Volume de la music - struct sScore Sco[8]; // Mémorise les scores +struct sPreference +{ + e_Difficulte Difficulte; // Difficulté de la partie (Vitesse) + int Niveau; // Niveau du joueur + int NVie; // Nombre de vie du joueur + int Score; // Score du joueur + double Vitesse; // Vitesse suivant le niveau + double VitesseMoy; // Vitesse en cours de la loco + float EcartWagon; // ecart en pixels entre 2 wagons + int NiveauMax; + int FullScreen; + int Langue; // Langue à afficher + int NLangues; // Nombre de langues disponible + float Volume; // Volumes audio + float VolumeM; // Volume de la music + struct sScore Sco[8]; // Mémorise les scores }; /*** Valeur retournées pour le menu princiaple ***/ enum eMenu { - mMenu, - mMenuJeux, - mMenuSpeed, - mMenuNiveau, - mLangue, - mGame, - mScore, - mScoreEdit, - mOption, - mQuit, - mEdit, + mMenu, + mMenuJeux, + mMenuSpeed, + mMenuNiveau, + mLangue, + mGame, + mScore, + mScoreEdit, + mOption, + mQuit, + mEdit, }; #endif diff --git a/src/screen.cc b/src/screen.cc index f82c6e8..10c6bdd 100644 --- a/src/screen.cc +++ b/src/screen.cc @@ -1,5 +1,5 @@ // (_||_/ -// ( ) +// ( ) // ( o 0 ) //-OOO°--(_)---°OOO--------------------------------------- // Copyright (C) 2006 By Dominique Roux-Serret @@ -31,86 +31,90 @@ extern Sprite *Sprites; /*** Constructeur ***/ /********************/ -Screen::Screen(void) : N(0), Score(-1) -{ } +Screen::Screen(void) : + N(0), Score(-1) +{ +} Screen::~Screen(void) -{ } +{ +} /*** Affiche un Sprite ***/ /*************************/ -void Screen::PrintSprite(e_Sprite NumSpr,int Num,int x,int y) +void Screen::PrintSprite(e_Sprite NumSpr, int Num, int x, int y) { - B[N].NumSpr=NumSpr; - B[N].Num=Num; - B[N].x=x; - B[N].y=y; - N++; + B[N].NumSpr = NumSpr; + B[N].Num = Num; + B[N].x = x; + B[N].y = y; + N++; - Sprites[NumSpr].Affiche(x,y,Num); + Sprites[NumSpr].Affiche(x, y, Num); } /*** Affiche un cable ***/ /************************/ -void Screen::PrintCable(int dx,int dy,int fx,int fy) +void Screen::PrintCable(int dx, int dy, int fx, int fy) { - // Affiche la corde - Sprites[corde].AfficheCorde(dx,dy,fx,fy); - - // Sauve la position du cable pour l'effacer - B[N].NumSpr=corde; - B[N].Num=0; - B[N].x=dx; - B[N].y=dy; - B[N].fx=fx; - B[N].fy=fy; - N++; + // Affiche la corde + Sprites[corde].AfficheCorde(dx, dy, fx, fy); + + // Sauve la position du cable pour l'effacer + B[N].NumSpr = corde; + B[N].Num = 0; + B[N].x = dx; + B[N].y = dy; + B[N].fx = fx; + B[N].fy = fy; + N++; } /*** Affiche un text ***/ /***********************/ -void Screen::PrintText(e_Sprite Text,int x,int y) +void Screen::PrintText(e_Sprite Text, int x, int y) { - B[N].NumSpr=Text; - B[N].Num=0; - B[N].x=x; - B[N].y=y; - N++; + B[N].NumSpr = Text; + B[N].Num = 0; + B[N].x = x; + B[N].y = y; + N++; - Sprites[Text].Affiche(x,y,0); + Sprites[Text].Affiche(x, y, 0); } /*** Affiche les options du jeu ***/ /**********************************/ -void Screen::PrintOptions(int NV,int NScore) +void Screen::PrintOptions(int NV, int NScore) { - int x,y; - - Score=NScore; - AfficheChiffre(740,215,Score); - - if(NV>10) NV=10; // Evite un dépassement de l'affichage - for(int i = 0; i < NV; ++i) { // Affiche les vies - x=i%2; - x=x*44+38+LT*D_Case; - y=i/2; - y=384+y*46; - Sprites[logo_vie].Affiche(x,y,0); - } + int x, y; + + Score = NScore; + AfficheChiffre(740, 215, Score); + + if (NV > 10) + NV = 10; // Evite un dépassement de l'affichage + for (int i = 0; i < NV; ++i) { // Affiche les vies + x = i % 2; + x = x * 44 + 38 + LT * D_Case; + y = i / 2; + y = 384 + y * 46; + Sprites[logo_vie].Affiche(x, y, 0); + } } /*** Efface les sprites ***/ /**************************/ void Screen::ClearSprite(e_Sprite NumSp) { - N=0; + N = 0; } /*** Efface l'ecran avec l'image de fond ***/ /*******************************************/ void Screen::CleanSpriteAndScreen(e_Sprite NumSp) { - Sprites[NumSp].Affiche(Sprites[NumSp].Dim[0].L/2,Sprites[NumSp].Dim[0].H/2,0); - N=0; - Score=-1; + Sprites[NumSp].Affiche(Sprites[NumSp].Dim[0].L / 2, Sprites[NumSp].Dim[0].H / 2, 0); + N = 0; + Score = -1; } diff --git a/src/screen.h b/src/screen.h index b5c1169..dccbf2a 100644 --- a/src/screen.h +++ b/src/screen.h @@ -29,33 +29,34 @@ /*** Définitions générales ***/ /*****************************/ -struct s_Screen { - e_Sprite NumSpr; - int Num; - int x,y; - int fx,fy; +struct s_Screen +{ + e_Sprite NumSpr; + int Num; + int x, y; + int fx, fy; }; /*** Definitions de la class Ecran ***/ /*************************************/ class Screen { - public: - Screen(void); - ~Screen(void); - - /*** Fonctions ***/ - void PrintSprite(e_Sprite NumSpr,int Num,int x,int y); // Affiche un sprite - void PrintCable(int dx,int dy,int fx,int fy); // Affiche un cable - void PrintText(e_Sprite Text,int x,int y); // Affiche un text à l'ecran - void PrintOptions(int NVies,int NouveauScore); // Affiche les options sur le coté - void ClearSprite(e_Sprite NumSpriteFondEcran); // Efface tous ce qui a été affiché - void CleanSpriteAndScreen(e_Sprite NumSpriteFondEcran); // Efface l'ecran avec l'image de fond - - /*** Variables ***/ - int N; // Nombre de sprites mémorisés aprés l'affichage - int Score; // Mémorise le score affiché - s_Screen B[LT*HT*2]; // N° des sprites à effacer plus tard +public: + Screen(void); + ~Screen(void); + + /*** Fonctions ***/ + void PrintSprite(e_Sprite NumSpr, int Num, int x, int y); // Affiche un sprite + void PrintCable(int dx, int dy, int fx, int fy); // Affiche un cable + void PrintText(e_Sprite Text, int x, int y); // Affiche un text à l'ecran + void PrintOptions(int NVies, int NouveauScore); // Affiche les options sur le coté + void ClearSprite(e_Sprite NumSpriteFondEcran); // Efface tous ce qui a été affiché + void CleanSpriteAndScreen(e_Sprite NumSpriteFondEcran); // Efface l'ecran avec l'image de fond + + /*** Variables ***/ + int N; // Nombre de sprites mémorisés aprés l'affichage + int Score; // Mémorise le score affiché + s_Screen B[LT * HT * 2]; // N° des sprites à effacer plus tard }; #endif diff --git a/src/sprite.cc b/src/sprite.cc index 363c680..ab4edb9 100644 --- a/src/sprite.cc +++ b/src/sprite.cc @@ -1,5 +1,5 @@ // (_||_/ -// ( ) +// ( ) // ( o 0 ) //-OOO°--(_)---°OOO--------------------------------------- // Copyright (C) 2006 By Dominique Roux-Serret @@ -31,18 +31,18 @@ /*** Variables Globales ***/ /**************************/ extern SDL_Renderer *sdlRenderer; -//extern SDL_Surface *sdlVideo; +// extern SDL_Surface *sdlVideo; extern Sprite *Sprites; extern int NSprites; extern sPreference Pref; -static const char* OrdreTexte="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-!?*+<>%$()&;"; -static const char* OrdreTexte2="abcdefghijklmnopqrstuvwxyz0123456789,_|?*+<>%$[]&;"; -static int TableTexte[256]; +static const char *OrdreTexte = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-!?*+<>%$()&;"; +static const char *OrdreTexte2 = "abcdefghijklmnopqrstuvwxyz0123456789,_|?*+<>%$[]&;"; +static int TableTexte[256]; char Langue[31][16]; // Mémorise les noms des langues -int NTextes=0; -bool AfficheC=false; // Si peut afficher le chargeur lors du chargement +int NTextes = 0; +bool AfficheC = false; // Si peut afficher le chargeur lors du chargement #define N_SPRITESFOND 2 @@ -50,428 +50,447 @@ bool AfficheC=false; // Si peut afficher le chargeur lors du chargement /**********************************************/ void AfficheChargeur() { - static int NumAf=-1; // Numéro su sprite affiché - int i,Old; - int Hor; - - if(AfficheC==true) { - Hor=SDL_GetTicks(); - i=(Hor/(1000/25))%Sprites[chargeur].N; // Calcule le numéro su sprite à afficher - - if(i!=NumAf) { - Old=NumAf; - NumAf=i; - Sprites[chargeur].Affiche(400,300,NumAf); - SDL_RenderPresent(sdlRenderer); - //TODO if(Old!=-1) Sprites[chargeur].Efface(400,300,Old,sdlVideo); + static int NumAf = -1; // Numéro su sprite affiché + int i, Old; + int Hor; + + if (AfficheC == true) { + Hor = SDL_GetTicks(); + i = (Hor / (1000 / 25)) % Sprites[chargeur].N; // Calcule le numéro su sprite à afficher + + if (i != NumAf) { + Old = NumAf; + NumAf = i; + Sprites[chargeur].Affiche(400, 300, NumAf); + SDL_RenderPresent(sdlRenderer); + // TODO if(Old!=-1) Sprites[chargeur].Efface(400,300,Old,sdlVideo); + } } - } - } /*** Charge les Sprites d'une langue ***/ /***************************************/ bool LoadLangue() { - long L,P; - int i; - unsigned char *Buf; - char PathFile[512]; - - strcpy(PathFile,Langue[Pref.Langue]); - Utils::GetPath(PathFile); - if(Utils::FileExists(PathFile)==false) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find '%s'", Langue[Pref.Langue]); - return false; - } - L=Utils::LoadFile(PathFile,Buf); - - // Lit les sprites - P=0; - for(i=0;ipixels; - - if(pul[0]==0) { // Processeur type Power PC, 68000, .. - for(j=0;jpixels; + + if (pul[0] == 0) { // Processeur type Power PC, 68000, .. + for (j = 0; j < Dim[i].L * Dim[i].H * Dim[i].bpp; j += Dim[i].bpp) { + if (Dim[i].bpp == 4) + B[j + 3] = Buf[P++]; + B[j + 2] = Buf[P++]; + B[j + 1] = Buf[P++]; + B[j] = Buf[P++]; + } + } + else + for (j = 0; j < Dim[i].L * Dim[i].H * Dim[i].bpp; j++) + B[j] = Buf[P++]; + + SDL_UnlockSurface(surface); + Image[i] = SDL_CreateTextureFromSurface(sdlRenderer, surface); + SDL_FreeSurface(surface); } - else - for(j=0;jpixels; - - lx=lx/(float)n; - ly=ly/(float)n; - - for(i=0;i<=n;i++) { - P=((int)(x)+(int)(y)*800)*sdlVideo->format->BytesPerPixel; - for(j=0;jformat->BytesPerPixel;j++) B[P+j]=255; - x+=lx; - y+=ly; - } - - SDL_UnlockSurface(sdlVideo);*/ + float d; + float lx = float(fx - dx); + float ly = float(fy - dy); + int P, n, i, j; + unsigned char *B; + float x = dx; + float y = dy; + + d = sqrt(lx * lx + ly * ly); // Longueur de la corde + if ((float)((int)(d)) != d) + n = (int)(d) + 1; // Met en nombre de point + else + n = (int)d; + + // Trace la ligne + /*TODO SDL_LockSurface(sdlVideo); + B=(unsigned char*)sdlVideo->pixels; + + lx=lx/(float)n; + ly=ly/(float)n; + + for(i=0;i<=n;i++) { + P=((int)(x)+(int)(y)*800)*sdlVideo->format->BytesPerPixel; + for(j=0;jformat->BytesPerPixel;j++) B[P+j]=255; + x+=lx; + y+=ly; + } + + SDL_UnlockSurface(sdlVideo);*/ } /*** Efface le sprite ***/ /************************/ -void Sprite::Efface(int X,int Y,int NumSpr,SDL_Texture *Fond) +void Sprite::Efface(int X, int Y, int NumSpr, SDL_Texture *Fond) { - SDL_Rect Position; - - Position.w=Dim[NumSpr].L; - Position.h=Dim[NumSpr].H; - Position.x=X-Dim[NumSpr].cx; - Position.y=Y-Dim[NumSpr].cy; - //SDL_RenderCopy(sdlRenderer, Image[NumSpr],NULL, &Position); - //TODO SDL_BlitSurface(Fond,&Position,sdlVideo,&Position); + SDL_Rect Position; + + Position.w = Dim[NumSpr].L; + Position.h = Dim[NumSpr].H; + Position.x = X - Dim[NumSpr].cx; + Position.y = Y - Dim[NumSpr].cy; + // SDL_RenderCopy(sdlRenderer, Image[NumSpr],NULL, &Position); + // TODO SDL_BlitSurface(Fond,&Position,sdlVideo,&Position); } /*** Alloue un nouveau sprite vide ***/ /*************************************/ -bool Sprite::Nouveau(int Lx,int Ly) +bool Sprite::Nouveau(int Lx, int Ly) { - Delete(); // Efface au cas ou - - N=1; - Dim=new s_Dim[N]; - Image=new SDL_Texture* [N]; - - Dim[0].L=Lx; - Dim[0].H=Ly; - Dim[0].cx=Lx/2; - Dim[0].cy=Ly/2; - Dim[0].bpp=3; // Pas de transparence - - // Fabrique la surface - SDL_Surface *surface = SDL_CreateRGBSurface(0,Dim[0].L,Dim[0].H,Dim[0].bpp*8, - 0xff,0xff00,0xff0000,0xff000000*(Dim[0].bpp-3)); - if(surface==NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the SDL Surface"); - return false; - } - Image[0] = SDL_CreateTextureFromSurface(sdlRenderer, surface); - SDL_FreeSurface(surface); - return true; + Delete(); // Efface au cas ou + + N = 1; + Dim = new s_Dim[N]; + Image = new SDL_Texture *[N]; + + Dim[0].L = Lx; + Dim[0].H = Ly; + Dim[0].cx = Lx / 2; + Dim[0].cy = Ly / 2; + Dim[0].bpp = 3; // Pas de transparence + + // Fabrique la surface + SDL_Surface *surface = SDL_CreateRGBSurface(0, Dim[0].L, Dim[0].H, Dim[0].bpp * 8, + 0xff, 0xff00, 0xff0000, 0xff000000 * (Dim[0].bpp - 3)); + if (surface == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the SDL Surface"); + return false; + } + Image[0] = SDL_CreateTextureFromSurface(sdlRenderer, surface); + SDL_FreeSurface(surface); + return true; } /*** Efface le sprite ***/ /************************/ void Sprite::Delete(void) { - if(N) { - for(int i=0;i1024) { - AfficheChargeur(); - if( SDL_RWread(file,Po,1,1024) != 1024 ) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error while reading '%s'", Path); - SDL_RWclose(file); - delete [] Buf; - return -1; + SDL_RWops *file = SDL_RWFromFile(Path, "rb"); + if (!file) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to open '%s'", Path); + return -1; } - Compt-=1024; - Po+=1024; - } - - if(Compt) { // Ne fait pas le test à cause d'un bug dans windows - SDL_RWread(file,Po,1,(unsigned int)Compt); - } - - SDL_RWclose(file); - return L; + + if (SDL_RWseek(file, 0, RW_SEEK_END) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to compute file size"); + return -1; + } + + long L = SDL_RWtell(file); // récupère la longueur + SDL_RWseek(file, 0, RW_SEEK_SET); + + Buf = new unsigned char[L + 1]; + if (Buf == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Not enough memory"); + SDL_RWclose(file); + return -1; + } + + long Compt = L; + unsigned char *Po = Buf; + + while (Compt > 1024) { + AfficheChargeur(); + if (SDL_RWread(file, Po, 1, 1024) != 1024) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error while reading '%s'", Path); + SDL_RWclose(file); + delete[] Buf; + return -1; + } + Compt -= 1024; + Po += 1024; + } + + if (Compt) { // Ne fait pas le test à cause d'un bug dans windows + SDL_RWread(file, Po, 1, (unsigned int)Compt); + } + + SDL_RWclose(file); + return L; } /*** Sauve un Fichier ***/ /************************/ -bool Utils::SaveFile(const char *Path,char *Buf,long L) +bool Utils::SaveFile(const char *Path, char *Buf, long L) { - FILE *file; - - file=fopen(Path,"w"); - if(!file) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to open '%s'", Path); - return false; - } - - while(L>512) { - if( fwrite(Buf,1,512,file) != 512 ) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to write in '%s'", Path); - fclose(file); - return false; + FILE *file; + + file = fopen(Path, "w"); + if (!file) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to open '%s'", Path); + return false; } - L-=512; - Buf+=512; - } - - if(L>0) { - if( fwrite(Buf,1,(size_t)L,file) != (size_t)L ) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to write in '%s'", Path); - fclose(file); - return false; + + while (L > 512) { + if (fwrite(Buf, 1, 512, file) != 512) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to write in '%s'", Path); + fclose(file); + return false; + } + L -= 512; + Buf += 512; } - } - - fclose(file); - return true; + + if (L > 0) { + if (fwrite(Buf, 1, (size_t)L, file) != (size_t)L) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to write in '%s'", Path); + fclose(file); + return false; + } + } + + fclose(file); + return true; } /*** Met le bon chemin pour charger un fichier ***/ @@ -151,33 +150,40 @@ bool Utils::SaveFile(const char *Path,char *Buf,long L) // Version Linux void Utils::GetPath(char *Path) { - char Provi[512]; + char Provi[512]; - strcpy(Provi,Path); + strcpy(Provi, Path); #ifndef ANDROID - if(DefPath[0]) { - sprintf(Path,"%s%s",DefPath,Provi); - if(Utils::FileExists(Path)) return; - } - sprintf(Path,"%s/%s",DATA_DIR,Provi); - if(Utils::FileExists(Path)) return; + if (DefPath[0]) { + sprintf(Path, "%s%s", DefPath, Provi); + if (Utils::FileExists(Path)) + return; + } + sprintf(Path, "%s/%s", DATA_DIR, Provi); + if (Utils::FileExists(Path)) + return; #endif - // Android is directly the filename - sprintf(Path,"%s",Provi); - if(Utils::FileExists(Path)) return; - - sprintf(Path,"./%s",Provi); - if(Utils::FileExists(Path)) return; - sprintf(Path,"/usr/local/share/Li-ri/%s",Provi); - if(Utils::FileExists(Path)) return; - sprintf(Path,"/usr/share/Li-ri/%s",Provi); - if(Utils::FileExists(Path)) return; - sprintf(Path,"/usr/share/games/Li-ri/%s",Provi); - if(Utils::FileExists(Path)) return; - - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find '%s'", Provi); + // Android is directly the filename + sprintf(Path, "%s", Provi); + if (Utils::FileExists(Path)) + return; + + sprintf(Path, "./%s", Provi); + if (Utils::FileExists(Path)) + return; + sprintf(Path, "/usr/local/share/Li-ri/%s", Provi); + if (Utils::FileExists(Path)) + return; + sprintf(Path, "/usr/share/Li-ri/%s", Provi); + if (Utils::FileExists(Path)) + return; + sprintf(Path, "/usr/share/games/Li-ri/%s", Provi); + if (Utils::FileExists(Path)) + return; + + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find '%s'", Provi); } #endif @@ -185,15 +191,16 @@ void Utils::GetPath(char *Path) // Version AmigaOS4 void Utils::GetPath(char *Path) { - char Provi[512]; + char Provi[512]; - strcpy(Provi,Path); + strcpy(Provi, Path); - sprintf(Path,"PROGDIR:%s",Provi); - if(Utils::FileExists(Path)) return; - - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find '%s'", Path); - exit(-1); + sprintf(Path, "PROGDIR:%s", Provi); + if (Utils::FileExists(Path)) + return; + + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find '%s'", Path); + exit(-1); } #endif @@ -201,15 +208,16 @@ void Utils::GetPath(char *Path) // Version Mac OSX void Utils::GetPath(char *Path) { - char Provi[512]; + char Provi[512]; + + strcpy(Provi, Path); - strcpy(Provi,Path); + sprintf(Path, "Li-ri.app/Contents/Resources/%s", Provi); + if (Utils::FileExists(Path)) + return; - sprintf(Path,"Li-ri.app/Contents/Resources/%s",Provi); - if(Utils::FileExists(Path)) return; - - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find '%s'", Path); - exit(-1); + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find '%s'", Path); + exit(-1); } #endif @@ -217,16 +225,16 @@ void Utils::GetPath(char *Path) // Version Windows , chemin directe void Utils::GetPath(char *Path) { - char Provi[512]; - - strcpy(Provi,Path); - char *basePath = SDL_GetBasePath(); - sprintf(Path,"%s/%s",basePath,Provi); - if(Utils::FileExists(Path)) { - SDL_free(basePath); - return; - } - SDL_free(basePath); + char Provi[512]; + + strcpy(Provi, Path); + char *basePath = SDL_GetBasePath(); + sprintf(Path, "%s/%s", basePath, Provi); + if (Utils::FileExists(Path)) { + SDL_free(basePath); + return; + } + SDL_free(basePath); } #endif @@ -234,36 +242,35 @@ void Utils::GetPath(char *Path) /******************************/ bool Utils::LoadPref(void) { - int L; - unsigned char *Provi; - - char PathPref[512]; - char *PrefFolder = SDL_GetPrefPath("Li-Ri", "Li-Ri"); - sprintf(PathPref, "%sli-ri.pref", PrefFolder); - - SDL_free(PrefFolder); - - if(Utils::FileExists(PathPref)) { - L=Utils::LoadFile(PathPref,Provi); - if(L>0) { - memcpy((char*)&Pref,Provi,L); - delete [] Provi; - return true; + int L; + unsigned char *Provi; + + char PathPref[512]; + char *PrefFolder = SDL_GetPrefPath("Li-Ri", "Li-Ri"); + sprintf(PathPref, "%sli-ri.pref", PrefFolder); + + SDL_free(PrefFolder); + + if (Utils::FileExists(PathPref)) { + L = Utils::LoadFile(PathPref, Provi); + if (L > 0) { + memcpy((char *)&Pref, Provi, L); + delete[] Provi; + return true; + } } - } - - return false; + + return false; } /*** Sauve les preferences ***/ /*****************************/ void Utils::SauvePref(void) -{ - char PathPref[512]; - char *PrefFolder = SDL_GetPrefPath("Li-Ri", "Li-Ri"); - sprintf(PathPref, "%sli-ri.pref", PrefFolder); +{ + char PathPref[512]; + char *PrefFolder = SDL_GetPrefPath("Li-Ri", "Li-Ri"); + sprintf(PathPref, "%sli-ri.pref", PrefFolder); - SDL_free(PrefFolder); - Utils::SaveFile(PathPref,(char*)&Pref,sizeof(sPreference)); + SDL_free(PrefFolder); + Utils::SaveFile(PathPref, (char *)&Pref, sizeof(sPreference)); } - diff --git a/src/utils.h b/src/utils.h index 7e57901..c85fe67 100644 --- a/src/utils.h +++ b/src/utils.h @@ -24,11 +24,12 @@ #ifndef _UTILS_DOM_ #define _UTILS_DOM_ -class Utils { - public: - static bool FileExists(const char *Path); // Check if the file exists - static long LoadFile(const char *Path,unsigned char *&Buf); // Load a file in memory - static bool SaveFile(const char *Path,char *Buf,long L); // Save a file +class Utils +{ +public: + static bool FileExists(const char *Path); // Check if the file exists + static long LoadFile(const char *Path, unsigned char *&Buf); // Load a file in memory + static bool SaveFile(const char *Path, char *Buf, long L); // Save a file static void GetPath(char *Name); // Add the path to the filename depending on the OS (sprites, levels) From e50a7adb8774bfd5434e32adb8bfa110d5b9f79f Mon Sep 17 00:00:00 2001 From: Johnny Jazeix Date: Sun, 31 Dec 2023 15:50:55 +0100 Subject: [PATCH 3/3] workflow for clang-format --- .github/workflows/clang-format.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/clang-format.yml diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 0000000..4c82551 --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,13 @@ +name: clang-format Check +on: [push, pull_request] +jobs: + formatting-check: + name: Formatting Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Run clang-format style check for C/C++/Protobuf programs. + uses: jidicula/clang-format-action@v4.11.0 + with: + clang-format-version: '16' + check-path: 'src'