diff --git a/CMakeLists.txt b/CMakeLists.txt index bdd58d6..8dc52f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,9 +25,10 @@ option(USE_CONAN if(USE_CONAN) find_package(SDL2 REQUIRED CONFIG) find_package(SDL2_mixer REQUIRED CONFIG) + find_package(SDL2_ttf REQUIRED CONFIG) else() find_package(PkgConfig REQUIRED) - pkg_check_modules(SDL2 REQUIRED sdl2 SDL2_mixer) + pkg_check_modules(SDL2 REQUIRED sdl2 SDL2_mixer SDL2_ttf) endif() set(CMAKE_CXX_STANDARD 11) @@ -80,7 +81,7 @@ if(LINUX) endif() if(USE_CONAN) - target_link_libraries(${LIRI_EXECUTABLE_NAME} PRIVATE SDL2::SDL2 SDL2_mixer::SDL2_mixer) + target_link_libraries(${LIRI_EXECUTABLE_NAME} PRIVATE SDL2::SDL2 SDL2_mixer::SDL2_mixer SDL2_ttf::SDL2_ttf) else() target_include_directories(${LIRI_EXECUTABLE_NAME} PUBLIC ${SDL2_INCLUDE_DIRS}) target_link_libraries(${LIRI_EXECUTABLE_NAME} PRIVATE ${SDL2_LINK_LIBRARIES}) diff --git a/README.md b/README.md index 8e9384d..50bf91e 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Johnny Jazeix: port to SDL2 + android + cmake Copyright (c) 2006 Dominique Roux-Serret: design & programming & graphics & website. Maf464: musics +Also ingame using Comic neue font: https://github.com/crozynski/comicneue [Get it on F-Droid // for SDL_GetTicks #include // for SDL_WINDOWEVENT_ENTER #include +#include #include "editor.h" #include "menu.h" @@ -35,12 +36,14 @@ #include "level.h" #include "gamepad.h" #include "mouse.h" +#include "screen.h" /*** Variables globales ***/ /**************************/ extern SDL_Renderer *sdlRenderer; extern Sprite *Sprites; +extern Screen *Ec; extern sNewPreference Pref; extern int currentTime; @@ -251,7 +254,7 @@ void Editor::Draw() const } // Affiche numero du niveau - DrawNumber(740, 130, NumN + 1); + Ec->PrintText(std::to_string(NumN + 1), 740, 130); // Affiche les options for (i = 0; i < LT * HT; i++) { diff --git a/src/game.cc b/src/game.cc index 6f17fea..71d77ed 100644 --- a/src/game.cc +++ b/src/game.cc @@ -47,7 +47,7 @@ extern sNewPreference Pref; extern int currentTime; extern int previousTime; -extern Screen Ec; +extern Screen *Ec; extern Level level; @@ -76,7 +76,7 @@ eMenu Game::SDLMain() Help = true; Load(NumN); // Charge le tableau SDL_RenderPresent(sdlRenderer); - Ec.CleanSpriteAndScreen(fjeu); + Ec->CleanSpriteAndScreen(fjeu); Pause = true; currentTime = SDL_GetTicks(); // Prend l'horloge @@ -369,12 +369,14 @@ bool Game::DrawLevel(int NivN) #endif // Affiche les textes suivant la langue - DrawText(740, 110, T_level, Sprites[fjeu].Image[0]); - DrawText(740, 180, T_score, Sprites[fjeu].Image[0]); - DrawText(740, 260, T_options, Sprites[fjeu].Image[0]); - DrawText(740, 340, T_lives, Sprites[fjeu].Image[0]); + Ec->ChangeFontColor(255, 255, 0); + Ec->PrintText("Level", 740-Ec->TextLength("Level")/2, 110); + Ec->PrintText("Score", 740-Ec->TextLength("Score")/2, 180); + Ec->PrintText("Conf.", 740-Ec->TextLength("Conf.")/2, 260); + Ec->PrintText("Lives", 740-Ec->TextLength("Lives")/2, 340); + Ec->ChangeFontColor(255, 255, 255); - DrawNumber(740, 140, Pref.Level + 1, Sprites[fjeu].Image[0]); + Ec->PrintText(std::to_string(Pref.Level + 1), 740 - Ec->TextLength(std::to_string(Pref.Level + 1))/2, 140); return true; } @@ -533,44 +535,44 @@ void Game::AfficheEcran() 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; i < LT * HT; i++) { switch (T[i]) { case C_Wagon: // Si un loco - Ec.PrintSprite(wagon, (DureeJeu * 40 / 1000 + i * 7) % 50, i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2); + Ec->PrintSprite(wagon, (DureeJeu * 40 / 1000 + i * 7) % 50, i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2); break; case C_Allonge: // Si plus long - Ec.PrintSprite(pluslong, (DureeJeu * 40 / 1000 + i * 7) % 50, i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2); + Ec->PrintSprite(pluslong, (DureeJeu * 40 / 1000 + i * 7) % 50, i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2); break; case C_Reduit: // Si plus court - Ec.PrintSprite(pluscourt, (DureeJeu * 40 / 1000 + i * 7) % 50, i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2); + Ec->PrintSprite(pluscourt, (DureeJeu * 40 / 1000 + i * 7) % 50, i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2); break; case C_Speed: // Si plus vite - Ec.PrintSprite(speed, (DureeJeu * 40 / 1000 + i * 7) % 50, i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2); + Ec->PrintSprite(speed, (DureeJeu * 40 / 1000 + i * 7) % 50, i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2); break; case C_Live: // Si une vie - Ec.PrintSprite(life, (DureeJeu * 40 / 1000 + i * 7) % 50, i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2); + Ec->PrintSprite(life, (DureeJeu * 40 / 1000 + i * 7) % 50, i % LT * D_Case + D_Case / 2, i / LT * D_Case + D_Case / 2); break; } } // Si en pose demande une touche if (Pause) { - Ec.PrintText(T_press_any_key, LT * D_Case / 2, 300); + Ec->PrintText("Press any key", LT * D_Case / 2, 300); } // Affiche tableau de bord - Ec.PrintOptions(Pref.Lives, Pref.Score); + Ec->PrintOptions(Pref.Lives, Pref.Score); if (Pref.WagonGap < WAGON_GAP_MIN) { - Ec.PrintSprite(pluscourt, (DureeJeu * 40 / 1000) % 50, 715, 295); + Ec->PrintSprite(pluscourt, (DureeJeu * 40 / 1000) % 50, 715, 295); } if (Pref.WagonGap > WAGON_GAP_AVERAGE) { - Ec.PrintSprite(pluslong, (DureeJeu * 40 / 1000) % 50, 715, 295); + Ec->PrintSprite(pluslong, (DureeJeu * 40 / 1000) % 50, 715, 295); } if (Pref.SpeedAverage > Pref.Speed) { - Ec.PrintSprite(speed, (DureeJeu * 40 / 1000 + 7) % 50, 765, 295); + Ec->PrintSprite(speed, (DureeJeu * 40 / 1000 + 7) % 50, 765, 295); } } diff --git a/src/loco.cc b/src/loco.cc index db30b66..ce372fd 100644 --- a/src/loco.cc +++ b/src/loco.cc @@ -115,7 +115,7 @@ void Loco::Init(int Pos, int Direction) /*** Affiche la locomotive ***/ /*****************************/ -void Loco::Display(Screen &Ec) +void Loco::Display(Screen *Ec) { float ltrain = 0; float p1, p2, a, ar, vx, vy; @@ -190,7 +190,7 @@ void Loco::Display(Screen &Ec) cdy = y1 - (int)(cos(ar) * lv); // Affiche le cable - Ec.PrintCable(cdx, cdy, cfx, cfy); + Ec->PrintCable(cdx, cdy, cfx, cfy); } // Calcule le crocher de fin pour le prochaine wagon cfx = x1 - (int)(sin(ar + M_PI) * lv); @@ -218,13 +218,13 @@ void Loco::Display(Screen &Ec) ns += 160; } - Ec.PrintSprite(Wagon[i], ns, x1, y1); + 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(new_wagon, (int)(PosWagon[i].SprStart), x1, y1); + Ec->PrintSprite(new_wagon, (int)(PosWagon[i].SprStart), x1, y1); } } diff --git a/src/loco.h b/src/loco.h index 302a78e..8a2aefb 100644 --- a/src/loco.h +++ b/src/loco.h @@ -56,7 +56,7 @@ class Loco /*** Fonctions ***/ void Init(int Pos, int Direction); // Initialise la loco sur le tableau - void Display(Screen &Ec); // Fait l'affichage de la loco. + void Display(Screen *Ec); // Fait l'affichage de la loco. void TestCase(float Dist, 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 diff --git a/src/main.cc b/src/main.cc index 054bc14..cd61b77 100644 --- a/src/main.cc +++ b/src/main.cc @@ -32,6 +32,7 @@ #include // for SDL_CreateWindow, SDL_DestroyWindow #include #include +#include #include "config.h" #include "preference.h" @@ -55,7 +56,7 @@ char Titre[] = "Li-ri V" VERSION; Sprite *Sprites = nullptr; // Sprites pointer int NSprites = 0; // Number of sprites in memory -Screen Ec; // 2 Video buffer pointer +Screen *Ec; // 2 Video buffer pointer sNewPreference Pref; // Preference table. Level level; @@ -106,6 +107,10 @@ int main(int narg, char *argv[]) // Close the program properly when quitting atexit(SDL_Quit); + TTF_Init(); + + Ec = new Screen(); + // Set resolution int vOption = SDL_WINDOW_RESIZABLE; if (Pref.FullScreen) { @@ -201,6 +206,7 @@ int main(int narg, char *argv[]) SDL_DestroyRenderer(sdlRenderer); SDL_DestroyWindow(sdlWindow); + TTF_Quit(); Mix_Quit(); SDL_Quit(); return 0; diff --git a/src/menu.cc b/src/menu.cc index 446491c..fedb771 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include // for SDL_MIX_MAXVOLUME #include // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN @@ -56,7 +57,7 @@ extern int previousTime; extern SDL_Window *sdlWindow; extern SDL_Renderer *sdlRenderer; extern Sprite *Sprites; -extern Screen Ec; +extern Screen *Ec; extern sNewPreference Pref; static char Points[] = ". . . . . . . . . . . . . ."; @@ -75,6 +76,24 @@ void Sleeping() } } +/*** Draw button with string text ***/ +/************************************/ +void AddTextButton(int Num, std::string Text, int X, int Y) +{ + Ec->ChangeFontSize(45); + + int textWidth = Ec->TextLength(Text); + + Ec->PrintText(Text, X - textWidth / 2, Y - 22); + + Menu_Py[Num].DepX = X - textWidth / 2; + Menu_Py[Num].DepY = Y - 22; + Menu_Py[Num].FinX = X + textWidth / 2; + Menu_Py[Num].FinY = Y + 22; + Menu_Py[Num].Py = Num; + Menu_Py[Num].Valide = true; +} + /*** Ajoute une entrée dans le tableau des boutons ***/ /*****************************************************/ void AddButton(int Num, e_Sprite NumSp, int X, int Y) @@ -115,22 +134,21 @@ eMenu Menu::SDLMain() // Prend les evenements do { - Ec.CleanSpriteAndScreen(fmenu); + Ec->CleanSpriteAndScreen(fmenu); SDL_RenderClear(sdlRenderer); // Prend l'image du fond et fait l'affichage Sprites[fond_menu].Draw(400, 300, 0, Sprites[fmenu].Image[0]); Sprites[menu].Draw(400, 340, 0, Sprites[fmenu].Image[0]); Sprites[title].Draw(400, 65, 0, Sprites[fmenu].Image[0]); - Sprites[copyright].Draw(400, 587, 0, Sprites[fmenu].Image[0]); - - DrawText(400, 229, T_play, Sprites[fmenu].Image[0]); - AddButton(0, T_play, 400, 229); - DrawText(400, 306, T_scores, Sprites[fmenu].Image[0]); - AddButton(1, T_scores, 400, 306); - DrawText(400, 384, T_moptions, Sprites[fmenu].Image[0]); - AddButton(2, T_moptions, 400, 384); - DrawText(400, 461, T_quit, Sprites[fmenu].Image[0]); - AddButton(3, T_quit, 400, 461); + Ec->ChangeFontSize(14); + // Automatic year change + Ec->PrintText("G.P.L. Game - Copyright 2023-" + std::to_string(Year) + " By Johnny Jazeix (fork of Ri-Li originally written by D. Roux-Serret), Music by MAF", 0, 575); + Ec->ChangeFontSize(22); + + AddTextButton(0, "Play", 400, 229); + AddTextButton(1, "Scores", 400, 306); + AddTextButton(2, "Options", 400, 384); + AddTextButton(3, "Quit", 400, 461); Menu_Py[4].DepX = -1; SDL_Event event; while (SDL_PollEvent(&event)) { @@ -177,14 +195,12 @@ eMenu Menu::SDLMain() break; default: key = event.key.keysym.sym & 0x7F; // Prend le caracataire correspondant à la touche - if (CharExist(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 - } + 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 } } } @@ -380,8 +396,7 @@ void Menu::InitMain_Options() // Centre à gauche le text de menu CentreM = 120 + Sprites[T_menu].Dim[0].L / 2; - DrawText(CentreM, 490, T_menu, Sprites[fmenu].Image[0]); - AddButton(4, T_menu, CentreM, 490); + AddTextButton(4, "Menu", CentreM, 490); // Boutons des sounds Sprites[arrows].Draw(250, 110, 1, Sprites[fmenu].Image[0]); @@ -430,7 +445,7 @@ eMenu Menu::SDLMain_Options() PyE = 4; // Prend les evenements do { - Ec.CleanSpriteAndScreen(fmenu); + Ec->CleanSpriteAndScreen(fmenu); SDL_RenderClear(sdlRenderer); InitMain_Options(); // Prépare le menu SDL_Event event; @@ -595,42 +610,42 @@ eMenu Menu::SDLMain_Options() Sleeping(); // Gère l'Affichage - // Ec.Efface(fmenu); + // Ec->Efface(fmenu); if (Pref.FullScreen) { - Ec.PrintSprite(arrows, 1, 350, 300); - Ec.PrintSprite(arrows, 3, 450, 300); + Ec->PrintSprite(arrows, 1, 350, 300); + Ec->PrintSprite(arrows, 3, 450, 300); } else { - Ec.PrintSprite(arrows, 0, 350, 300); - Ec.PrintSprite(arrows, 4, 450, 300); + Ec->PrintSprite(arrows, 0, 350, 300); + Ec->PrintSprite(arrows, 4, 450, 300); } NumSp = (currentTime / 30) % 25; - Ec.PrintSprite(sound, NumSp, 150, 110); + Ec->PrintSprite(sound, NumSp, 150, 110); NumSp = (currentTime / 30) % 25; - Ec.PrintSprite(music, NumSp, 150, 200); + Ec->PrintSprite(music, NumSp, 150, 200); NumSp = (currentTime / 50) % 50; - Ec.PrintSprite(earth, NumSp, 180, 400); + Ec->PrintSprite(earth, NumSp, 180, 400); N = (int)(Pref.Volume * 10 + 1) / SDL_MIX_MAXVOLUME; NumSp = (currentTime / 50) % 40 + 120; for (i = 0; i < N; i++) { if (i == N - 1) { - Ec.PrintSprite(locomotive, NumSp, (690 - 300) / 10 * i + 300, 110); + Ec->PrintSprite(locomotive, NumSp, (690 - 300) / 10 * i + 300, 110); } else { - Ec.PrintSprite(logs_wagon, NumSp, (690 - 300) / 10 * i + 300, 110); + Ec->PrintSprite(logs_wagon, 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); + Ec->PrintSprite(locomotive, NumSp, (690 - 300) / 10 * i + 300, 200); } else { - Ec.PrintSprite(logs_wagon, NumSp, (690 - 300) / 10 * i + 300, 200); + Ec->PrintSprite(logs_wagon, NumSp, (690 - 300) / 10 * i + 300, 200); } } @@ -685,19 +700,16 @@ eMenu Menu::SDLMain_Speed() // Prend les evenements do { - Ec.CleanSpriteAndScreen(fmenu); + Ec->CleanSpriteAndScreen(fmenu); SDL_RenderClear(sdlRenderer); // Prend l'image du fond et fait l'affichage Sprites[fond_menu].Draw(400, 300, 0, Sprites[fmenu].Image[0]); Sprites[menu].Draw(400, 340, 0, Sprites[fmenu].Image[0]); Sprites[title].Draw(400, 65, 0, Sprites[fmenu].Image[0]); - DrawText(400, 225, T_easy, Sprites[fmenu].Image[0]); - AddButton(0, T_easy, 400, 225); - DrawText(400, 340, T_normal, Sprites[fmenu].Image[0]); - AddButton(1, T_normal, 400, 340); - DrawText(400, 455, T_hard, Sprites[fmenu].Image[0]); - AddButton(2, T_hard, 400, 455); + AddTextButton(0, "Easy", 400, 225); + AddTextButton(1, "Normal", 400, 340); + AddTextButton(2, "Hard", 400, 455); Menu_Py[3].DepX = -1; SDL_Event event; @@ -791,19 +803,16 @@ eMenu Menu::SDLMain_Level() // Prend les evenements do { // Efface le fond - Ec.CleanSpriteAndScreen(fmenu); + Ec->CleanSpriteAndScreen(fmenu); SDL_RenderClear(sdlRenderer); // Prend l'image du fond et fait l'affichage Sprites[fond_menu].Draw(400, 300, 0, Sprites[fmenu].Image[0]); Sprites[menu].Draw(400, 340, 0, Sprites[fmenu].Image[0]); Sprites[title].Draw(400, 65, 0, Sprites[fmenu].Image[0]); - DrawText(400, 225, T_new_game, Sprites[fmenu].Image[0]); - AddButton(0, T_new_game, 400, 225); - DrawText(400, 320, T_old_level, Sprites[fmenu].Image[0]); - AddButton(1, T_old_level, 400, 320); - DrawText(400, 455, T_menu, Sprites[fmenu].Image[0]); - AddButton(2, T_menu, 400, 455); + AddTextButton(0, "New game", 400, 225); + AddTextButton(1, "Old level", 400, 320); + AddTextButton(2, "Menu", 400, 455); AddButton(3, arrows, 330, 380); AddButton(4, arrows, 470, 380); @@ -899,29 +908,29 @@ eMenu Menu::SDLMain_Level() // Draw arrows if (Niv > 0) { if (PyE == 3) { - Ec.PrintSprite(arrows, 2, 330, 380); + Ec->PrintSprite(arrows, 2, 330, 380); } else { - Ec.PrintSprite(arrows, 1, 330, 380); + Ec->PrintSprite(arrows, 1, 330, 380); } } else { - Ec.PrintSprite(arrows, 0, 330, 380); + Ec->PrintSprite(arrows, 0, 330, 380); } if (Niv < Pref.LevelMax[Pref.Difficulty]) { if (PyE == 4) { - Ec.PrintSprite(arrows, 5, 470, 380); + Ec->PrintSprite(arrows, 5, 470, 380); } else { - Ec.PrintSprite(arrows, 4, 470, 380); + Ec->PrintSprite(arrows, 4, 470, 380); } } else { - Ec.PrintSprite(arrows, 3, 470, 380); + Ec->PrintSprite(arrows, 3, 470, 380); } - DrawNumber(400, 380, Niv + 1); + Ec->PrintText(std::to_string(Niv + 1), 400, 380); if (PyE != 3 && PyE != 4) { Print_Main(); @@ -972,15 +981,13 @@ eMenu Menu::SDLMain_HR() Sprites[deco].Draw(580, 100 + (rand() % 130), rand() % 18, Sprites[fmenu].Image[0]); Sprites[deco].Draw(580, 470 - (rand() % 130), rand() % 18, Sprites[fmenu].Image[0]); - DrawText(340, 300, e_Sprite(T_art1 + N1), Sprites[fmenu].Image[0]); - if (Ordre) { - AddButton(0, e_Sprite(T_tart1 + N1), 240, 492); - AddButton(1, e_Sprite(T_tart1 + N2), 440, 492); + AddTextButton(0, "Article " + std::to_string(N1), 240, 492); + AddTextButton(1, "Article " + std::to_string(N2), 440, 492); } else { - AddButton(0, e_Sprite(T_tart1 + N1), 440, 492); - AddButton(1, e_Sprite(T_tart1 + N2), 240, 492); + AddTextButton(0, "Article " + std::to_string(N1), 440, 492); + AddTextButton(1, "Article " + std::to_string(N2), 240, 492); } Menu_Py[0].DepY -= 20; Menu_Py[0].FinY += 20; @@ -1114,18 +1121,18 @@ eMenu Menu::SDLMain_HR() Sleeping(); if (Ordre) { - Ec.PrintSprite(fond_hrr, 0, 240, 492); - DrawText(240, 492, e_Sprite(T_tart1 + N1)); + Ec->PrintSprite(fond_hrr, 0, 240, 492); + Ec->PrintText(std::to_string(N1), 240, 492); } else { - Ec.PrintSprite(fond_hrr, 0, 440, 492); - DrawText(440, 492, e_Sprite(T_tart1 + N1)); + Ec->PrintSprite(fond_hrr, 0, 440, 492); + Ec->PrintText(std::to_string(N1), 440, 492); } if (Fini == -1) { if (Ordre) { - Ec.PrintSprite(fond_hrr, 0, 440, 492); - DrawText(440, 492, e_Sprite(T_tart1 + N2)); + Ec->PrintSprite(fond_hrr, 0, 440, 492); + Ec->PrintText(std::to_string(N2), 240, 492); if (PyE == 0) { Print_Main(240); } @@ -1134,8 +1141,8 @@ eMenu Menu::SDLMain_HR() } } else { - Ec.PrintSprite(fond_hrr, 0, 240, 492); - DrawText(240, 492, e_Sprite(T_tart1 + N2)); + Ec->PrintSprite(fond_hrr, 0, 240, 492); + Ec->PrintText(std::to_string(N2), 440, 492); if (PyE == 1) { Print_Main(240); } @@ -1173,12 +1180,9 @@ void Menu::Print_InGame() Sprites[menu].Draw(340, 300, 0, Sprites[fmenu].Image[0]); - DrawText(340, 185, T_continue, Sprites[fmenu].Image[0]); - AddButton(0, T_continue, 340, 185); - DrawText(340, 300, T_moptions, Sprites[fmenu].Image[0]); - AddButton(1, T_moptions, 340, 300); - DrawText(340, 415, T_exit_game, Sprites[fmenu].Image[0]); - AddButton(2, T_exit_game, 340, 415); + AddTextButton(0, "Continue", 340, 185); + AddTextButton(1, "Options", 340, 300); + AddTextButton(2, "Exit game", 340, 415); Menu_Py[3].DepX = -1; } @@ -1190,7 +1194,7 @@ eMenu Menu::SDLMain_InGame() // Prend les evenements do { - Ec.CleanSpriteAndScreen(fmenu); + Ec->CleanSpriteAndScreen(fmenu); SDL_RenderClear(sdlRenderer); SDL_Event event; while (SDL_PollEvent(&event)) { @@ -1201,7 +1205,7 @@ eMenu Menu::SDLMain_InGame() case SDL_WINDOWEVENT: if (event.window.event == SDL_WINDOWEVENT_ENTER) { // SDL_RenderPresent(sdlRenderer); - // Ec.Cls(fmenu); + // Ec->Cls(fmenu); } break; case SDL_KEYDOWN: @@ -1278,14 +1282,14 @@ 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--) { + for (i = 0; i < 8; i++) { if (Pref.Sco[i].Score < Pref.Score) { NEdit = i; + break; } } if (NEdit == -1) { @@ -1295,13 +1299,13 @@ eMenu Menu::SDLMain_Score(bool EditScore) 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); + 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; + Pref.Sco[NEdit].Name.clear(); } // Met la sourie sur tous l'ecran @@ -1321,31 +1325,37 @@ eMenu Menu::SDLMain_Score(bool EditScore) // Prend les evenements do { // Efface le fond - Ec.CleanSpriteAndScreen(fmenu); + Ec->CleanSpriteAndScreen(fmenu); SDL_RenderClear(sdlRenderer); // Prend l'image du fond et fait l'affichage Sprites[fond_menu].Draw(400, 300, 0, Sprites[fmenu].Image[0]); // Draw title and commands - DrawText(400, 50, T_better_scores, Sprites[fmenu].Image[0]); - DrawText(400, 550, T_press_any_key, Sprites[fmenu].Image[0]); + Ec->ChangeFontColor(255, 255, 0); + Ec->PrintText("Best players", 400-Ec->TextLength("Best players")/2, 50); + #ifndef ANDROID + Ec->PrintText("Press ENTER to continue", 400-Ec->TextLength("Press ENTER to continue")/2, 550); + #else + Ec->PrintText("Tap to continue", 400-Ec->TextLength("Tap to continue")/2, 550); + #endif + Ec->ChangeFontColor(255, 255, 255); // Draw scores for (i = 0; i < 8; i++) { sprintf(Provi, "%d", i + 1); - DrawString(70, 120 + i * (360 / 7), Provi, Sprites[fmenu].Image[0]); + Ec->PrintText(Provi, 70, 120 + i * (360 / 7)); if (EditScore == false || NEdit != i) { - if (Pref.Sco[i].Name[0]) { - DrawString(140, 120 + i * (360 / 7), Pref.Sco[i].Name, Sprites[fmenu].Image[0]); + if (!Pref.Sco[i].Name.empty()) { + Ec->PrintText(Pref.Sco[i].Name, 140, 120 + i * (360 / 7)); } else { - DrawString(140, 120 + i * (360 / 7), Points, Sprites[fmenu].Image[0]); + Ec->PrintText(Points, 140, 120 + i * (360 / 7)); } } sprintf(Provi, "%i", Pref.Sco[i].Score); - DrawString(740 - StringLength(Provi), 120 + i * (360 / 7), Provi, Sprites[fmenu].Image[0]); + Ec->PrintText(Provi, 740 - Ec->TextLength(std::string(Provi)), 120 + i * (360 / 7)); } // Efface le fond @@ -1362,10 +1372,10 @@ eMenu Menu::SDLMain_Score(bool EditScore) break; case SDL_KEYDOWN: // Prend un touche au clavier if (event.key.state == SDL_PRESSED) { - m_audio.Play(sClic); - if (EditScore == false && event.key.keysym.sym != SDLK_F12) { - event.key.keysym.sym = SDLK_RETURN; + if (NEdit >= 0 && event.key.keysym.sym == SDLK_BACKSPACE && !Pref.Sco[NEdit].Name.empty()) { + Pref.Sco[NEdit].Name.pop_back(); } + m_audio.Play(sClic); switch (event.key.keysym.sym) { case SDLK_F12: // Save screenshot if (event.key.repeat == 0) { @@ -1379,22 +1389,12 @@ eMenu Menu::SDLMain_Score(bool 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 (StringLength(Pref.Sco[NEdit].Name) < LSCOREMAX && PosCur < 79 && CharExist(event.text.text[0])) { - PosCur += strlen(event.text.text); - strcat(Pref.Sco[NEdit].Name, event.text.text); + if (NEdit >= 0) { + Pref.Sco[NEdit].Name += event.text.text; } break; case SDL_QUIT: @@ -1410,12 +1410,16 @@ eMenu Menu::SDLMain_Score(bool EditScore) currentTime = SDL_GetTicks(); Sleeping(); - if (EditScore) { // Handle the scores edition drawing - DrawString(140, 120 + NEdit * (360 / 7), Pref.Sco[NEdit].Name); + if (EditScore && NEdit >= 0 && NEdit < 8) { // Handle the scores edition drawing + if (!Pref.Sco[NEdit].Name.empty()) { + Ec->PrintText(Pref.Sco[NEdit].Name, 140, 120 + NEdit * (360 / 7)); + } i = (currentTime / 50) % 20; // Draw cursors - Ec.PrintSprite(arrow_left, i, 110, 120 + NEdit * (360 / 7)); - Ec.PrintSprite(arrow_right, i, 180 + StringLength(Pref.Sco[NEdit].Name), 120 + NEdit * (360 / 7)); + Ec->PrintSprite(arrow_left, i, 110, 120 + NEdit * (360 / 7)); + + int textLen = Pref.Sco[NEdit].Name.empty() ? 0 : Ec->TextLength(Pref.Sco[NEdit].Name); + Ec->PrintSprite(arrow_right, i, 180 + textLen, 120 + NEdit * (360 / 7)); } // Echange les buffets video @@ -1438,8 +1442,8 @@ void Menu::Print_Main(int Centre) const int const x2 = (Centre - x1) + Centre; int const y = (Menu_Py[PyE].FinY + Menu_Py[PyE].DepY) / 2; - Ec.PrintSprite(arrow_left, NumSp, x1, y); - Ec.PrintSprite(arrow_right, NumSp, x2, y); + Ec->PrintSprite(arrow_left, NumSp, x1, y); + Ec->PrintSprite(arrow_right, NumSp, x2, y); } /*** Centre les flèches sur le boutton ***/ @@ -1451,6 +1455,6 @@ void Menu::Affiche_Main_Centre() const int const x2 = Menu_Py[PyE].FinX + 5; int const y = (Menu_Py[PyE].FinY + Menu_Py[PyE].DepY) / 2; - Ec.PrintSprite(arrow_left, NumSp, x1, y); - Ec.PrintSprite(arrow_right, NumSp, x2, y); + Ec->PrintSprite(arrow_left, NumSp, x1, y); + Ec->PrintSprite(arrow_right, NumSp, x2, y); } diff --git a/src/menu.h b/src/menu.h index 009eb68..f297cfb 100644 --- a/src/menu.h +++ b/src/menu.h @@ -73,6 +73,10 @@ class Menu Audio &m_audio; Mouse &m_mouse; Gamepad &m_gamepad; + + char Points[28] = ". . . . . . . . . . . . . ."; + int Year = 2026; + }; #endif diff --git a/src/mouse.cc b/src/mouse.cc index c39762f..9e77b13 100644 --- a/src/mouse.cc +++ b/src/mouse.cc @@ -32,7 +32,7 @@ /*** Variables Globales ***/ /**************************/ extern int currentTime; -extern Screen Ec; +extern Screen *Ec; extern SDL_Window *sdlWindow; /*** Initialise la sourie ***/ @@ -143,6 +143,6 @@ void Mouse::Print() const #ifndef ANDROID // Affiche le curseur - Ec.PrintSprite(cursor, NumSp, X, Y); + Ec->PrintSprite(cursor, NumSp, X, Y); #endif } diff --git a/src/preference.h b/src/preference.h index b24bdef..4cf4514 100644 --- a/src/preference.h +++ b/src/preference.h @@ -25,6 +25,7 @@ #define PREFERENCE_DOM_ #include // for SDL_MIX_MAXVOLUME +#include #define SPEED_MAX 180.0 #define SPEED_AVERAGE 120.0 @@ -77,7 +78,7 @@ enum e_Difficulty { struct sScore { int Score; - char Name[80]; + std::string Name; }; /*** Preferences structures ***/ diff --git a/src/screen.cc b/src/screen.cc index e3c10b3..31e34c7 100644 --- a/src/screen.cc +++ b/src/screen.cc @@ -22,12 +22,36 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "preference.h" -#include "sprite.h" #include "screen.h" +#include "sprite.h" +#include "utils.h" /*** Variables globales ***/ /**************************/ extern Sprite *Sprites; +extern SDL_Renderer *sdlRenderer; + +Screen::Screen() +{ + // Loading font + char fontPath[512]; + strcpy(fontPath, "comic.ttf"); + Utils::GetPath(fontPath); + m_font = TTF_OpenFont(fontPath, 28); + + // Selecting font color + fColor.r = 255; + fColor.g = 255; + fColor.b = 255; + fColor.a = 255; +} + +Screen::~Screen() +{ + // Destroying font + SDL_DestroyTexture(fontTexture); + TTF_CloseFont(m_font); +} /*** Affiche un Sprite ***/ /*************************/ @@ -42,11 +66,37 @@ void Screen::PrintCable(int dx, int dy, int fx, int fy) Sprites[rope].PrintRope(dx, dy, fx, fy); } -/*** Affiche un text ***/ -/***********************/ -void Screen::PrintText(e_Sprite Text, int x, int y) +void Screen::ChangeFontSize(int size){ + TTF_SetFontSize(m_font, size); +} + +void Screen::ChangeFontColor(float r, float g, float b){ + fColor.r = r; + fColor.g = g; + fColor.b = b; + fColor.a = 255; +} + +void Screen::PrintText(const std::string &Text, int x, int y) { - Sprites[Text].Draw(x, y, 0); + fontSurface = TTF_RenderUTF8_Blended(m_font, Text.c_str(), fColor); // Rendering text + fontTexture = SDL_CreateTextureFromSurface(sdlRenderer, fontSurface); // Creating texture + + // Setting position and size + SDL_Rect dst; + dst.x = x; + dst.y = y; + dst.w = fontSurface->w; + dst.h = fontSurface->h; + + // Rendering text + SDL_RenderCopy(sdlRenderer, fontTexture, nullptr, &dst); +} + +int Screen::TextLength(std::string Text){ + int w,h; + TTF_SizeUTF8(m_font, Text.c_str(), &w, &h); + return w; } /*** Affiche les options du jeu ***/ @@ -56,7 +106,9 @@ void Screen::PrintOptions(int NV, int NScore) int x, y; Score = NScore; - DrawNumber(740, 215, Score); + ChangeFontSize(24); + PrintText(std::to_string(Score), 740 - TextLength(std::to_string(Score))/2, 215); + ChangeFontSize(22); if (NV > 10) { NV = 10; // Evite un dépassement de l'affichage diff --git a/src/screen.h b/src/screen.h index c47941e..9aef6aa 100644 --- a/src/screen.h +++ b/src/screen.h @@ -24,24 +24,37 @@ #ifndef SCREEN_DOM_ #define SCREEN_DOM_ -#include "sprite.h" +#include +#include +#include +#include +#include #include "preference.h" +#include "string" +#include "sprite.h" class Screen { public: - Screen() = default; - ~Screen() = default; + Screen(); + ~Screen(); 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 ChangeFontSize(int size); // Change font size + void ChangeFontColor(float r, float g, float b); + void PrintText(const std::string &Text, int x, int y); // Affiche un text à l'ecran + int TextLength(std::string Text); void PrintOptions(int NVies, int NScore); // Affiche les options sur le coté void CleanSpriteAndScreen(e_Sprite NumSpriteFondEcran); // Efface l'ecran avec l'image de fond private: /*** Variables ***/ int Score { -1 }; // Mémorise le score affiché + TTF_Font* m_font; + SDL_Color fColor; + SDL_Surface* fontSurface; + SDL_Texture* fontTexture; }; #endif diff --git a/src/sprite.cc b/src/sprite.cc index 754e372..9e98250 100644 --- a/src/sprite.cc +++ b/src/sprite.cc @@ -211,106 +211,6 @@ bool LoadSprites() return true; } -/*** Retourne la longueur d'un nombre ***/ -/****************************************/ -int NumberLength(int C) -{ - int l = 0; - - do { - l += Sprites[digits].Dim[(C % 10)].L; - C /= 10; - if (C) { - l += ECART_ENTRE_CHIFFRE; - } - } while (C); - - return l; -} - -/*** Retourne la longueur d'un texte ***/ -/***************************************/ -int StringLength(char *Texte) -{ - int i = 0; - int l = 0; - int Le; - - while (Texte[i] != 0) { - Le = (int)(Texte[i]); - if (TableTexte[Le] != -1) { - l += Sprites[lettres].Dim[(TableTexte[Le])].L; - if (Texte[i + 1] != 0) { - l += ECART_ENTRE_LETTRE; - } - } - else { - if (Le == (int)(' ')) { - l += LONGUEUR_ESPACE; - } - } - - i++; - } - - return l; -} - -/*** Test si un caracataire existe ***/ -/*************************************/ -bool CharExist(char C) -{ - if ((int)(C) < 0) { - return false; - } - if (C == ' ') { - return true; - } - if (TableTexte[(int)(C)] != -1) { - return true; - } - return false; -} -/*** Affiche un nombre ***/ -/*************************/ -void DrawNumber(int x, int y, int Nombre, SDL_Texture *Fond) -{ - int const l = NumberLength(Nombre); - - x += l / 2; - do { - Sprites[digits].Draw(x - (Sprites[digits].Dim[(Nombre % 10)].L) / 2, y, Nombre % 10, Fond); - x -= Sprites[digits].Dim[(Nombre % 10)].L + ECART_ENTRE_CHIFFRE; - Nombre /= 10; - } while (Nombre); -} - -/*** Affiche un Texte ***/ -/************************/ -void DrawString(int x, int y, char *Texte, SDL_Texture *Fond) -{ - int i = 0; - int Le; - - // TODO Handle here unicode - while (Texte[i] != 0) { - Le = (int)(Texte[i]); - - if (TableTexte[Le] != -1) { // Si un caractaire connue - Le = TableTexte[Le]; - Sprites[lettres].Draw(x + (Sprites[lettres].Dim[Le].L / 2), y, Le, Fond); - x += Sprites[lettres].Dim[Le].L + ECART_ENTRE_LETTRE; - } - else { // Si un espace - if (Le == (int)(' ')) { - x += LONGUEUR_ESPACE - ECART_ENTRE_LETTRE; - } - } - - i++; - } -} - /*** Affiche un text dans la langue ***/ /**************************************/ void DrawText(int x, int y, e_Sprite Text, SDL_Texture *Fond) diff --git a/src/sprite.h b/src/sprite.h index df5f7a2..e1a5ae7 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -178,13 +178,6 @@ void DrawLoading(); // Affiche le chargeur sur la page de départ bool LoadLanguage(); // Charge les sprites d'une langue bool LoadSprites(); // Charge tous les sprites -int NumberLength(int C); // Retourne la longueur en pixels d'un nombre -int StringLength(char *Texte); // Retourne la longueur en pixels d'un texte -bool CharExist(char C); // Si un caracataire existe - -void DrawNumber(int x, int y, int Nombre, SDL_Texture *Fond = nullptr); // Affiche un chiffre -void DrawString(int x, int y, char *Texte, SDL_Texture *Fond = nullptr); // Affiche une chaine de caractaire - void DrawText(int x, int y, e_Sprite Text, SDL_Texture *Fond = nullptr); // Affiche un text dans la langue /*** Definition de la classe Sprite ***/ diff --git a/src/utils.cc b/src/utils.cc index 9070adf..c2282ae 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -298,9 +298,9 @@ bool Utils::LoadPref() } Pref.Sco[i].Score = std::stoi(pv); if (pv) { - pv = ini.GetValue("highscore", nameKey.c_str(), Pref.Sco[i].Name); + pv = ini.GetValue("highscore", nameKey.c_str(), Pref.Sco[i].Name.c_str()); } - strncpy(Pref.Sco[i].Name, pv, 80); + Pref.Sco[i].Name = pv; } return true; } @@ -322,7 +322,7 @@ bool Utils::LoadPref() Pref.LevelMax[2] = oldPref.Difficulte == Hard ? oldPref.NiveauMax : 0; for (int i = 0; i < 8; ++i) { Pref.Sco[i].Score = oldPref.Sco[i].Score; - strncpy(Pref.Sco[i].Name, oldPref.Sco[i].Name, 80); + Pref.Sco[i].Name = std::string(oldPref.Sco[i].Name); } // TODO Delete old file at some file return true; @@ -354,7 +354,7 @@ void Utils::SavePref() std::string scoreKey = "score_" + std::to_string(i); std::string nameKey = "name_" + std::to_string(i); ini.SetValue("highscore", scoreKey.c_str(), std::to_string(Pref.Sco[i].Score).c_str()); - ini.SetValue("highscore", nameKey.c_str(), Pref.Sco[i].Name); + ini.SetValue("highscore", nameKey.c_str(), Pref.Sco[i].Name.c_str()); } ini.SaveFile(PathPref); } diff --git a/tools/Li-ri.sh b/tools/Li-ri.sh old mode 100755 new mode 100644 diff --git a/tools/bump_version.sh b/tools/bump_version.sh old mode 100755 new mode 100644 diff --git a/tools/create_release.sh b/tools/create_release.sh old mode 100755 new mode 100644