Skip to content

Commit

Permalink
Initial support for translation in code and build system
Browse files Browse the repository at this point in the history
  • Loading branch information
sharkwouter committed Jul 18, 2024
1 parent 63894cb commit d31b88c
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 24 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*.lo
*.o
*.obj
*.mo

# Precompiled Headers
*.gch
Expand Down
27 changes: 23 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.20)

if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
message(FATAL_ERROR "Please create a build directory. Building inside the oceanpop directory directly would prevent the asset directory from being build correctly.")
Expand Down Expand Up @@ -31,7 +31,6 @@ pkg_search_module(SDL2_IMAGE REQUIRED SDL2_image)
pkg_search_module(SDL2_MIXER REQUIRED SDL2_mixer)
pkg_search_module(SDL2_TTF REQUIRED SDL2_ttf)
pkg_search_module(JSONCPP REQUIRED jsoncpp)
pkg_search_module(TINYGETTEXT REQUIRED tinygettext)


# Link libraries
Expand All @@ -43,7 +42,6 @@ if(BUILD_STATIC)
${SDL2_MIXER_STATIC_LIBRARIES}
${SDL2_TTF_STATIC_LIBRARIES}
${JSONCPP_STATIC_LIBRARIES}
${TINYGETTEXT_STATIC_LIBRARIES}
)
else()
target_link_libraries(${PROJECT_NAME} PRIVATE
Expand All @@ -52,7 +50,6 @@ else()
${SDL2_MIXER_LIBRARIES}
${SDL2_TTF_LIBRARIES}
${JSONCPP_LIBRARIES}
${TINYGETTEXT_LIBRARIES}
)
endif()

Expand All @@ -65,13 +62,30 @@ 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")
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")
Expand Down Expand Up @@ -102,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
Expand Down
55 changes: 55 additions & 0 deletions assets/languages/nl.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# 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 <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-18 11:01+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/states/MenuState.cpp:22
msgid "challenge mode"
msgstr "uitdagingsmodus"

#: src/states/MenuState.cpp:23
msgid "ends only when lives run out"
msgstr "eindigt alleen als je levens op zijn"

#: src/states/MenuState.cpp:36
msgid "exit"
msgstr "stoppen"

#: src/states/MenuState.cpp:30
msgid "high scores"
msgstr "resultaten"

#: src/states/MenuState.cpp:27
msgid "match without consequences"
msgstr "match zonder consequenties"

#: src/states/MenuState.cpp:33
msgid "options"
msgstr "opties"

#: src/states/MenuState.cpp:19
msgid "play pre-made levels"
msgstr "speel voorgeprogrammeerde levels"

#: src/states/MenuState.cpp:26
msgid "relaxed mode"
msgstr "relaxmodus"

#: src/states/MenuState.cpp:18
msgid "standard mode"
msgstr "standardmodus"
53 changes: 43 additions & 10 deletions src/TranslationManager.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#ifdef TRANSLATION_SUPPORT

#include "TranslationManager.hpp"

#include <iostream>
Expand All @@ -21,22 +23,53 @@ TranslationManager::~TranslationManager() {
}

void TranslationManager::loadTranslations() {
std::string system_language = getSystemLanguage();
std::string language_dir = getResourcePath("assets/languages/");

dictionary_manager.add_directory(language_dir);
tinygettext::Language language = tinygettext::Language::from_name(system_language);
if (language) {
dictionary_manager.set_language(language);
} else {
SDL_Log("Couldn't load language %s", system_language.c_str());


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::string TranslationManager::getSystemLanguage() {
return "";
std::vector<std::string> TranslationManager::getSystemLanguageList() {
std::vector<std::string> locales;

#include <locale.h>
char * locale_c_str = setlocale(LC_ALL, "");
if (locale_c_str != NULL){
std::string locale(locale_c_str);
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) {
return dictionary_manager.get_dictionary().translate(input);
if (language_set) {
return dictionary_manager.get_dictionary().translate(input);
} else {
return input;
}
}

#endif // TRANSLATION_SUPPORT
6 changes: 5 additions & 1 deletion src/TranslationManager.hpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
#ifndef TRANSLATIONMANAGER_H
#define TRANSLATIONMANAGER_H

#ifdef TRANSLATION_SUPPORT
#include <vector>

#include <tinygettext/tinygettext.hpp>

class TranslationManager {
private:
tinygettext::DictionaryManager dictionary_manager;
bool language_set = false;

std::string getSystemLanguage();
std::vector<std::string> getSystemLanguageList();
void loadTranslations();

public:
Expand All @@ -17,5 +20,6 @@ class TranslationManager {

std::string translate(std::string input);
};
#endif

#endif // TRANSLATIONMANAGER_H
6 changes: 6 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
19 changes: 10 additions & 9 deletions src/states/MenuState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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 = "?????????";
Expand Down
9 changes: 9 additions & 0 deletions src/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <vector>
#include <string>

#include "TranslationManager.hpp"

struct DisplayMode
{
int width;
Expand All @@ -24,4 +26,11 @@ std::string getResourcePath(std::string file);
SDL_DisplayMode getStandardDisplayMode();
std::vector<SDL_DisplayMode> getDisplayModes();

#ifdef TRANSLATION_SUPPORT
extern TranslationManager translation_manager;
#define _(x) translation_manager.translate(x)
#else
#define _(x) x
#endif

#endif // UTILS_HPP

0 comments on commit d31b88c

Please sign in to comment.