diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index eb3694d..83ec1bc 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -23,7 +23,7 @@ jobs: run: | sudo apt-get update sudo apt-get install -y cmake make - sudo apt-get install -y libsdl2-dev libsdl2-mixer-dev + sudo apt-get install -y libsdl2-dev libsdl2-mixer-dev libsdl2-ttf-dev - name: Install clang run: | diff --git a/Assets/Fonts/comic.ttf b/Assets/Fonts/comic.ttf new file mode 100644 index 0000000..6525a27 Binary files /dev/null and b/Assets/Fonts/comic.ttf differ diff --git a/CMakeLists.txt b/CMakeLists.txt index bdd58d6..bfb6c11 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 sdl_ttf::sdl_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/android/app/src/main/java/org/liri/app/LiRi.java b/android/app/src/main/java/org/liri/app/LiRi.java index 8c2801a..d98b2df 100644 --- a/android/app/src/main/java/org/liri/app/LiRi.java +++ b/android/app/src/main/java/org/liri/app/LiRi.java @@ -39,6 +39,7 @@ protected String[] getLibraries() { return new String[] { "SDL2", "SDL2_mixer", + "SDL2_ttf", "main" }; } diff --git a/android/app/src/main/jni/src/Android.mk b/android/app/src/main/jni/src/Android.mk index de032b0..53ee6e7 100644 --- a/android/app/src/main/jni/src/Android.mk +++ b/android/app/src/main/jni/src/Android.mk @@ -8,6 +8,7 @@ SDL_PATH := ../SDL2 LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/ \ $(LOCAL_PATH)/../SDL2_mixer \ + $(LOCAL_PATH)/../SDL2_ttf \ $(LOCAL_PATH)/../simpleini \ # Add your application source files here... @@ -25,7 +26,7 @@ LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \ ../../../../../../src/sprite.cc \ ../../../../../../src/utils.cc \ -LOCAL_SHARED_LIBRARIES := SDL2 SDL2_mixer +LOCAL_SHARED_LIBRARIES := SDL2 SDL2_mixer SDL2_ttf LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog diff --git a/android/src/org/libsdl/app/SDLActivity.java b/android/src/org/libsdl/app/SDLActivity.java index 0c453aa..ff47349 100644 --- a/android/src/org/libsdl/app/SDLActivity.java +++ b/android/src/org/libsdl/app/SDLActivity.java @@ -50,7 +50,7 @@ public class SDLActivity extends Activity { //System.loadLibrary("SDL2_image"); System.loadLibrary("SDL2_mixer"); //System.loadLibrary("SDL2_net"); - //System.loadLibrary("SDL2_ttf"); + System.loadLibrary("SDL2_ttf"); System.loadLibrary("main"); } diff --git a/conanfile.py b/conanfile.py index 9a3ade6..a6680f6 100644 --- a/conanfile.py +++ b/conanfile.py @@ -3,7 +3,7 @@ class LiRi(ConanFile): settings = "os", "compiler", "build_type", "arch" - requires = "sdl/2.32.10", "sdl_mixer/2.8.1", "openssl/1.1.1w" + requires = "sdl/2.32.10", "sdl_mixer/2.8.1", "sdl_ttf/2.24.0", "openssl/1.1.1w" tool_requires = "cmake/4.2.1" def layout(self): diff --git a/src/editor.cc b/src/editor.cc index fad4486..f6e1afd 100644 --- a/src/editor.cc +++ b/src/editor.cc @@ -244,7 +244,7 @@ void Editor::Draw() const } // Displays the level number - DrawNumber(740, 130, NumN + 1); + // DrawNumber(740, 130, NumN + 1); // Display possible sprites for (i = 0; i < LT * HT; i++) { diff --git a/src/game.cc b/src/game.cc index 658559b..4ed5d12 100644 --- a/src/game.cc +++ b/src/game.cc @@ -359,12 +359,15 @@ bool Game::DrawLevel(int LevelN) #endif // Displays texts for selected language - DrawText(740, 110, T_level, Sprites[fgame].Image[0]); - DrawText(740, 180, T_score, Sprites[fgame].Image[0]); - DrawText(740, 260, T_options, Sprites[fgame].Image[0]); - DrawText(740, 340, T_lives, Sprites[fgame].Image[0]); + m_screen.ChangeFontSize(20); + m_screen.ChangeFontColor(255, 255, 0); + m_screen.PrintText("Level", 740 - m_screen.TextLength("Level") / 2, 110); + m_screen.PrintText("Score", 740 - m_screen.TextLength("Score") / 2, 180); + m_screen.PrintText("Options", 740 - m_screen.TextLength("Options") / 2, 260); + m_screen.PrintText("Lives", 740 - m_screen.TextLength("Lives") / 2, 340); + m_screen.ChangeFontColor(255, 255, 255); - DrawNumber(740, 140, Pref.Level + 1, Sprites[fgame].Image[0]); + m_screen.PrintText(std::to_string(Pref.Level + 1), 740 - m_screen.TextLength(std::to_string(Pref.Level + 1)) / 2, 140); return true; } @@ -548,7 +551,13 @@ void Game::DisplayScreen() // When paused, asks for a key press if (Pause) { - m_screen.PrintText(T_press_any_key, LT * D_Case / 2, 300); + m_screen.ChangeFontSize(60); + m_screen.ChangeFontColor(0, 0, 0); + m_screen.PrintText("Press any key", 341 - m_screen.TextLength("Press any key") / 2, 271); + m_screen.ChangeFontColor(255, 255, 0); + m_screen.PrintText("Press any key", 340 - m_screen.TextLength("Press any key") / 2, 270); + m_screen.ChangeFontColor(255, 255, 255); + m_screen.ChangeFontSize(14); } // Prints a dashboard diff --git a/src/main.cc b/src/main.cc index 5d07995..2efa76f 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" @@ -97,6 +98,7 @@ int main(int narg, char *argv[]) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to initialize SDL: %s", SDL_GetError()); exit(-1); } + TTF_Init(); // Close the program properly when quitting atexit(SDL_Quit); diff --git a/src/menu.cc b/src/menu.cc index 4338f9c..dfac6a4 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -72,6 +72,24 @@ void Sleeping() } } +/*** Add button with text to the menu array ***/ +/**********************************************/ +void AddTextButton(int Num, const std::string &Text, int X, int Y, Screen &ScreenObj) +{ + ScreenObj.ChangeFontSize(45); + + int textWidth = ScreenObj.TextLength(Text); + + ScreenObj.PrintText(Text, X - textWidth / 2, Y - 22); + + Menu_Py[Num].StartX = X - textWidth / 2; + Menu_Py[Num].StartY = Y - 22; + Menu_Py[Num].EndX = X + textWidth / 2; + Menu_Py[Num].EndY = Y + 22; + Menu_Py[Num].Py = Num; + Menu_Py[Num].Valid = true; +} + /*** Add an button to the menu array ***/ /***************************************/ void AddButton(int Num, e_Sprite NumSp, int X, int Y) @@ -116,16 +134,16 @@ eMenu Menu::SDLMain() Sprites[background_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); + + m_screen.ChangeFontSize(14); + // Automatic year change + m_screen.PrintText(CopyrightText, 400 - m_screen.TextLength(CopyrightText) / 2, 575); + m_screen.ChangeFontSize(22); + + AddTextButton(0, "Play", 400, 229, m_screen); + AddTextButton(1, "Scores", 400, 306, m_screen); + AddTextButton(2, "Options", 400, 384, m_screen); + AddTextButton(3, "Exit", 400, 461, m_screen); Menu_Py[4].StartX = -1; SDL_Event event; while (SDL_PollEvent(&event)) { @@ -172,14 +190,12 @@ eMenu Menu::SDLMain() break; default: key = event.key.keysym.sym & 0x7F; // Gets the character corresponding to the key - if (CharExist(key) == true) { // if character exists - for (i = 2; i >= 0; i--) { - MCode[i + 1] = MCode[i]; // shift code - } - MCode[0] = key; - if (strcmp(MCode, "tide") == 0 || strcmp(MCode, "TIDE") == 0) { - return mEdit; // If level editor selected - } + for (i = 2; i >= 0; i--) { + MCode[i + 1] = MCode[i]; // shift code + } + MCode[0] = key; + if (strcmp(MCode, "tide") == 0 || strcmp(MCode, "TIDE") == 0) { + return mEdit; // If level editor selected } } } @@ -384,9 +400,7 @@ void Menu::InitMain_Options() Menu_Py[4].Valid = true; // Center text left - CenterM = 120 + Sprites[T_menu].Dim[0].L / 2; - DrawText(CenterM, 490, T_menu, Sprites[fmenu].Image[0]); - AddButton(5, T_menu, CenterM, 490); + AddTextButton(5, "Menu", 180, 490, m_screen); // Sound buttons Sprites[arrows].Draw(250, 110, 1, Sprites[fmenu].Image[0]); @@ -632,13 +646,13 @@ eMenu Menu::SDLMain_Options() switch (Pref.AudioTheme) { case mMaf: - DrawString(400, 420, "MAF 464", Sprites[fmenu].Image[0]); + m_screen.PrintText("MAF 464", 400, 390); break; case mZabiden: - DrawString(400, 420, "ZABIDEN", Sprites[fmenu].Image[0]); + m_screen.PrintText("ZABIDEN", 400, 390); break; } - DrawString(350, 370, "Audio Theme", Sprites[fmenu].Image[0]); + m_screen.PrintText("Audio Theme", 360, 340); NumSp = (currentTime / 30) % 25; m_screen.PrintSprite(sound, NumSp, 150, 110); @@ -676,7 +690,7 @@ eMenu Menu::SDLMain_Options() Print_Main(490); break; case 5: - Print_Main(CenterM); + Print_Main(180); break; case 6: PyE = 0; @@ -729,12 +743,9 @@ eMenu Menu::SDLMain_Speed() 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, m_screen); + AddTextButton(1, "Normal", 400, 340, m_screen); + AddTextButton(2, "Hard", 400, 455, m_screen); Menu_Py[3].StartX = -1; SDL_Event event; @@ -835,12 +846,9 @@ eMenu Menu::SDLMain_Level() 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, m_screen); + AddTextButton(1, "Old level", 400, 305, m_screen); + AddTextButton(2, "Menu", 400, 445, m_screen); AddButton(3, arrows, 330, 380); AddButton(4, arrows, 470, 380); @@ -958,7 +966,7 @@ eMenu Menu::SDLMain_Level() m_screen.PrintSprite(arrows, 3, 470, 380); } - DrawNumber(400, 380, Level + 1); + m_screen.PrintText(std::to_string(Level + 1), 390, 355); if (PyE != 3 && PyE != 4) { Print_Main(); @@ -1208,12 +1216,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, m_screen); + AddTextButton(1, "Settings", 340, 300, m_screen); + AddTextButton(2, "Exit", 340, 415, m_screen); Menu_Py[3].StartX = -1; } @@ -1313,7 +1318,6 @@ eMenu Menu::SDLMain_Score(bool EditScore) int i; int NEdit = -1; char Provi[256]; - int PosCur = 0; char key; // Searches the score index to edit @@ -1330,13 +1334,13 @@ eMenu Menu::SDLMain_Score(bool EditScore) if (NEdit < 7) { // if shifting must be done 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; } } // Erase name and enter score Pref.Sco[NEdit].Score = Pref.Score; - Pref.Sco[NEdit].Name[0] = 0; + Pref.Sco[NEdit].Name.clear(); } // Sets mouse on entire display @@ -1362,25 +1366,31 @@ eMenu Menu::SDLMain_Score(bool EditScore) Sprites[background_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]); + m_screen.ChangeFontColor(255, 255, 0); + m_screen.PrintText("Better scores", 400 - m_screen.TextLength("Better scores") / 2, 50); +#ifndef ANDROID + m_screen.PrintText("Press any key", 400 - m_screen.TextLength("Press any key") / 2, 540); +#else + m_screen.PrintText("Tap to continue", 400 - m_screen.TextLength("Tap to continue") / 2, 540); +#endif + m_screen.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]); + m_screen.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()) { + m_screen.PrintText(Pref.Sco[i].Name, 140, 120 + i * (360 / 7)); } else { - DrawString(140, 120 + i * (360 / 7), Points, Sprites[fmenu].Image[0]); + m_screen.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]); + m_screen.PrintText(Provi, 720 - m_screen.TextLength(std::string(Provi)), 120 + i * (360 / 7)); } // Erase background @@ -1397,6 +1407,15 @@ eMenu Menu::SDLMain_Score(bool EditScore) break; case SDL_KEYDOWN: // Waits a Keyboard press if (event.key.state == SDL_PRESSED) { + if (NEdit >= 0 && event.key.keysym.sym == SDLK_BACKSPACE && !Pref.Sco[NEdit].Name.empty()) { + std::string ¤tScore = Pref.Sco[NEdit].Name; + // For utf-8 characters, we need to pop_back twice + // Use SDL_StepBackUTF8 with sdl3 to detect utf-8 characters? + if ((currentScore[currentScore.size() - 1] & 0xc0) == 0x80) { + currentScore.pop_back(); + } + currentScore.pop_back(); + } m_audio.Play(sClick); if (EditScore == false && event.key.keysym.sym != SDLK_F12) { event.key.keysym.sym = SDLK_RETURN; @@ -1414,22 +1433,14 @@ eMenu Menu::SDLMain_Score(bool EditScore) SDL_StopTextInput(); } return mMenu; - case SDLK_BACKSPACE: // Erases - 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.size() <= 16) { + Pref.Sco[NEdit].Name += event.text.text; } break; case SDL_QUIT: @@ -1445,12 +1456,15 @@ 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()) { + m_screen.PrintText(Pref.Sco[NEdit].Name, 140, 120 + NEdit * (360 / 7)); + } i = (currentTime / 50) % 20; // Draw cursors - m_screen.PrintSprite(arrow_left, i, 110, 120 + NEdit * (360 / 7)); - m_screen.PrintSprite(arrow_right, i, 180 + StringLength(Pref.Sco[NEdit].Name), 120 + NEdit * (360 / 7)); + int textLen = Pref.Sco[NEdit].Name.empty() ? 0 : m_screen.TextLength(Pref.Sco[NEdit].Name); + m_screen.PrintSprite(arrow_left, i, 110, 150 + NEdit * (360 / 7)); + m_screen.PrintSprite(arrow_right, i, 180 + textLen, 150 + NEdit * (360 / 7)); } // Update render diff --git a/src/menu.h b/src/menu.h index 5db645e..09921b9 100644 --- a/src/menu.h +++ b/src/menu.h @@ -26,6 +26,8 @@ #include "preference.h" +#include + void Sleeping(); class Game; @@ -60,13 +62,15 @@ class Menu private: int PyE { 0 }; // Position of the cursor in the menu int Level { 0 }; - int CenterM { 0 }; // Variable for the settings menu Game &m_game; Audio &m_audio; Screen &m_screen; Mouse &m_mouse; Gamepad &m_gamepad; + + int Year = 2026; + std::string CopyrightText = "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"; }; #endif diff --git a/src/preference.h b/src/preference.h index b3253a2..92b1beb 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; }; /*** Old Preferences structures, UNUSED ***/ diff --git a/src/screen.cc b/src/screen.cc index 2eea0ab..d8c7cb2 100644 --- a/src/screen.cc +++ b/src/screen.cc @@ -22,10 +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" extern Sprite *Sprites; +extern SDL_Renderer *sdlRenderer; + +/*** Constructor ***/ +/*******************/ +Screen::Screen() +{ + // Loading font + char fontPath[512]; + strcpy(fontPath, "Assets/Fonts/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; +} + +/*** Destructor ***/ +/******************/ +Screen::~Screen() +{ + TTF_CloseFont(m_font); +} /*** Display a sprite ***/ /************************/ @@ -40,11 +66,44 @@ void Screen::PrintCable(int dx, int dy, int fx, int fy) Sprites[rope].PrintRope(dx, dy, fx, fy); } +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; +} + /*** Display a text ***/ /**********************/ -void Screen::PrintText(e_Sprite Text, int x, int y) +void Screen::PrintText(const std::string &Text, int x, int y) +{ + SDL_Texture *texture = nullptr; + SDL_Surface *surf = TTF_RenderUTF8_Blended(m_font, Text.c_str(), fColor); + texture = SDL_CreateTextureFromSurface(sdlRenderer, surf); + SDL_FreeSurface(surf); + + // Setting position and size + SDL_Rect Position; + SDL_QueryTexture(texture, nullptr, nullptr, &Position.w, &Position.h); + Position.x = x; // - Position.w; + Position.y = y; // - Position.h; + + // Rendering text + SDL_RenderCopy(sdlRenderer, texture, nullptr, &Position); + SDL_DestroyTexture(texture); +} + +int Screen::TextLength(const std::string &Text) { - Sprites[Text].Draw(x, y, 0); + int w, h; + TTF_SizeUTF8(m_font, Text.c_str(), &w, &h); + return w; } /*** Display game settings ***/ @@ -54,7 +113,9 @@ void Screen::PrintOptions(int Nlives, 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 (Nlives > 10) { Nlives = 10; // Clamp to avoid going off screen diff --git a/src/screen.h b/src/screen.h index e4431d7..d21eb16 100644 --- a/src/screen.h +++ b/src/screen.h @@ -24,23 +24,31 @@ #ifndef SCREEN_DOM_ #define SCREEN_DOM_ -#include "sprite.h" +#include +#include +#include #include "preference.h" +#include "sprite.h" class Screen { public: - Screen() = default; - ~Screen() = default; + Screen(); + ~Screen(); void PrintSprite(e_Sprite NumSpr, int Num, int x, int y); // Displays a sprite void PrintCable(int dx, int dy, int fx, int fy); // Displays a cable/rope - void PrintText(e_Sprite Text, int x, int y); // Displays text + 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); // Displays text + int TextLength(const std::string &Text); void PrintOptions(int Nlives, int NScore); // Displays information on the side void CleanSpriteAndScreen(e_Sprite NumSpritebackground); // Erases display with background image private: int Score { -1 }; // Stores displayed score + SDL_Color fColor; + TTF_Font *m_font; }; #endif diff --git a/src/sprite.cc b/src/sprite.cc index 452fec3..ad49d9f 100644 --- a/src/sprite.cc +++ b/src/sprite.cc @@ -35,10 +35,6 @@ extern Sprite *Sprites; extern int NSprites; extern sNewPreference Pref; -static const char *TextOrder = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-!?*+<>%$()&;"; -static const char *TextOrder2 = "abcdefghijklmnopqrstuvwxyz0123456789,_|?*+<>%$[]&;"; -static int TextTable[256]; - char Languages[31][16]; // Stores languages int NTexts = 0; bool shouldDrawLoading = false; @@ -111,21 +107,6 @@ bool LoadSprites() char PathFile[512] = "language.dat"; Utils::GetPath(PathFile); - // Initialize characters table for texts - for (i = 0; i < 256; i++) { - TextTable[i] = -1; - } - i = 0; - while (TextOrder[i] != 0) { - TextTable[(int)(TextOrder[i])] = i; - i++; - } - i = 0; - while (TextOrder2[i] != 0) { - TextTable[(int)(TextOrder2[i])] = i; - i++; - } - // *** Loads the languages file *** // ******************************** if (Utils::FileExists(PathFile) == false) { @@ -226,49 +207,6 @@ int NumberLength(int C) return l; } -/*** Returns the length of a string ***/ -/**************************************/ -int StringLength(char *Text) -{ - int i = 0; - int l = 0; - int Le; - - while (Text[i] != 0) { - Le = (int)(Text[i]); - if (TextTable[Le] != -1) { - l += Sprites[letters].Dim[(TextTable[Le])].L; - if (Text[i + 1] != 0) { - l += GAP_BETWEEN_LETTERS; - } - } - else { - if (Le == (int)(' ')) { - l += SPACE_LENGTH; - } - } - - i++; - } - - return l; -} - -/*** Checks if a char exists ***/ -/*******************************/ -bool CharExist(char C) -{ - if ((int)(C) < 0) { - return false; - } - if (C == ' ') { - return true; - } - if (TextTable[(int)(C)] != -1) { - return true; - } - return false; -} /*** Displays a number ***/ /*************************/ void DrawNumber(int x, int y, int Number, SDL_Texture *Background) @@ -283,32 +221,6 @@ void DrawNumber(int x, int y, int Number, SDL_Texture *Background) } while (Number); } -/*** Display a string ***/ -/************************/ -void DrawString(int x, int y, const char *Text, SDL_Texture *background) -{ - int i = 0; - int Le; - - // TODO Handle here unicode - while (Text[i] != 0) { - Le = (int)(Text[i]); - - if (TextTable[Le] != -1) { // If known char - Le = TextTable[Le]; - Sprites[letters].Draw(x + (Sprites[letters].Dim[Le].L / 2), y, Le, background); - x += Sprites[letters].Dim[Le].L + GAP_BETWEEN_LETTERS; - } - else { // if there's a space - if (Le == (int)(' ')) { - x += SPACE_LENGTH - GAP_BETWEEN_LETTERS; - } - } - - i++; - } -} - /*** Display text in a language ***/ /**********************************/ void DrawText(int x, int y, e_Sprite Text, SDL_Texture *Background) diff --git a/src/sprite.h b/src/sprite.h index 4ffcb86..513c232 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -177,11 +177,8 @@ bool LoadLanguage(); // Loads sprites of a language bool LoadSprites(); // Loads all sprites int NumberLength(int C); // Returns the length in pixels of a number -int StringLength(char *Text); // Returns the length in pixels of a string. -bool CharExist(char C); // Checks if a character exists void DrawNumber(int x, int y, int Number, SDL_Texture *Background = nullptr); // Displays a number -void DrawString(int x, int y, const char *Text, SDL_Texture *Background = nullptr); // Displays a string void DrawText(int x, int y, e_Sprite Text, SDL_Texture *Background = nullptr); // Displays a text in the language diff --git a/src/utils.cc b/src/utils.cc index 20250f2..6e5d254 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -302,9 +302,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; } @@ -326,7 +326,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; @@ -359,7 +359,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); }