diff --git a/.gitignore b/.gitignore index 3042647..71eab3f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ *.lo *.o *.obj +*.mo +*.pot +*.po~ # Precompiled Headers *.gch diff --git a/CMakeLists.txt b/CMakeLists.txt index 4867649..b67b4e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,20 @@ include_directories( ${JSONCPP_INCLUDE_DIRS} ) +option(TRANSLATION_SUPPORT "Add support for loading translations, requires tinygettext" OFF) + +# Create translations +if(TRANSLATION_SUPPORT) + pkg_search_module(TINYGETTEXT REQUIRED tinygettext) + if(BUILD_STATIC) + target_link_libraries(${PROJECT_NAME} PRIVATE ${TINYGETTEXT_STATIC_LIBRARIES}) + else() + target_link_libraries(${PROJECT_NAME} PRIVATE ${TINYGETTEXT_LIBRARIES}) + endif() + + add_compile_definitions(TRANSLATION_SUPPORT=1) +endif() + # Set asset paths set(ASSETS_FONTS "${CMAKE_SOURCE_DIR}/assets/fonts") set(ASSETS_IMAGES "${CMAKE_SOURCE_DIR}/assets/images") @@ -69,6 +83,9 @@ set(ASSETS_LEVELS "${CMAKE_SOURCE_DIR}/assets/levels") set(ASSETS_SOUNDS "${CMAKE_SOURCE_DIR}/assets/sounds") set(ASSETS_MUSIC "${CMAKE_SOURCE_DIR}/assets/music") set(ASSETS_BACKGROUNDS "${CMAKE_SOURCE_DIR}/assets/backgrounds") +if(TRANSLATION_SUPPORT) + set(ASSETS_LANGUAGES "${CMAKE_SOURCE_DIR}/assets/languages") +endif() if(PSP) set(ASSETS_BACKGROUNDS "${CMAKE_CURRENT_SOURCE_DIR}/platform/psp/assets/backgrounds") @@ -99,6 +116,11 @@ if(NOT VITA) add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${ASSETS_SOUNDS} ${CMAKE_CURRENT_BINARY_DIR}/assets/sounds) + if(TRANSLATION_SUPPORT) + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${ASSETS_LANGUAGES} ${CMAKE_CURRENT_BINARY_DIR}/assets/languages) + endif() endif() # Platform specific install diff --git a/assets/languages/nl.po b/assets/languages/nl.po new file mode 100644 index 0000000..e138e4f --- /dev/null +++ b/assets/languages/nl.po @@ -0,0 +1,164 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-07-18 15:25+0200\n" +"PO-Revision-Date: 2024-07-18 11:07+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.4\n" + +#: ../src/BoardManager.cpp:610 +msgid " moves" +msgstr " acties" + +#: ../src/states/WonState.cpp:7 +msgid "Game Mode Completed!" +msgstr "Modus Afgerond!" + +#: ../src/states/GameOverState.cpp:7 +msgid "Game Over!" +msgstr "Game Over!" + +#: ../src/states/GameStateChallenge.cpp:12 ../src/states/GameState.cpp:15 +#: ../src/states/GameStateRelaxed.cpp:7 +msgid "Game Paused" +msgstr "Spel gepauseerd" + +#: ../src/states/HighscoreState.cpp:12 +msgid "High Scores" +msgstr "Resultaten" + +#: ../src/states/GameStateChallenge.cpp:14 ../src/states/GameState.cpp:17 +msgid "Level Failed" +msgstr "Level Mislukt" + +#: ../src/states/GameStateChallenge.cpp:13 ../src/states/GameState.cpp:16 +msgid "Level Finished!" +msgstr "Level Afgerond!" + +#: ../src/states/NotImplementedState.cpp:7 +msgid "Not Yet Implemented" +msgstr "Nog Niet Geimplementeerd" + +#: ../src/states/OptionsState.cpp:272 +msgid "Options" +msgstr "opties" + +#: ../src/states/MenuState.cpp:23 +msgid "challenge mode" +msgstr "uitdagingsmodus" + +#: ../src/states/OptionsState.cpp:172 +msgid "change music upon level switch: " +msgstr "wissel muziek bij level overgang: " + +#: ../src/states/MenuState.cpp:24 +msgid "ends only when lives run out" +msgstr "eindigt alleen als je levens op zijn" + +#: ../src/states/MenuState.cpp:37 +msgid "exit" +msgstr "stoppen" + +#: ../src/states/OptionsState.cpp:176 +msgid "full screen: " +msgstr "volledig scherm" + +#: ../src/states/MenuState.cpp:31 +msgid "high scores" +msgstr "resultaten" + +#: ../src/states/HighscoreState.cpp:17 +msgid "highest level reached in challenge mode: " +msgstr "hoogste level bereikt in uitdagingsmodus: " + +#: ../src/BoardManager.cpp:590 +msgid "level " +msgstr "level " + +#: ../src/states/GameStateChallenge.cpp:112 +msgid "lives left" +msgstr "levens " + +#: ../src/states/MenuState.cpp:28 +msgid "match without consequences" +msgstr "match zonder consequenties" + +#: ../src/states/HighscoreState.cpp:18 +msgid "matches in relaxed mode: " +msgstr "matches in relaxmodus: " + +#: ../src/states/OptionsState.cpp:162 +msgid "music volume: " +msgstr "muziekvolume: " + +#: ../src/states/HighscoreState.cpp:15 ../src/states/OptionsState.cpp:172 +#: ../src/states/OptionsState.cpp:176 +msgid "no" +msgstr "nee" + +#: ../src/states/MenuState.cpp:34 +msgid "options" +msgstr "opties" + +#: ../src/states/MenuState.cpp:20 +msgid "play pre-made levels" +msgstr "speel voorgeprogrammeerde levels" + +#: ../src/states/HighscoreState.cpp:13 +msgid "press confirm to go back" +msgstr "druk op bevestigen om terug te gaan" + +#: ../src/states/GameStateChallenge.cpp:13 ../src/states/GameState.cpp:16 +#: ../src/states/NotImplementedState.cpp:7 +msgid "press the confirm button to continue" +msgstr "druk op bevestigen om verder te gaan" + +#: ../src/states/GameOverState.cpp:7 ../src/states/GameStateChallenge.cpp:12 +#: ../src/states/GameState.cpp:15 ../src/states/GameStateRelaxed.cpp:7 +#: ../src/states/WonState.cpp:7 +msgid "press the confirm button to exit" +msgstr "druk op bevestigen om te sluiten" + +#: ../src/states/GameStateChallenge.cpp:14 ../src/states/GameState.cpp:17 +msgid "press the confirm button to restart" +msgstr "druk op bevestigen om het opnieuw te proberen" + +#: ../src/states/MenuState.cpp:27 +msgid "relaxed mode" +msgstr "relaxmodus" + +#: ../src/states/OptionsState.cpp:180 +msgid "resolution: " +msgstr "resolutie: " + +#: ../src/states/OptionsState.cpp:295 +msgid "return to menu" +msgstr "terug naar menu" + +#: ../src/states/OptionsState.cpp:152 +msgid "sound volume: " +msgstr "volume geluiden: " + +#: ../src/states/MenuState.cpp:19 +msgid "standard mode" +msgstr "standardmodus" + +#: ../src/states/HighscoreState.cpp:16 +msgid "standard mode completed: " +msgstr "standardmodus afgesloten: " + +#: ../src/states/HighscoreState.cpp:15 ../src/states/OptionsState.cpp:172 +#: ../src/states/OptionsState.cpp:176 +msgid "yes" +msgstr "ja" diff --git a/platform/add-translation.sh b/platform/add-translation.sh new file mode 100755 index 0000000..c12860a --- /dev/null +++ b/platform/add-translation.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +cd "$(dirname "$0")" + +if [ -z "${1}" ]; then + echo "Please select a language like: ${0} en_US" +fi + +POTFILE="oceanpop.pot" + +xgettext --from-code=UTF-8 --keyword=_ --sort-output --language=C++ ../src/*.cpp ../src/*.hpp ../src/states/*.cpp ../src/states/*.hpp -o ${POTFILE} + +msginit --locale="${1}" --input=${POTFILE} -o "../assets/languages/${1}.po" \ No newline at end of file diff --git a/platform/update-translation-files.sh b/platform/update-translation-files.sh new file mode 100755 index 0000000..ea63f7c --- /dev/null +++ b/platform/update-translation-files.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +cd "$(dirname "$0")" + +POTFILE="oceanpop.pot" + +xgettext --from-code=UTF-8 --keyword=_ --sort-output --language=C++ ../src/*.cpp ../src/*.hpp ../src/states/*.cpp ../src/states/*.hpp -o ${POTFILE} + +# Update each po file +for langfile in ../assets/languages/*.po; do + msgmerge -U "${langfile}" "${POTFILE}" +done diff --git a/src/BoardManager.cpp b/src/BoardManager.cpp index ef2080f..b1ebeca 100644 --- a/src/BoardManager.cpp +++ b/src/BoardManager.cpp @@ -7,6 +7,7 @@ #include "Sound.hpp" #include "colors.hpp" #include "FontType.hpp" +#include "utils.hpp" BoardManager::BoardManager(SDL_Renderer *renderer, FontManager *fonts, SoundManager * sounds, OptionManager * options, int x, int y, int width, int height, int moves, int required_matches, int level, int seed) : fonts(fonts), sounds(sounds), options(options), textures(renderer, options) { @@ -586,7 +587,7 @@ void BoardManager::drawInfo(SDL_Renderer * renderer) { // Generate texture with text if (this->level_updated) { std::string str_level = std::to_string(level); - str_level = "level " + str_level; + str_level = _("level ") + str_level; if (text_level != NULL) { SDL_DestroyTexture(text_level); } @@ -606,7 +607,7 @@ void BoardManager::drawInfo(SDL_Renderer * renderer) { } if (this->moves_updated) { std::string str_moves = std::to_string(this->moves); - str_moves += " moves"; + str_moves += _(" moves"); if (text_moves != NULL) { SDL_DestroyTexture(text_moves); } diff --git a/src/TranslationManager.cpp b/src/TranslationManager.cpp new file mode 100644 index 0000000..673f244 --- /dev/null +++ b/src/TranslationManager.cpp @@ -0,0 +1,77 @@ +#ifdef TRANSLATION_SUPPORT + +#include "TranslationManager.hpp" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "utils.hpp" + +TranslationManager::TranslationManager() : dictionary_manager(std::unique_ptr(new tinygettext::UnixFileSystem)) { + loadTranslations(); +} + +TranslationManager::~TranslationManager() { + +} + +void TranslationManager::loadTranslations() { + std::string language_dir = getResourcePath("assets/languages/"); + dictionary_manager.add_directory(language_dir); + + + for(std::string system_language : getSystemLanguageList()) { + tinygettext::Language language = tinygettext::Language::from_name(system_language); + if (language) { + for (tinygettext::Language l: dictionary_manager.get_languages()) { + if (l == language) { + dictionary_manager.set_language(language); + SDL_Log("Using language %s", language.get_language().c_str()); + language_set = true; + return; + } + } + } + } + SDL_Log("Using default language English");; +} + +std::vector TranslationManager::getSystemLanguageList() { + std::vector locales; + + #include + char * locale_c_str = setlocale(LC_ALL, ""); + if (locale_c_str != NULL){ + std::string locale(locale_c_str); + if (strlen(locale_c_str) > 1) { + free(locale_c_str); + } + + locales.push_back(locale); + if (locale.find(".") != std::string::npos) { + locales.push_back(locale.substr(0, locale.find("."))); + } + if (locale.find("_") != std::string::npos) { + locales.push_back(locale.substr(0, locale.find("_"))); + } + } + + return locales; +} + +std::string TranslationManager::translate(std::string input) { + if (language_set) { + return dictionary_manager.get_dictionary().translate(input); + } else { + return input; + } +} + +#endif // TRANSLATION_SUPPORT \ No newline at end of file diff --git a/src/TranslationManager.hpp b/src/TranslationManager.hpp new file mode 100644 index 0000000..6228d2b --- /dev/null +++ b/src/TranslationManager.hpp @@ -0,0 +1,25 @@ +#ifndef TRANSLATIONMANAGER_H +#define TRANSLATIONMANAGER_H + +#ifdef TRANSLATION_SUPPORT +#include + +#include + +class TranslationManager { +private: + tinygettext::DictionaryManager dictionary_manager; + bool language_set = false; + + std::vector getSystemLanguageList(); + void loadTranslations(); + +public: + TranslationManager(); + ~TranslationManager(); + + std::string translate(std::string input); +}; +#endif + +#endif // TRANSLATIONMANAGER_H \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 5a26dae..3c7557a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,10 +11,16 @@ #include "StateManager.hpp" #include "EventManager.hpp" #include "OptionManager.hpp" +#include "TranslationManager.hpp" #include "utils.hpp" #include "constants.hpp" #include "states/MenuState.hpp" +#ifdef TRANSLATION_SUPPORT + // Create global TranslationManager object set in utils.h + TranslationManager translation_manager; +#endif + void run() { OptionManager option_manager; Window window("OceanPop", &option_manager); diff --git a/src/states/GameOverState.cpp b/src/states/GameOverState.cpp index 8ca8a05..6cb1eb4 100644 --- a/src/states/GameOverState.cpp +++ b/src/states/GameOverState.cpp @@ -1,8 +1,10 @@ #include "GameOverState.hpp" +#include "../utils.hpp" + GameOverState::GameOverState(SDL_Renderer * renderer, FontManager * fonts, SoundManager * sounds, OptionManager * options) : theme(renderer, options, Theme::MENU), - screen_text(renderer, fonts, options, "Game Over!", "press the confirm button to exit") + screen_text(renderer, fonts, options, _("Game Over!"), _("press the confirm button to exit")) { this->renderer = renderer; this->fonts = fonts; diff --git a/src/states/GameState.cpp b/src/states/GameState.cpp index d4cf8fa..b4231dc 100644 --- a/src/states/GameState.cpp +++ b/src/states/GameState.cpp @@ -12,9 +12,9 @@ GameState::GameState(SDL_Renderer * renderer, FontManager * fonts, SoundManager * sounds, OptionManager * options) : theme(renderer, options, Theme::NONE), - pause_screen(renderer, fonts, options, "Game Paused", "press the confirm button to exit"), - win_screen(renderer, fonts, options, "Level Finished!", "press the confirm button to continue"), - lose_screen(renderer, fonts, options, "Level Failed", "press the confirm button to restart") + pause_screen(renderer, fonts, options, _("Game Paused"), _("press the confirm button to exit")), + win_screen(renderer, fonts, options, _("Level Finished!"), _("press the confirm button to continue")), + lose_screen(renderer, fonts, options, _("Level Failed"), _("press the confirm button to restart")) { this->renderer = renderer; this->fonts = fonts; diff --git a/src/states/GameStateChallenge.cpp b/src/states/GameStateChallenge.cpp index 7afb659..4fd722c 100644 --- a/src/states/GameStateChallenge.cpp +++ b/src/states/GameStateChallenge.cpp @@ -5,12 +5,13 @@ #include #include "../colors.hpp" #include "../FontType.hpp" +#include "../utils.hpp" GameStateChallenge::GameStateChallenge(SDL_Renderer * renderer, FontManager * fonts, SoundManager * sounds, OptionManager * options) : theme(renderer, options, Theme::NONE), - pause_screen(renderer, fonts, options, "Game Paused", "press the confirm button to exit"), - win_screen(renderer, fonts, options, "Level Finished!", "press the confirm button to continue"), - lose_screen(renderer, fonts, options, "Level Failed", "press the confirm button to restart") + pause_screen(renderer, fonts, options, _("Game Paused"), _("press the confirm button to exit")), + win_screen(renderer, fonts, options, _("Level Finished!"), _("press the confirm button to continue")), + lose_screen(renderer, fonts, options, _("Level Failed"), _("press the confirm button to restart")) { this->renderer = renderer; this->fonts = fonts; @@ -108,7 +109,7 @@ void GameStateChallenge::draw(SDL_Renderer *renderer) { void GameStateChallenge::drawAttempts(SDL_Renderer * renderer) { if(text_attempts == NULL) { - text_attempts = fonts->getTexture(renderer, "lives left", FontType::NORMAL, {255, 255, 255, 255}); + text_attempts = fonts->getTexture(renderer, _("lives left"), FontType::NORMAL, {255, 255, 255, 255}); } if (this->attempts_changed) { if (text_attempts_number != NULL) { diff --git a/src/states/GameStateRelaxed.cpp b/src/states/GameStateRelaxed.cpp index 33d7fb0..be76519 100644 --- a/src/states/GameStateRelaxed.cpp +++ b/src/states/GameStateRelaxed.cpp @@ -1,8 +1,10 @@ #include "GameStateRelaxed.hpp" +#include "../utils.hpp" + GameStateRelaxed::GameStateRelaxed(SDL_Renderer * renderer, FontManager * fonts, SoundManager * sounds, OptionManager * options) : theme(renderer, options, Theme::NONE), - pause_screen(renderer, fonts, options, "Game Paused", "press the confirm button to exit") + pause_screen(renderer, fonts, options, _("Game Paused"), _("press the confirm button to exit")) { this->renderer = renderer; this->fonts = fonts; diff --git a/src/states/HighscoreState.cpp b/src/states/HighscoreState.cpp index 7fa81ae..c454eca 100644 --- a/src/states/HighscoreState.cpp +++ b/src/states/HighscoreState.cpp @@ -3,18 +3,19 @@ #include "../constants.hpp" #include "../colors.hpp" #include "../FontType.hpp" +#include "../utils.hpp" #include "GameState.hpp" HighscoreState::HighscoreState(SDL_Renderer * renderer, FontManager * fonts, SoundManager * sounds, OptionManager * options) : renderer(renderer), fonts(fonts), sounds(sounds), options(options), theme(renderer, options, Theme::MENU) { - this->text_title = fonts->getTexture(renderer, "High Scores", FontType::TITLE, {COLOR_MENU_TITLE.r, COLOR_MENU_TITLE.g, COLOR_MENU_TITLE.b, COLOR_MENU_TITLE.a}); - this->text_bottom = fonts->getTexture(renderer, "press confirm to go back", FontType::NORMAL, {255, 255, 255, 255}); + this->text_title = fonts->getTexture(renderer, _("High Scores"), FontType::TITLE, {COLOR_MENU_TITLE.r, COLOR_MENU_TITLE.g, COLOR_MENU_TITLE.b, COLOR_MENU_TITLE.a}); + this->text_bottom = fonts->getTexture(renderer, _("press confirm to go back"), FontType::NORMAL, {255, 255, 255, 255}); - std::string standard_mode_completed = options->getStandardModeCompleted() ? "yes" : "no"; - texts.push_back(fonts->getTexture(renderer, "standard mode completed: " + standard_mode_completed, FontType::NORMAL, {255, 255, 255, 255})); - texts.push_back(fonts->getTexture(renderer, "highest level reached in challenge mode: " + std::to_string(options->getChallengeModeHighscore()), FontType::NORMAL, {255, 255, 255, 255})); - texts.push_back(fonts->getTexture(renderer, "matches in relaxed mode: " + std::to_string(options->getRelaxedModeScore()), FontType::NORMAL, {255, 255, 255, 255})); + std::string standard_mode_completed = options->getStandardModeCompleted() ? _("yes") : _("no"); + texts.push_back(fonts->getTexture(renderer, _("standard mode completed: ") + standard_mode_completed, FontType::NORMAL, {255, 255, 255, 255})); + texts.push_back(fonts->getTexture(renderer, _("highest level reached in challenge mode: ") + std::to_string(options->getChallengeModeHighscore()), FontType::NORMAL, {255, 255, 255, 255})); + texts.push_back(fonts->getTexture(renderer, _("matches in relaxed mode: ") + std::to_string(options->getRelaxedModeScore()), FontType::NORMAL, {255, 255, 255, 255})); this->text_start_y = getTextY(0); } diff --git a/src/states/MenuState.cpp b/src/states/MenuState.cpp index 2d4a1f6..668c3e1 100644 --- a/src/states/MenuState.cpp +++ b/src/states/MenuState.cpp @@ -3,6 +3,7 @@ #include "../constants.hpp" #include "../colors.hpp" #include "../FontType.hpp" +#include "../utils.hpp" #include "GameState.hpp" MenuState::MenuState(SDL_Renderer * renderer, FontManager * fonts, SoundManager * sounds, OptionManager * options) : renderer(renderer), fonts(fonts), sounds(sounds), options(options), @@ -15,25 +16,25 @@ MenuState::MenuState(SDL_Renderer * renderer, FontManager * fonts, SoundManager std::string option_sub_text; switch ((State) i) { case State::STANDARD: - option_text = "standard mode"; - option_sub_text = "play pre-made levels"; + option_text = _("standard mode"); + option_sub_text = _("play pre-made levels"); break; case State::CHALLENGE: - option_text = "challenge mode"; - option_sub_text = "ends only when lives run out"; + option_text = _("challenge mode"); + option_sub_text = _("ends only when lives run out"); break; case State::RELAXED: - option_text = "relaxed mode"; - option_sub_text = "match without consequences"; + option_text = _("relaxed mode"); + option_sub_text = _("match without consequences"); break; case State::HIGHSCORES: - option_text = "high scores"; + option_text = _("high scores"); break; case State::OPTIONS: - option_text = "options"; + option_text = _("options"); break; case State::EXIT: - option_text = "exit"; + option_text = _("exit"); break; default: option_text = "?????????"; diff --git a/src/states/NotImplementedState.cpp b/src/states/NotImplementedState.cpp index 1ef35d1..0796f3b 100644 --- a/src/states/NotImplementedState.cpp +++ b/src/states/NotImplementedState.cpp @@ -1,8 +1,10 @@ #include "NotImplementedState.hpp" +#include "../utils.hpp" + NotImplementedState::NotImplementedState(SDL_Renderer * renderer, FontManager * fonts, SoundManager * sounds, OptionManager * options) : theme(renderer, options, Theme::MENU), - screen_text(renderer, fonts, options, "Not Yet Implemented", "press the confirm button to continue") + screen_text(renderer, fonts, options, _("Not Yet Implemented"), _("press the confirm button to continue")) { this->renderer = renderer; this->fonts = fonts; diff --git a/src/states/OptionsState.cpp b/src/states/OptionsState.cpp index 7ece9bf..553efcd 100644 --- a/src/states/OptionsState.cpp +++ b/src/states/OptionsState.cpp @@ -149,7 +149,7 @@ void OptionsState::draw(SDL_Renderer * renderer) { } std::string OptionsState::getSoundVolumeString() { - std::string result = "sound volume: "; + std::string result = _("sound volume: "); for (int i = 0; i < this->options->getSoundVolume(); i++) { result += "|"; @@ -159,7 +159,7 @@ std::string OptionsState::getSoundVolumeString() { } std::string OptionsState::getMusicVolumeString() { - std::string result = "music volume: "; + std::string result = _("music volume: "); for (int i = 0; i < this->options->getMusicVolume(); i++) { result += "|"; @@ -169,15 +169,15 @@ std::string OptionsState::getMusicVolumeString() { } std::string OptionsState::getChangeMusicString() { - return "change music upon level switch: " + std::string(this->options->getChangeMusicOnSwitch() ? "yes" : "no"); + return _("change music upon level switch: ") + std::string(this->options->getChangeMusicOnSwitch() ? _("yes") : _("no")); } std::string OptionsState::getFullscreenString() { - return "full screen: " + std::string(this->options->getFullscreen() ? "yes" : "no"); + return _("full screen: ") + std::string(this->options->getFullscreen() ? _("yes") : _("no")); } std::string OptionsState::getResolutionString() { - std::string result = "resolution: " + std::to_string(this->options->getScreenWidth()) + "x" + std::to_string(this->options->getScreenHeight()); + std::string result = _("resolution: ") + std::to_string(this->options->getScreenWidth()) + "x" + std::to_string(this->options->getScreenHeight()); if (this->options->getScreenRefreshRate() > 0) { result += " (" + std::to_string(this->options->getScreenRefreshRate()) + " hz)"; } @@ -269,7 +269,7 @@ void OptionsState::changeResolution(int amount) { } void OptionsState::loadTexts() { - this->text_title = fonts->getTexture(this->renderer, "Options", FontType::TITLE, {COLOR_MENU_TITLE.r, COLOR_MENU_TITLE.g, COLOR_MENU_TITLE.b, COLOR_MENU_TITLE.a}); + this->text_title = fonts->getTexture(this->renderer, _("Options"), FontType::TITLE, {COLOR_MENU_TITLE.r, COLOR_MENU_TITLE.g, COLOR_MENU_TITLE.b, COLOR_MENU_TITLE.a}); for (int i = 0; i < (((int) Option::GO_BACK) + 1); i++) { std::string current_text; @@ -292,7 +292,7 @@ void OptionsState::loadTexts() { break; #endif case Option::GO_BACK: - current_text = "return to menu"; + current_text = _("return to menu"); break; default: current_text = "?????????"; diff --git a/src/states/WonState.cpp b/src/states/WonState.cpp index 22ed5d7..7425ae1 100644 --- a/src/states/WonState.cpp +++ b/src/states/WonState.cpp @@ -1,8 +1,10 @@ #include "WonState.hpp" +#include "../utils.hpp" + WonState::WonState(SDL_Renderer * renderer, FontManager * fonts, SoundManager * sounds, OptionManager * options) : theme(renderer, options, Theme::MENU), - screen_text(renderer, fonts, options, "Game Mode Completed!", "press the confirm button to exit") + screen_text(renderer, fonts, options, _("Game Mode Completed!"), _("press the confirm button to exit")) { this->renderer = renderer; this->fonts = fonts; diff --git a/src/utils.hpp b/src/utils.hpp index 62b198c..49d365c 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -6,6 +6,8 @@ #include #include +#include "TranslationManager.hpp" + struct DisplayMode { int width; @@ -24,4 +26,11 @@ std::string getResourcePath(std::string file); SDL_DisplayMode getStandardDisplayMode(); std::vector getDisplayModes(); +#ifdef TRANSLATION_SUPPORT + extern TranslationManager translation_manager; + #define _(x) translation_manager.translate(x) +#else + #define _(x) x +#endif + #endif // UTILS_HPP