From 97b8005051621e49d78700f215d5794aca64eaed Mon Sep 17 00:00:00 2001 From: Maschell Date: Fri, 14 Apr 2017 13:10:57 +0200 Subject: [PATCH] Intial languages support and clean up - Initial support for multiple languages (Currenty there is no option to set a language) - Added language files for english and german - Deleted not used resources --- Makefile | 1 + data/images/settingButton.png | Bin 14236 -> 0 bytes data/images/settingSelectedButton.png | Bin 14236 -> 0 bytes data/images/twittergithub.png | Bin 9722 -> 0 bytes languages/english.lang | 316 ++++++++++++++++++++ languages/german.lang | 255 ++++++++++++++++ src/Application.cpp | 3 + src/controller_patcher | 2 +- src/language/gettext.cpp | 283 ++++++++++++++++++ src/language/gettext.h | 39 +++ src/main.cpp | 2 + src/menu/InputGetterMenu.cpp | 15 +- src/menu/InputGetterMenu.h | 1 + src/menu/drc/MainWindowContent.cpp | 4 +- src/menu/drc/MainWindowContent.h | 1 + src/menu/drc/MainWindowDRC.cpp | 3 +- src/menu/drc/MainWindowDRC.h | 1 + src/menu/drc/MenuElement.h | 1 + src/menu/drc/MenuElementController.cpp | 8 +- src/menu/drc/MenuElementController.h | 1 + src/menu/drc/MenuElementInfo.h | 1 + src/menu/drc/MenuListDRC.cpp | 12 +- src/menu/drc/MenuListDRC.h | 1 + src/menu/drc/content/ContentAbout.h | 1 + src/menu/drc/content/ContentController.cpp | 31 +- src/menu/drc/content/ContentController.h | 1 + src/menu/drc/content/ContentHelp.cpp | 26 +- src/menu/drc/content/ContentHelp.h | 1 + src/menu/drc/content/ContentHome.cpp | 8 +- src/menu/drc/content/ContentHome.h | 1 + src/menu/drc/content/ContentNetworkHelp.cpp | 34 +-- src/menu/drc/content/ContentNetworkHelp.h | 1 + src/menu/drc/content/ContentTemplate.h | 2 - src/menu/tv/TVButtonController.cpp | 8 +- src/menu/tv/TVButtonController.h | 1 + src/menu/tv/TVControllerBanner.cpp | 4 +- src/resources/filelist.h | 14 +- updatelang.sh | 9 + 38 files changed, 1000 insertions(+), 92 deletions(-) delete mode 100644 data/images/settingButton.png delete mode 100644 data/images/settingSelectedButton.png delete mode 100644 data/images/twittergithub.png create mode 100644 languages/english.lang create mode 100644 languages/german.lang create mode 100644 src/language/gettext.cpp create mode 100644 src/language/gettext.h create mode 100644 updatelang.sh diff --git a/Makefile b/Makefile index f206a0e..fb9a117 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ SOURCES := src \ src/game \ src/gui \ src/kernel \ + src/language \ src/menu \ src/menu/tv \ src/menu/drc \ diff --git a/data/images/settingButton.png b/data/images/settingButton.png deleted file mode 100644 index ae07542da7d8f00faf0db31ac6d77b7e3f6b1dcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14236 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%0DHJt6c@q|g&tvrPd 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%0DHJt6c@q|g&tvrPd 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, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-04-13 18:55+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/menu/drc/content/ContentController.cpp:29 +#: src/menu/drc/content/ContentController.cpp:29 +msgid "Currently no device is connected." +msgstr "" + +#: src/menu/drc/content/ContentController.cpp:33 +#: src/menu/drc/content/ContentController.cpp:33 +msgid "Device connected. You can test it by pressing buttons." +msgstr "" + +#: src/menu/drc/content/ContentController.cpp:34 +#: src/menu/drc/content/ContentController.cpp:34 +msgid "Press A to remap to a new controller." +msgstr "" + +#: src/menu/drc/content/ContentController.cpp:35 +#: src/menu/drc/content/ContentController.cpp:35 +msgid "Mouse connected. You can test it by pressing buttons." +msgstr "" + +#: src/menu/drc/content/ContentController.cpp:36 +#: src/menu/drc/content/ContentController.cpp:36 +msgid "Keyboard connected. You can test it by pressing buttons." +msgstr "" + +#: src/menu/drc/content/ContentController.cpp:37 +#: src/menu/drc/content/ContentController.cpp:37 +msgid "Press X to add a Keyboard." +msgstr "" + +#: src/menu/drc/content/ContentController.cpp:38 +#: src/menu/drc/content/ContentController.cpp:38 +msgid "Press X to add a Mouse." +msgstr "" + +#: src/menu/drc/content/ContentController.cpp:39 +#: src/menu/drc/content/ContentController.cpp:39 +msgid "Keyboard connected." +msgstr "" + +#: src/menu/drc/content/ContentController.cpp:40 +#: src/menu/drc/content/ContentController.cpp:40 +msgid "Mouse connected." +msgstr "" + +#: src/menu/drc/content/ContentController.cpp:51 +#: src/menu/drc/content/ContentController.cpp:51 +msgid "Press A to map a controller to " +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:20 src/menu/drc/MenuListDRC.cpp:40 +#: src/menu/drc/content/ContentHelp.cpp:20 src/menu/drc/MenuListDRC.cpp:40 +msgid "Help" +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:39 +#: src/menu/drc/content/ContentHelp.cpp:39 +msgid "My controller is not working!" +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:46 +#: src/menu/drc/content/ContentHelp.cpp:46 +msgid "Make sure you have a valid config in the folder \"sd:/wiiu/controller\"" +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:54 +#: src/menu/drc/content/ContentHelp.cpp:54 +msgid "Where do I get the config files from?" +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:61 +#: src/menu/drc/content/ContentHelp.cpp:61 +msgid "You can create them by yourself or download them from " +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:69 +#: src/menu/drc/content/ContentHelp.cpp:69 +msgid "https://github.com/Maschell/controller_patcher_configs" +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:76 +#: src/menu/drc/content/ContentHelp.cpp:76 +msgid "I have no idea how create a own config!" +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:83 +#: src/menu/drc/content/ContentHelp.cpp:83 +msgid "You're lucky! There a whole wiki about creating them:" +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:97 +#: src/menu/drc/content/ContentHelp.cpp:97 +msgid "XYZ is not working!" +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:104 +#: src/menu/drc/content/ContentHelp.cpp:104 +msgid "If you find a bug, please open an issue on github" +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:111 +#: src/menu/drc/content/ContentHelp.cpp:111 +msgid "Could you add feature XYZ? Please!" +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:118 +#: src/menu/drc/content/ContentHelp.cpp:118 +msgid "Maybe.It depends on the request, I can't promise anything." +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:124 +#: src/menu/drc/content/ContentHelp.cpp:124 +msgid "Just open an issue and I'll try to do my best." +msgstr "" + +#: src/menu/drc/content/ContentHome.cpp:22 +#: src/menu/drc/content/ContentHome.cpp:22 +msgid "Welcome to HID to VPAD!" +msgstr "" + +#: src/menu/drc/content/ContentHome.cpp:23 +#: src/menu/drc/content/ContentHome.cpp:23 +msgid "" +"HID to VPAD allows you to use your USB controller on your WiiU. Currently " +"you can emulate the Gamepad or a Pro Controller." +msgstr "" + +#: src/menu/drc/content/ContentHome.cpp:24 +#: src/menu/drc/content/ContentHome.cpp:24 +msgid "" +"Before you use your controller, you may need to provide a valid config. More " +"information and config files can be found in the help section or on gbatemp." +"net (gbatemp.net/threads/424127/)." +msgstr "" + +#: src/menu/drc/content/ContentHome.cpp:25 +#: src/menu/drc/content/ContentHome.cpp:25 +msgid "" +"To map a device, select a controller from the list on the left hand side." +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:20 +#: src/menu/drc/MenuListDRC.cpp:41 +#: src/menu/drc/content/ContentNetworkHelp.cpp:20 +#: src/menu/drc/MenuListDRC.cpp:41 +msgid "Network Client" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:39 +#: src/menu/drc/content/ContentNetworkHelp.cpp:39 +msgid "What is the Network Client?" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:46 +#: src/menu/drc/content/ContentNetworkHelp.cpp:46 +msgid "It allows you to use your controller connected to your Computer with" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:54 +#: src/menu/drc/content/ContentNetworkHelp.cpp:54 +msgid "HID to VPAD. This way for example XInput- and HID-Bluetooth-Devices" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:61 +#: src/menu/drc/content/ContentNetworkHelp.cpp:61 +msgid "can be used. It connects to your console over your local network." +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:68 +#: src/menu/drc/content/ContentNetworkHelp.cpp:68 +msgid "How do I use it?" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:75 +#: src/menu/drc/content/ContentNetworkHelp.cpp:75 +msgid "Enter the IP (upper right corner!) of your console and press connect." +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:82 +#: src/menu/drc/content/ContentNetworkHelp.cpp:82 +msgid "If everything worked correctly, use the controller just like one" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:89 +#: src/menu/drc/content/ContentNetworkHelp.cpp:89 +msgid "connected via USB. You can find a detailed guide here:" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:96 +#: src/menu/drc/content/ContentNetworkHelp.cpp:96 +msgid "http://gbatemp.net/threads/hid-to-vpad.424127/" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:105 +#: src/menu/drc/content/ContentNetworkHelp.cpp:105 +msgid "Is there any input lag?" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:112 +#: src/menu/drc/content/ContentNetworkHelp.cpp:112 +msgid "With a connection via Ethernet, you shouldn't notice any lag." +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:119 +#: src/menu/drc/content/ContentNetworkHelp.cpp:119 +msgid "Wi-Fi may lead to some issues or lag, but it heavily depends on the" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:126 +#: src/menu/drc/content/ContentNetworkHelp.cpp:126 +msgid "" +"quality of your signal. If it's possible, connect everything via Ethernet." +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:133 +#: src/menu/drc/content/ContentNetworkHelp.cpp:133 +msgid "Where can I get it?" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:140 +#: src/menu/drc/content/ContentNetworkHelp.cpp:140 +msgid "It's open source and you can find it here: " +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:147 +#: src/menu/drc/content/ContentNetworkHelp.cpp:147 +msgid "https://github.com/QuarkTheAwesome/HIDtoVPADNetworkClient" +msgstr "" + +#: src/menu/drc/MainWindowContent.cpp:28 src/menu/drc/MainWindowContent.cpp:28 +msgid "Exit to HBL " +msgstr "" + +#: src/menu/drc/MainWindowContent.cpp:31 src/menu/drc/MainWindowContent.cpp:31 +msgid "Apply Patches" +msgstr "" + +#: src/menu/drc/MainWindowDRC.cpp:48 src/menu/drc/MainWindowDRC.cpp:48 +msgid "TCP Server running on: " +msgstr "" + +#: src/menu/drc/MenuElementController.cpp:43 +#: src/menu/drc/MenuElementController.cpp:43 +msgid "Nothing attached" +msgstr "" + +#: src/menu/drc/MenuElementController.cpp:160 +#: src/menu/tv/TVButtonController.cpp:38 +#: src/menu/tv/TVButtonController.cpp:172 +#: src/menu/drc/MenuElementController.cpp:160 +#: src/menu/tv/TVButtonController.cpp:38 +#: src/menu/tv/TVButtonController.cpp:172 +msgid "No device" +msgstr "" + +#: src/menu/drc/MenuElementController.cpp:169 +#: src/menu/tv/TVButtonController.cpp:181 +#: src/menu/drc/MenuElementController.cpp:169 +#: src/menu/tv/TVButtonController.cpp:181 +msgid "Real Pro Controller" +msgstr "" + +#: src/menu/drc/MenuElementController.cpp:171 +#: src/menu/tv/TVButtonController.cpp:183 +#: src/menu/drc/MenuElementController.cpp:171 +#: src/menu/tv/TVButtonController.cpp:183 +msgid "Mouse / Keyboard" +msgstr "" + +#: src/menu/drc/MenuListDRC.cpp:31 src/menu/drc/MenuListDRC.cpp:32 +#: src/menu/drc/MenuListDRC.cpp:31 src/menu/drc/MenuListDRC.cpp:32 +msgid "Home" +msgstr "" + +#: src/menu/drc/MenuListDRC.cpp:39 src/menu/drc/MenuListDRC.cpp:39 +msgid "Other" +msgstr "" + +#: src/menu/drc/MenuListDRC.cpp:42 src/menu/drc/MenuListDRC.cpp:42 +msgid "About" +msgstr "" + +#: src/menu/InputGetterMenu.cpp:34 src/menu/InputGetterMenu.cpp:34 +msgid "Press any button on the USB-Controller you want to use." +msgstr "" + +#: src/menu/InputGetterMenu.cpp:35 src/menu/InputGetterMenu.cpp:35 +msgid "Press B to disable the mapping" +msgstr "" + +#: src/menu/tv/TVControllerBanner.cpp:41 src/menu/tv/TVControllerBanner.cpp:41 +msgid "Press to return to HBL" +msgstr "" + +#: src/menu/tv/TVControllerBanner.cpp:44 src/menu/tv/TVControllerBanner.cpp:44 +msgid "Press to apply patches" +msgstr "" diff --git a/languages/german.lang b/languages/german.lang new file mode 100644 index 0000000..009aed3 --- /dev/null +++ b/languages/german.lang @@ -0,0 +1,255 @@ +# German translations for PACKAGE package. +# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-04-13 18:11+0200\n" +"PO-Revision-Date: 2017-04-13 16:51+0200\n" +"Last-Translator: \n" +"Language-Team: German\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/menu/drc/content/ContentController.cpp:29 +msgid "Currently no device is connected." +msgstr "Derzeit ist kein Controller verbunden." + +#: src/menu/drc/content/ContentController.cpp:33 +msgid "Device connected. You can test it by pressing buttons." +msgstr "Controller verbunden. Drücke Tasten um ihn zu testen." + +#: src/menu/drc/content/ContentController.cpp:34 +msgid "Press A to remap to a new controller." +msgstr "Drücke A um einen neuen Controller zu setzen." + +#: src/menu/drc/content/ContentController.cpp:35 +msgid "Mouse connected. You can test it by pressing buttons." +msgstr "Maus verbunden. Drücke eine Taste um sie zu testen." + +#: src/menu/drc/content/ContentController.cpp:36 +msgid "Keyboard connected. You can test it by pressing buttons." +msgstr "Tastatur verbunden. Drücke eine Taste um sie zu testen." + +#: src/menu/drc/content/ContentController.cpp:37 +msgid "Press X to add a Keyboard." +msgstr "Drücke X um eine Tastatur hinzufügen." + +#: src/menu/drc/content/ContentController.cpp:38 +msgid "Press X to add a Mouse." +msgstr "Drücke X um eine Maus hinzufügen." + +#: src/menu/drc/content/ContentController.cpp:39 +msgid "Keyboard connected." +msgstr "Tastatur verbunden." + +#: src/menu/drc/content/ContentController.cpp:40 +msgid "Mouse connected." +msgstr "Maus verbunden." + +#: src/menu/drc/content/ContentController.cpp:51 +msgid "Press A to map a controller to " +msgstr "Drücke A um einen Controller festzulegen für " + +#: src/menu/drc/content/ContentHelp.cpp:20 src/menu/drc/MenuListDRC.cpp:40 +msgid "Help" +msgstr "Hilfe" + +#: src/menu/drc/content/ContentHelp.cpp:39 +msgid "My controller is not working!" +msgstr "Mein Controller funktioniert nicht!" + +#: src/menu/drc/content/ContentHelp.cpp:46 +msgid "Make sure you have a valid config in the folder \"sd:/wiiu/controller\"" +msgstr "Sei dir sicher, dass eine gültige Config im Ordner \"sd:/wiiu/controller\" ist" + +#: src/menu/drc/content/ContentHelp.cpp:54 +msgid "Where do I get the config files from?" +msgstr "Wo bekomme ich Configs her?" + +#: src/menu/drc/content/ContentHelp.cpp:61 +msgid "You can create them by yourself or download them from " +msgstr "Du kannst sie selbst erstellen oder hier runterladen:" + +#: src/menu/drc/content/ContentHelp.cpp:69 +msgid "https://github.com/Maschell/controller_patcher_configs" +msgstr "" + +#: src/menu/drc/content/ContentHelp.cpp:76 +msgid "I have no idea how create a own config!" +msgstr "Wie erstelle ich selbst eine?" + +#: src/menu/drc/content/ContentHelp.cpp:83 +msgid "You're lucky! There a whole wiki about creating them:" +msgstr "Du hast Glück! Es gibt ein Wiki mit allen Informationen." + +#: src/menu/drc/content/ContentHelp.cpp:97 +msgid "XYZ is not working!" +msgstr "XYZ funktioniert nicht." + +#: src/menu/drc/content/ContentHelp.cpp:104 +msgid "If you find a bug, please open an issue on github" +msgstr "Wenn du einen Fehler findest, eröffnet bitte ein Issue auf Github" + +#: src/menu/drc/content/ContentHelp.cpp:111 +msgid "Could you add feature XYZ? Please!" +msgstr "Ist Feature XYZ möglick? BITTE!" + +#: src/menu/drc/content/ContentHelp.cpp:118 +msgid "Maybe.It depends on the request, I can't promise anything." +msgstr "Vielleicht. Es kommt drauf an, ich kann nichts versprechen." + +#: src/menu/drc/content/ContentHelp.cpp:124 +msgid "Just open an issue and I'll try to do my best." +msgstr "Eröffne ein Issue und vielleicht kann ich helfen." + +#: src/menu/drc/content/ContentHome.cpp:22 +msgid "Welcome to HID to VPAD!" +msgstr "Willkommen zu HID to VPAD!" + +#: src/menu/drc/content/ContentHome.cpp:23 +msgid "HID to VPAD allows you to use your USB controller on your WiiU. Currently you can emulate the Gamepad or a Pro Controller." +msgstr "HID to VPAD erlaubt es dir deine USB-Controller auf deiner WiiU als Gamepad oder Pro Controller zu nutzen." + +#: src/menu/drc/content/ContentHome.cpp:24 +msgid "Before you use your controller, you may need to provide a valid config. More information and config files can be found in the help section or on gbatemp.net (gbatemp.net/threads/424127/)." +msgstr "Bevor du eigene Controller verwenden kannst, brauchst du möglicherweise eine Config. Informationen findest du unter Hilfe oder auf gbatemp (gbatemp.net/threads/424127/)." + +#: src/menu/drc/content/ContentHome.cpp:25 +msgid "To map a device, select a controller from the list on the left hand side." +msgstr "Wähle links einen Controller aus um fortzufahren." + +#: src/menu/drc/content/ContentNetworkHelp.cpp:20 +#: src/menu/drc/MenuListDRC.cpp:41 +msgid "Network Client" +msgstr "Network Client" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:39 +msgid "What is the Network Client?" +msgstr "Was ist der Netzwerk Client?" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:46 +msgid "It allows you to use your controller connected to your Computer with" +msgstr "Er erlaubt es dir Controller von deinem PC mit deiner WiiU zu " + +#: src/menu/drc/content/ContentNetworkHelp.cpp:54 +msgid "HID to VPAD. This way for example XInput- and HID-Bluetooth-Devices" +msgstr "verbinden. So können XInput- and HID-Bluetooth-Geräte verwendet" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:61 +msgid "can be used. It connects to your console over your local network." +msgstr "werden. Es verbindet sich über dein Lokales Netzwerk." + +#: src/menu/drc/content/ContentNetworkHelp.cpp:68 +msgid "How do I use it?" +msgstr "Wie verwendet ich es?" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:75 +msgid "Enter the IP (upper right corner!) of your console and press connect." +msgstr "Gib die IP deiner Konsole ein und drück auf Connect. Wenn alles" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:82 +msgid "If everything worked correctly, use the controller just like one" +msgstr "geklappt hat, kannst den Controller nun so nutzen als " + +#: src/menu/drc/content/ContentNetworkHelp.cpp:89 +msgid "connected via USB. You can find a detailed guide here:" +msgstr "wäre er per USB verbunden. Weitere hilfe erhälst du hier:" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:96 +msgid "http://gbatemp.net/threads/hid-to-vpad.424127/" +msgstr "" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:105 +msgid "Is there any input lag?" +msgstr "Gibt es Input-Lag?" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:112 +msgid "With a connection via Ethernet, you shouldn't notice any lag." +msgstr "Bei einer Verbindung per Lan-Label sollte es keinen Lag geben." + +#: src/menu/drc/content/ContentNetworkHelp.cpp:119 +msgid "Wi-Fi may lead to some issues or lag, but it heavily depends on the" +msgstr "W-Lan kann unter umständen zu Problemen führen, es kommt aber" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:126 +msgid "quality of your signal. If it's possible, connect everything via Ethernet." +msgstr "auf das Signal an. Wenn möglich, nutze einen Lan-Adapter." + +#: src/menu/drc/content/ContentNetworkHelp.cpp:133 +msgid "Where can I get it?" +msgstr "Wo bekomme ich ihn her?" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:140 +msgid "It's open source and you can find it here: " +msgstr "Es ist Open-Source und kann hier geladen werden:" + +#: src/menu/drc/content/ContentNetworkHelp.cpp:147 +msgid "https://github.com/QuarkTheAwesome/HIDtoVPADNetworkClient" +msgstr "" + +#: src/menu/drc/MainWindowContent.cpp:28 +msgid "Exit to HBL " +msgstr "Zurück zum HBL" + +#: src/menu/drc/MainWindowContent.cpp:31 +msgid "Apply Patches" +msgstr "System Menu" + +#: src/menu/drc/MainWindowDRC.cpp:48 +msgid "TCP Server running on: " +msgstr "TCP Server erreichbar:" + +#: src/menu/drc/MenuElementController.cpp:43 +msgid "Nothing attached" +msgstr "Nichts verbunden" + +#: src/menu/drc/MenuElementController.cpp:160 +#: src/menu/tv/TVButtonController.cpp:38 +#: src/menu/tv/TVButtonController.cpp:172 +msgid "No device" +msgstr "Kein Controller" + +#: src/menu/drc/MenuElementController.cpp:169 +#: src/menu/tv/TVButtonController.cpp:181 +msgid "Real Pro Controller" +msgstr "Echter Pro Controller" + +#: src/menu/drc/MenuElementController.cpp:171 +#: src/menu/tv/TVButtonController.cpp:183 +msgid "Mouse / Keyboard" +msgstr "Maus / Tastatur" + +#: src/menu/drc/MenuListDRC.cpp:31 src/menu/drc/MenuListDRC.cpp:32 +msgid "Home" +msgstr "Home" + +#: src/menu/drc/MenuListDRC.cpp:39 +msgid "Other" +msgstr "Sonstiges" + +#: src/menu/drc/MenuListDRC.cpp:42 +msgid "About" +msgstr "About" + +#: src/menu/InputGetterMenu.cpp:34 +msgid "Press any button on the USB-Controller you want to use." +msgstr "Drücke eine Taste auf dem Controller den du nutzen möchstest." + +#: src/menu/InputGetterMenu.cpp:35 +msgid "Press B to disable the mapping" +msgstr "Drücke B um die Verbindung zu trennen" + +#: src/menu/tv/TVControllerBanner.cpp:41 +msgid "Press to return to HBL" +msgstr " zurück zum HBL." + +#: src/menu/tv/TVControllerBanner.cpp:44 +msgid "Press to apply patches" +msgstr "Drücke zum starten." diff --git a/src/Application.cpp b/src/Application.cpp index 96c5965..4027cc3 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -44,6 +44,9 @@ Application::Application() //! create bgMusic bgMusic = new GuiSound(Resources::GetFile("bgMusic.mp3"), Resources::GetFileSize("bgMusic.mp3")); + //std::string languagePath = "sd:/wiiu/apps/hidtovpad/languages/english.lang"; + //gettextLoadLanguage(languagePath.c_str()); + exitApplication = false; } diff --git a/src/controller_patcher b/src/controller_patcher index 42fc97a..8dee7c3 160000 --- a/src/controller_patcher +++ b/src/controller_patcher @@ -1 +1 @@ -Subproject commit 42fc97a37ea624cb2719eba41a00d40e6f5e99ca +Subproject commit 8dee7c3e705ed6a292e1f1ac0e28ff46c5e83376 diff --git a/src/language/gettext.cpp b/src/language/gettext.cpp new file mode 100644 index 0000000..1a70ac0 --- /dev/null +++ b/src/language/gettext.cpp @@ -0,0 +1,283 @@ +/**************************************************************************** + * Copyright (C) 2015 Dimok + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "gettext.h" +#include "fs/CFile.hpp" +#include "utils/StringTools.h" + +typedef struct _MSG +{ + u32 id; + char* msgstr; + struct _MSG *next; +} MSG; +static MSG *baseMSG = 0; + +#define HASHWORDBITS 32 + +/* Defines the so called `hashpjw' function by P.J. Weinberger + [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, + 1986, 1987 Bell Telephone Laboratories, Inc.] */ +static inline u32 hash_string(const char *str_param) +{ + u32 hval, g; + const char *str = str_param; + + /* Compute the hash value for the given string. */ + hval = 0; + while (*str != '\0') + { + hval <<= 4; + hval += (u8) *str++; + g = hval & ((u32) 0xf << (HASHWORDBITS - 4)); + if (g != 0) + { + hval ^= g >> (HASHWORDBITS - 8); + hval ^= g; + } + } + return hval; +} + +/* Expand some escape sequences found in the argument string. */ +static char * +expand_escape(const char *str) +{ + char *retval, *rp; + const char *cp = str; + + retval = (char *) malloc(strlen(str) + 1); + if (retval == NULL) return NULL; + rp = retval; + + while (cp[0] != '\0' && cp[0] != '\\') + *rp++ = *cp++; + if (cp[0] == '\0') goto terminate; + do + { + + /* Here cp[0] == '\\'. */ + switch (*++cp) + { + case '\"': /* " */ + *rp++ = '\"'; + ++cp; + break; + case 'a': /* alert */ + *rp++ = '\a'; + ++cp; + break; + case 'b': /* backspace */ + *rp++ = '\b'; + ++cp; + break; + case 'f': /* form feed */ + *rp++ = '\f'; + ++cp; + break; + case 'n': /* new line */ + *rp++ = '\n'; + ++cp; + break; + case 'r': /* carriage return */ + *rp++ = '\r'; + ++cp; + break; + case 't': /* horizontal tab */ + *rp++ = '\t'; + ++cp; + break; + case 'v': /* vertical tab */ + *rp++ = '\v'; + ++cp; + break; + case '\\': + *rp = '\\'; + ++cp; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + int ch = *cp++ - '0'; + + if (*cp >= '0' && *cp <= '7') + { + ch *= 8; + ch += *cp++ - '0'; + + if (*cp >= '0' && *cp <= '7') + { + ch *= 8; + ch += *cp++ - '0'; + } + } + *rp = ch; + } + break; + default: + *rp = '\\'; + break; + } + + while (cp[0] != '\0' && cp[0] != '\\') + *rp++ = *cp++; + } while (cp[0] != '\0'); + + /* Terminate string. */ + terminate: *rp = '\0'; + return retval; +} + +static MSG *findMSG(u32 id) +{ + MSG *msg; + for (msg = baseMSG; msg; msg = msg->next) + { + if (msg->id == id) return msg; + } + return NULL; +} + +static MSG *setMSG(const char *msgid, const char *msgstr) +{ + u32 id = hash_string(msgid); + MSG *msg = findMSG(id); + if (!msg) + { + msg = (MSG *) malloc(sizeof(MSG)); + msg->id = id; + msg->msgstr = NULL; + msg->next = baseMSG; + baseMSG = msg; + } + if (msg) + { + if (msgstr) + { + if (msg->msgstr) free(msg->msgstr); + //msg->msgstr = strdup(msgstr); + msg->msgstr = expand_escape(msgstr); + } + return msg; + } + return NULL; +} + +extern "C" void gettextCleanUp(void) +{ + while (baseMSG) + { + MSG *nextMsg = baseMSG->next; + free(baseMSG->msgstr); + free(baseMSG); + baseMSG = nextMsg; + } +} + +extern "C" bool gettextLoadLanguage(const char* langFile) +{ + char *lastID = NULL; + gettextCleanUp(); + + CFile file(langFile, CFile::ReadOnly); + if (!file.isOpen()) + return false; + + std::string strBuffer; + strBuffer.resize(file.size()); + file.read((u8 *) &strBuffer[0], strBuffer.size()); + file.close(); + + //! remove all windows crap signs + size_t position; + while(1) + { + position = strBuffer.find('\r'); + if(position == std::string::npos) + break; + + strBuffer.erase(position, 1); + } + + std::vector lines = stringSplit(strBuffer, "\n"); + + + if(lines.empty()) + return false; + + for(unsigned int i = 0; i < lines.size(); i++) + { + std::string & line = lines[i]; + // lines starting with # are comments + if (line[0] == '#') + continue; + else if (strncmp(line.c_str(), "msgid \"", 7) == 0) + { + char *msgid, *end; + if (lastID) + { + free(lastID); + lastID = NULL; + } + msgid = &line[7]; + end = strrchr(msgid, '"'); + if (end && end - msgid > 1) + { + *end = 0; + lastID = strdup(msgid); + } + } + else if (strncmp(line.c_str(), "msgstr \"", 8) == 0) + { + char *msgstr, *end; + + if (lastID == NULL) continue; + + msgstr = &line[8]; + end = strrchr(msgstr, '"'); + if (end && end - msgstr > 1) + { + *end = 0; + setMSG(lastID, msgstr); + } + free(lastID); + lastID = NULL; + } + + } + return true; +} + +extern "C" const char *gettext(const char *msgid) +{ + if(!msgid) return NULL; + MSG *msg = findMSG(hash_string(msgid)); + if (msg && msg->msgstr) return msg->msgstr; + return msgid; +} + diff --git a/src/language/gettext.h b/src/language/gettext.h new file mode 100644 index 0000000..e1da228 --- /dev/null +++ b/src/language/gettext.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * Copyright (C) 2015 Dimok + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#ifndef _GETTEXT_H_ +#define _GETTEXT_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + + bool gettextLoadLanguage(const char* langFile); + void gettextCleanUp(void); + /* + * input msg = a text in ASCII + * output = the translated msg in utf-8 + */ + const char *gettext(const char *msg); +#define tr(s) gettext(s) +#define trNOOP(s) s + +#ifdef __cplusplus +} +#endif + +#endif /* _GETTEXT_H_ */ diff --git a/src/main.cpp b/src/main.cpp index 05982ed..2b8289a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,8 @@ #include "version.h" #include "common/common.h" +#include "language/gettext.h" + #include "controller_patcher/ControllerPatcher.hpp" #include "utils/function_patcher.h" #include "patcher/hid_controller_function_patcher.hpp" diff --git a/src/menu/InputGetterMenu.cpp b/src/menu/InputGetterMenu.cpp index 82d73fc..8db5263 100644 --- a/src/menu/InputGetterMenu.cpp +++ b/src/menu/InputGetterMenu.cpp @@ -20,6 +20,7 @@ #include "Application.h" #include "gui/GuiElement.h" #include "utils/logger.h" +#include "language/gettext.h" #include "dynamic_libs/padscore_functions.h" CThread * InputGetterMenu::pThread = NULL; @@ -30,8 +31,8 @@ InputGetterMenu::InputGetterMenu(UController_Type controller_type) , backgroundImage(backgroundImageData) , bgBlur(1280, 720, (GX2Color){0, 0, 0, 255}) , infoController("", 70, glm::vec4(0.2f, 0.2f, 0.2f, 1.0f)) - , infoText("Press any button on the USB-Controller you want to use.", 35, glm::vec4(0.3f, 0.3f, 0.3f, 1.0f)) - , infoTextreturn("Press B to disable the mapping", 55, glm::vec4(0.3f, 0.3f, 0.3f, 1.0f)) + , infoText(gettext("Press any button on the USB-Controller you want to use."), 35, glm::vec4(0.3f, 0.3f, 0.3f, 1.0f)) + , infoTextreturn(gettext("Press B to disable the mapping"), 55, glm::vec4(0.3f, 0.3f, 0.3f, 1.0f)) , buttonBTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_B, true) , DPADButtons(0,0) { @@ -42,19 +43,19 @@ InputGetterMenu::InputGetterMenu(UController_Type controller_type) gameLauncherMenuFrame = GuiFrame(width, height); std::string name; if(controller_type == UController_Type_Gamepad){ - name = "GamePad"; + name = UController_Type_Gamepad_Name; }else if(controller_type == UController_Type_Pro1){ WPADDisconnect(0); - name = "Pro Controller 1"; + name = UController_Type_Pro1_Name; }else if(controller_type == UController_Type_Pro2){ WPADDisconnect(1); - name = "Pro Controller 2"; + name = UController_Type_Pro2_Name; }else if(controller_type == UController_Type_Pro3){ WPADDisconnect(2); - name = "Pro Controller 3"; + name = UController_Type_Pro3_Name; }else if(controller_type == UController_Type_Pro4){ WPADDisconnect(3); - name = "Pro Controller 4"; + name = UController_Type_Pro4_Name; } infoController.setText(name.c_str()); diff --git a/src/menu/InputGetterMenu.h b/src/menu/InputGetterMenu.h index ebe5d76..5d2d65b 100644 --- a/src/menu/InputGetterMenu.h +++ b/src/menu/InputGetterMenu.h @@ -20,6 +20,7 @@ #include "controller_patcher/ControllerPatcher.hpp" #include "gui/Gui.h" #include "system/CThread.h" +#include "language/gettext.h" class InputGetterMenu : public GuiFrame, public sigslot::has_slots<> { diff --git a/src/menu/drc/MainWindowContent.cpp b/src/menu/drc/MainWindowContent.cpp index 271307e..bdfc93c 100644 --- a/src/menu/drc/MainWindowContent.cpp +++ b/src/menu/drc/MainWindowContent.cpp @@ -25,10 +25,10 @@ MainWindowContent::MainWindowContent(s32 w, s32 h) , footer_img(footer_imgdata) , homebutton_imgdata(Resources::GetImageData("HomeButtonIcon.png")) , homebutton_img(homebutton_imgdata) - , exitHome("Exit to HBL ") + , exitHome(gettext("Exit to HBL ")) , plusbutton_imgdata(Resources::GetImageData("PlusButtonIcon.png")) , plusbutton_img(plusbutton_imgdata) - , exitPlus("Apply Patches") + , exitPlus(gettext("Apply Patches")) { bgImageColor.setImageColor((GX2Color){ 248, 249, 248, 255 }, 0); bgImageColor.setImageColor((GX2Color){ 248, 249, 248, 255 }, 1); diff --git a/src/menu/drc/MainWindowContent.h b/src/menu/drc/MainWindowContent.h index 27fb948..1ba1526 100644 --- a/src/menu/drc/MainWindowContent.h +++ b/src/menu/drc/MainWindowContent.h @@ -21,6 +21,7 @@ #include "system/AsyncDeleter.h" #include "MainWindowContent.h" #include "content/ContentTemplate.h" +#include "language/gettext.h" class MainWindowContent : public GuiFrame, public sigslot::has_slots<>{ public: diff --git a/src/menu/drc/MainWindowDRC.cpp b/src/menu/drc/MainWindowDRC.cpp index 6db1a51..bf5f615 100644 --- a/src/menu/drc/MainWindowDRC.cpp +++ b/src/menu/drc/MainWindowDRC.cpp @@ -45,8 +45,7 @@ MainWindowDRC::MainWindowDRC(s32 w, s32 h) versionText.setText(fmt("%s - %s",APP_VERION,__DATE__)); versionText.setAlignment(ALIGN_TOP_LEFT); versionText.setPosition(windowSplitter_img.getOffsetX()+5,-25); - - ipAddress.setText(wfmt("TCP Server running on: %u.%u.%u.%u",(hostIpAddress >> 24) & 0xFF, (hostIpAddress >> 16) & 0xFF, (hostIpAddress >> 8) & 0xFF, (hostIpAddress >> 0) & 0xFF)); + ipAddress.setText(wfmt("%s%u.%u.%u.%u",gettext("TCP Server running on: "),(hostIpAddress >> 24) & 0xFF, (hostIpAddress >> 16) & 0xFF, (hostIpAddress >> 8) & 0xFF, (hostIpAddress >> 0) & 0xFF)); ipAddress.setAlignment(ALIGN_TOP_RIGHT); ipAddress.setPosition(-5,-25); append(&windowSplitter_img); diff --git a/src/menu/drc/MainWindowDRC.h b/src/menu/drc/MainWindowDRC.h index 3603b95..49c69c2 100644 --- a/src/menu/drc/MainWindowDRC.h +++ b/src/menu/drc/MainWindowDRC.h @@ -22,6 +22,7 @@ #include "MenuListDRC.h" #include "menu/MainWindow.h" #include "MainWindowContent.h" +#include "language/gettext.h" class MainWindowDRC : public GuiConfigurationScreen, public sigslot::has_slots<>{ public: diff --git a/src/menu/drc/MenuElement.h b/src/menu/drc/MenuElement.h index 89e451f..d70ad52 100644 --- a/src/menu/drc/MenuElement.h +++ b/src/menu/drc/MenuElement.h @@ -19,6 +19,7 @@ #include "gui/GuiButton.h" #include "content/ContentTemplate.h" +#include "language/gettext.h" class MenuElement : public GuiButton { diff --git a/src/menu/drc/MenuElementController.cpp b/src/menu/drc/MenuElementController.cpp index 5de9fb6..565e96a 100644 --- a/src/menu/drc/MenuElementController.cpp +++ b/src/menu/drc/MenuElementController.cpp @@ -40,7 +40,7 @@ MenuElementController::MenuElementController(UController_Type controllertype) ,gamepad_imgdata(Resources::GetImageData("gamepad.png")) ,gamepad_img(gamepad_imgdata) ,controllerlabel("") - ,notAttachedLabel("Nothing attached") + ,notAttachedLabel(gettext("Nothing attached")) ,ledon_imgdata(Resources::GetImageData("ledon.png")) ,ledoff_imgdata(Resources::GetImageData("ledoff.png")) { @@ -157,7 +157,7 @@ void MenuElementController::draw(CVideo *v){ controllerConnected = 0; s32 found = ControllerPatcher::getActiveMappingSlot(getControllerType()); if(found == -1){ - name = "No device"; + name = gettext("No device"); }else{ controllerConnected = 1; @@ -166,9 +166,9 @@ void MenuElementController::draw(CVideo *v){ if(info->type == CM_Type_Controller){ drawControllerName(v,info->vidpid.vid,info->vidpid.pid); }else if(info->type == CM_Type_RealController){ - name = "Real Pro Controller"; + name = gettext("Real Pro Controller"); }else if(info->type == CM_Type_Mouse || info->type == CM_Type_Keyboard){ - name = "Mouse / Keyboard"; + name = gettext("Mouse / Keyboard"); } } } diff --git a/src/menu/drc/MenuElementController.h b/src/menu/drc/MenuElementController.h index cbf5ff6..0c9f4b1 100644 --- a/src/menu/drc/MenuElementController.h +++ b/src/menu/drc/MenuElementController.h @@ -21,6 +21,7 @@ #include "controller_patcher/patcher/ControllerPatcherDefs.h" #include "controller_patcher/utils/CPRetainVars.hpp" #include "utils/StringTools.h" +#include "language/gettext.h" class MenuElementController : public MenuElement{ public: diff --git a/src/menu/drc/MenuElementInfo.h b/src/menu/drc/MenuElementInfo.h index 5b21782..b0e9c01 100644 --- a/src/menu/drc/MenuElementInfo.h +++ b/src/menu/drc/MenuElementInfo.h @@ -19,6 +19,7 @@ #include "MenuElement.h" #include "content/ContentTemplate.h" +#include "language/gettext.h" class MenuElementInfo : public MenuElement{ public: diff --git a/src/menu/drc/MenuListDRC.cpp b/src/menu/drc/MenuListDRC.cpp index a20a94c..d26384a 100644 --- a/src/menu/drc/MenuListDRC.cpp +++ b/src/menu/drc/MenuListDRC.cpp @@ -28,18 +28,18 @@ MenuListDRC::MenuListDRC(s32 w, s32 h,MainWindowContent * _contentWindow) , width(w) , height(h) , bgImageColor(w, h, (GX2Color){ 0, 0, 0, 0 }) - , homeSeperator("Home") - , elementHome( "Home", "homeIcon.png", ContentTemplate::CONTENT_HOME) + , homeSeperator(gettext("Home")) + , elementHome(gettext("Home"), "homeIcon.png", ContentTemplate::CONTENT_HOME) , controllerSeperator("Controller") , elementGamePad(UController_Type_Gamepad) , elementProController1(UController_Type_Pro1) , elementProController2(UController_Type_Pro2) , elementProController3(UController_Type_Pro3) , elementProController4(UController_Type_Pro4) - , otherSeperator("Other") - , elementHelp( "Help", "helpIcon.png", ContentTemplate::CONTENT_HELP) - , elementNetworkHelp( "Network Client", "netbtn.png", ContentTemplate::CONTENT_NETWORK_HELP) - , elementAbout( "About", "aboutIcon.png", ContentTemplate::CONTENT_ABOUT) + , otherSeperator(gettext("Other")) + , elementHelp(gettext("Help"), "helpIcon.png", ContentTemplate::CONTENT_HELP) + , elementNetworkHelp( gettext("Network Client"), "netbtn.png", ContentTemplate::CONTENT_NETWORK_HELP) + , elementAbout(gettext("About"), "aboutIcon.png", ContentTemplate::CONTENT_ABOUT) , buttonUpTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_UP | GuiTrigger::STICK_L_UP, true) , buttonDownTrigger(GuiTrigger::CHANNEL_ALL, GuiTrigger::BUTTON_DOWN | GuiTrigger::STICK_L_DOWN, true) , touchTrigger(GuiTrigger::CHANNEL_1, GuiTrigger::VPAD_TOUCH) diff --git a/src/menu/drc/MenuListDRC.h b/src/menu/drc/MenuListDRC.h index 018824e..4f9e84f 100644 --- a/src/menu/drc/MenuListDRC.h +++ b/src/menu/drc/MenuListDRC.h @@ -24,6 +24,7 @@ #include "MenuElementController.h" #include "MenuElementInfo.h" #include "MenuSeperator.h" +#include "language/gettext.h" class MenuListDRC : public GuiFrame, public sigslot::has_slots<>{ public: diff --git a/src/menu/drc/content/ContentAbout.h b/src/menu/drc/content/ContentAbout.h index e10dec6..6a47e70 100644 --- a/src/menu/drc/content/ContentAbout.h +++ b/src/menu/drc/content/ContentAbout.h @@ -21,6 +21,7 @@ #include "gui/Gui.h" #include "ContentHome.h" #include "ContentTemplate.h" +#include "language/gettext.h" class ContentAbout : public ContentTemplate{ public: diff --git a/src/menu/drc/content/ContentController.cpp b/src/menu/drc/content/ContentController.cpp index c2c1eb0..c51c86e 100644 --- a/src/menu/drc/content/ContentController.cpp +++ b/src/menu/drc/content/ContentController.cpp @@ -26,29 +26,30 @@ ContentController::ContentController(UController_Type controller_type_): Content , proinput(controller_type_) , connectedFrame(1280-450-2,720) , notConnectedFrame(1280-450-2,720) - , notConnectedLabel("Currently no device is connected.") + , notConnectedLabel(gettext("Currently no device is connected.")) , notConnectedLabel2("") , not_connected_imgdata(Resources::GetImageData("not_connected.png")) , not_connected_img(not_connected_imgdata) - , connectedLabel("Device connected. You can test it by pressing buttons.") - , connectedLabel2("Press A to remap to a new controller.") - , mouseConnectedLabel("Mouse connected. You can test it by pressing buttons.") - , keyboardConnectedLabel("Keyboard connected. You can test it by pressing buttons.") - , mouseConnectedLabel2("Press X to add a Keyboard.") - , keyboardConnectedLabel2("Press X to add a Mouse.") - , mouseConnectedLabel3("Keyboard connected.") - , keyboardConnectedLabel3("Mouse connected.") + , connectedLabel(gettext("Device connected. You can test it by pressing buttons.")) + , connectedLabel2(gettext("Press A to remap to a new controller.")) + , mouseConnectedLabel(gettext("Mouse connected. You can test it by pressing buttons.")) + , keyboardConnectedLabel(gettext("Keyboard connected. You can test it by pressing buttons.")) + , mouseConnectedLabel2(gettext("Press X to add a Keyboard.")) + , keyboardConnectedLabel2(gettext("Press X to add a Mouse.")) + , mouseConnectedLabel3(gettext("Keyboard connected.")) + , keyboardConnectedLabel3(gettext("Mouse connected.")) { std::string text(""); switch(controller_type){ - case UController_Type_Gamepad: {text = "GamePad"; break; } - case UController_Type_Pro1: { text = "Pro Controller 1"; break; } - case UController_Type_Pro2: { text = "Pro Controller 2"; break; } - case UController_Type_Pro3: { text = "Pro Controller 3"; break; } - case UController_Type_Pro4: { text = "Pro Controller 4"; break; } + case UController_Type_Gamepad: {text = UController_Type_Gamepad_Name; break; } + case UController_Type_Pro1: { text = UController_Type_Pro1_Name; break; } + case UController_Type_Pro2: { text = UController_Type_Pro2_Name; break; } + case UController_Type_Pro3: { text = UController_Type_Pro3_Name; break; } + case UController_Type_Pro4: { text = UController_Type_Pro4_Name; break; } default: break; } - notConnectedLabel2.setText(strfmt("Press A to map a controller to \"%s\".",text.c_str()).c_str()); + notConnectedLabel2.setText(strfmt("%s\"%s\".",gettext("Press A to map a controller to "),text.c_str()).c_str()); + notConnectedLabel2.setMaxWidth(800,GuiText::SCROLL_HORIZONTAL); headLine.setText(text.c_str()); headLine.setFontSize(50); diff --git a/src/menu/drc/content/ContentController.h b/src/menu/drc/content/ContentController.h index 1931c9d..52de2e0 100644 --- a/src/menu/drc/content/ContentController.h +++ b/src/menu/drc/content/ContentController.h @@ -23,6 +23,7 @@ #include "menu/drc/MenuElementController.h" #include "menu/InputGetterMenu.h" #include "gui/GuiControllerInputDisplay.h" +#include "language/gettext.h" class ContentController : public ContentTemplate{ public: diff --git a/src/menu/drc/content/ContentHelp.cpp b/src/menu/drc/content/ContentHelp.cpp index a0708f9..835a4f4 100644 --- a/src/menu/drc/content/ContentHelp.cpp +++ b/src/menu/drc/content/ContentHelp.cpp @@ -17,7 +17,7 @@ #include "ContentHelp.h" ContentHelp::ContentHelp(): ContentTemplate(){ - headLine.setText("Help"); + headLine.setText(gettext("Help")); headLine.setFontSize(60); headLine.setAlignment(ALIGN_TOP_CENTER); headLine.setPosition(0,-110); @@ -36,14 +36,14 @@ ContentHelp::ContentHelp(): ContentTemplate(){ s32 fontSize2 = 24; glm::vec4 textColor = glm::vec4(0.3f,0.3f,0.3f,1.0f); - text = new GuiText("My controller is not working!", fontSize, textColor); + text = new GuiText(gettext("My controller is not working!"), fontSize, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 35; - text = new GuiText("Make sure you have a valid config in the folder \"sd:/wiiu/controller\"", fontSize2, textColor); + text = new GuiText(gettext("Make sure you have a valid config in the folder \"sd:/wiiu/controller\""), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); @@ -51,14 +51,14 @@ ContentHelp::ContentHelp(): ContentTemplate(){ positionY -= 50; - text = new GuiText("Where do I get the config files from?", fontSize, textColor); + text = new GuiText(gettext("Where do I get the config files from?"), fontSize, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 35; - text = new GuiText("You can create them by yourself or download them from ", fontSize2, textColor); + text = new GuiText(gettext("You can create them by yourself or download them from "), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); @@ -66,21 +66,21 @@ ContentHelp::ContentHelp(): ContentTemplate(){ positionY -= 25; - text = new GuiText("https://github.com/Maschell/controller_patcher_configs", fontSize2, textColor); + text = new GuiText(gettext("https://github.com/Maschell/controller_patcher_configs"), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 50; - text = new GuiText("I have no idea how create a own config!", fontSize, textColor); + text = new GuiText(gettext("I have no idea how create a own config!"), fontSize, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 35; - text = new GuiText("You're lucky! There a whole wiki about creating them:", fontSize2, textColor); + text = new GuiText(gettext("You're lucky! There a whole wiki about creating them:"), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); @@ -94,34 +94,34 @@ ContentHelp::ContentHelp(): ContentTemplate(){ append(text); positionY -= 50; - text = new GuiText("XYZ is not working!", fontSize, textColor); + text = new GuiText(gettext("XYZ is not working!"), fontSize, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 35; - text = new GuiText("If you find a bug, please open an issue on github", fontSize2, textColor); + text = new GuiText(gettext("If you find a bug, please open an issue on github"), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 50; - text = new GuiText("Could you add feature XYZ? Please!", fontSize, textColor); + text = new GuiText(gettext("Could you add feature XYZ? Please!"), fontSize, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 35; - text = new GuiText("Maybe.It depends on the request, I can't promise anything.", fontSize2, textColor); + text = new GuiText(gettext("Maybe.It depends on the request, I can't promise anything."), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 20; - text = new GuiText("Just open an issue and I'll try to do my best.", fontSize2, textColor); + text = new GuiText(gettext("Just open an issue and I'll try to do my best."), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); diff --git a/src/menu/drc/content/ContentHelp.h b/src/menu/drc/content/ContentHelp.h index 17624f2..f1b9c0d 100644 --- a/src/menu/drc/content/ContentHelp.h +++ b/src/menu/drc/content/ContentHelp.h @@ -20,6 +20,7 @@ #include "gui/Gui.h" #include "ContentHome.h" #include "ContentTemplate.h" +#include "language/gettext.h" class ContentHelp : public ContentTemplate{ public: diff --git a/src/menu/drc/content/ContentHome.cpp b/src/menu/drc/content/ContentHome.cpp index d3acbc0..81a21e8 100644 --- a/src/menu/drc/content/ContentHome.cpp +++ b/src/menu/drc/content/ContentHome.cpp @@ -19,10 +19,10 @@ ContentHome::ContentHome():ContentTemplate() , logoImageData(Resources::GetImageData("logo.png")) , logoImage(logoImageData) - , welcomeHeadLineLabel("Welcome to HID to VPAD!") - , welcomeTextLabel("HID to VPAD allows you to use your USB controller on your WiiU. Currently you can emulate the Gamepad or a Pro Controller.") - , welcomeTextLabel2("Before you use your controller, you may need to provide a valid config. More information and config files can be found in the help section or on gbatemp.net (gbatemp.net/threads/424127/).") - , welcomeTextLabel3("To map a device, select a controller from the list on the left hand side.") + , welcomeHeadLineLabel(gettext("Welcome to HID to VPAD!")) + , welcomeTextLabel(gettext("HID to VPAD allows you to use your USB controller on your WiiU. Currently you can emulate the Gamepad or a Pro Controller.")) + , welcomeTextLabel2(gettext("Before you use your controller, you may need to provide a valid config. More information and config files can be found in the help section or on gbatemp.net (gbatemp.net/threads/424127/).")) + , welcomeTextLabel3(gettext("To map a device, select a controller from the list on the left hand side.")) , twitterLogoImageData(Resources::GetImageData("TwitterIcon.png")) , twitterLogoImage(twitterLogoImageData) , githubLogoImageData(Resources::GetImageData("GithubIcon.png")) diff --git a/src/menu/drc/content/ContentHome.h b/src/menu/drc/content/ContentHome.h index 71524bf..8a7f487 100644 --- a/src/menu/drc/content/ContentHome.h +++ b/src/menu/drc/content/ContentHome.h @@ -20,6 +20,7 @@ #include "gui/Gui.h" #include "ContentHome.h" #include "ContentTemplate.h" +#include "language/gettext.h" class ContentHome : public ContentTemplate{ public: diff --git a/src/menu/drc/content/ContentNetworkHelp.cpp b/src/menu/drc/content/ContentNetworkHelp.cpp index 04f3e80..1998448 100644 --- a/src/menu/drc/content/ContentNetworkHelp.cpp +++ b/src/menu/drc/content/ContentNetworkHelp.cpp @@ -17,7 +17,7 @@ #include "ContentNetworkHelp.h" ContentNetworkHelp::ContentNetworkHelp(): ContentTemplate(){ - headLine.setText("Network Client"); + headLine.setText(gettext("Network Client")); headLine.setFontSize(60); headLine.setAlignment(ALIGN_TOP_CENTER); headLine.setPosition(0,-110); @@ -36,14 +36,14 @@ ContentNetworkHelp::ContentNetworkHelp(): ContentTemplate(){ s32 fontSize2 = 24; glm::vec4 textColor = glm::vec4(0.3f,0.3f,0.3f,1.0f); - text = new GuiText("What is the Network Client?", fontSize, textColor); + text = new GuiText(gettext("What is the Network Client?"), fontSize, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 35; - text = new GuiText("It allows you to use your controller connected to your Computer with", fontSize2, textColor); + text = new GuiText(gettext("It allows you to use your controller connected to your Computer with"), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); @@ -51,49 +51,49 @@ ContentNetworkHelp::ContentNetworkHelp(): ContentTemplate(){ positionY -= 25; - text = new GuiText("HID to VPAD. This way for example XInput- and HID-Bluetooth-Devices", fontSize2, textColor); + text = new GuiText(gettext("HID to VPAD. This way for example XInput- and HID-Bluetooth-Devices"), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 25; - text = new GuiText("can be used. It connects to your console over your local network.", fontSize2, textColor); + text = new GuiText(gettext("can be used. It connects to your console over your local network."), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 35; - text = new GuiText("How do I use it?", fontSize, textColor); + text = new GuiText(gettext("How do I use it?"), fontSize, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 35; - text = new GuiText("Enter the IP (upper right corner!) of your console and press connect.", fontSize2, textColor); + text = new GuiText(gettext("Enter the IP (upper right corner!) of your console and press connect."), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 25; - text = new GuiText("If everything worked correctly, use the controller just like one", fontSize2, textColor); + text = new GuiText(gettext("If everything worked correctly, use the controller just like one"), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 25; - text = new GuiText("connected via USB. You can find a detailed guide here:", fontSize2, textColor); + text = new GuiText(gettext("connected via USB. You can find a detailed guide here:"), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 25; - text = new GuiText("http://gbatemp.net/threads/hid-to-vpad.424127/", fontSize2, textColor); + text = new GuiText(gettext("http://gbatemp.net/threads/hid-to-vpad.424127/"), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); @@ -102,49 +102,49 @@ ContentNetworkHelp::ContentNetworkHelp(): ContentTemplate(){ - text = new GuiText("Is there any input lag?", fontSize, textColor); + text = new GuiText(gettext("Is there any input lag?"), fontSize, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 35; - text = new GuiText("With a connection via Ethernet, you shouldn't notice any lag.", fontSize2, textColor); + text = new GuiText(gettext("With a connection via Ethernet, you shouldn't notice any lag."), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 25; - text = new GuiText("Wi-Fi may lead to some issues or lag, but it heavily depends on the", fontSize2, textColor); + text = new GuiText(gettext("Wi-Fi may lead to some issues or lag, but it heavily depends on the"), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 25; - text = new GuiText("quality of your signal. If it's possible, connect everything via Ethernet.", fontSize2, textColor); + text = new GuiText(gettext("quality of your signal. If it's possible, connect everything via Ethernet."), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 35; - text = new GuiText("Where can I get it?", fontSize, textColor); + text = new GuiText(gettext("Where can I get it?"), fontSize, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 35; - text = new GuiText("It's open source and you can find it here: ", fontSize2, textColor); + text = new GuiText(gettext("It's open source and you can find it here: "), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); append(text); positionY -= 25; - text = new GuiText("https://github.com/QuarkTheAwesome/HIDtoVPADNetworkClient", fontSize2, textColor); + text = new GuiText(gettext("https://github.com/QuarkTheAwesome/HIDtoVPADNetworkClient"), fontSize2, textColor); text->setPosition(positionX, positionY); text->setAlignment(ALIGN_LEFT | ALIGN_MIDDLE); helpText.push_back(text); diff --git a/src/menu/drc/content/ContentNetworkHelp.h b/src/menu/drc/content/ContentNetworkHelp.h index 588e571..b5e3109 100644 --- a/src/menu/drc/content/ContentNetworkHelp.h +++ b/src/menu/drc/content/ContentNetworkHelp.h @@ -19,6 +19,7 @@ #include "gui/Gui.h" #include "ContentTemplate.h" +#include "language/gettext.h" class ContentNetworkHelp : public ContentTemplate{ public: diff --git a/src/menu/drc/content/ContentTemplate.h b/src/menu/drc/content/ContentTemplate.h index 3e83848..fa8b1b0 100644 --- a/src/menu/drc/content/ContentTemplate.h +++ b/src/menu/drc/content/ContentTemplate.h @@ -19,8 +19,6 @@ #include "gui/Gui.h" - - class ContentTemplate : public GuiFrame, public sigslot::has_slots<>{ public: diff --git a/src/menu/tv/TVButtonController.cpp b/src/menu/tv/TVButtonController.cpp index 53cd7af..18c380b 100644 --- a/src/menu/tv/TVButtonController.cpp +++ b/src/menu/tv/TVButtonController.cpp @@ -35,7 +35,7 @@ TVButtonController::TVButtonController(UController_Type controllertype) ,gamepad_imgdata(Resources::GetImageData("gamepadBig.png")) ,gamepad_img(gamepad_imgdata) ,controllerlabel("") - ,notAttachedLabel("No device") + ,notAttachedLabel(gettext("No device")) ,ledon_imgdata(Resources::GetImageData("ledon.png")) ,ledoff_imgdata(Resources::GetImageData("ledoff.png")) { @@ -169,7 +169,7 @@ void TVButtonController::draw(CVideo *v){ s32 foundSlot = ControllerPatcher::getActiveMappingSlot(getControllerType()); if(foundSlot == -1){ - name = "No device"; + name = gettext("No device"); }else{ controllerConnected = 1; @@ -178,9 +178,9 @@ void TVButtonController::draw(CVideo *v){ if(info->type == CM_Type_Controller){ drawControllerName(v,info->vidpid.vid,info->vidpid.pid); }else if(info->type == CM_Type_RealController){ - name = "Real Pro Controller"; + name = gettext("Real Pro Controller"); }else if(info->type == CM_Type_Mouse || info->type == CM_Type_Keyboard){ - name = "Mouse / Keyboard"; + name = gettext("Mouse / Keyboard"); } } } diff --git a/src/menu/tv/TVButtonController.h b/src/menu/tv/TVButtonController.h index 0f6786e..d85f467 100644 --- a/src/menu/tv/TVButtonController.h +++ b/src/menu/tv/TVButtonController.h @@ -21,6 +21,7 @@ #include "controller_patcher/utils/CPRetainVars.hpp" #include "utils/StringTools.h" #include "gui/Gui.h" +#include "language/gettext.h" class TVButtonController : public GuiButton{ public: diff --git a/src/menu/tv/TVControllerBanner.cpp b/src/menu/tv/TVControllerBanner.cpp index baeb2a1..3afe331 100644 --- a/src/menu/tv/TVControllerBanner.cpp +++ b/src/menu/tv/TVControllerBanner.cpp @@ -38,10 +38,10 @@ TVControllerBanner::TVControllerBanner(s32 w, s32 h) , gamepad(UController_Type_Gamepad) , homebutton_imgdata(Resources::GetImageData("HomeButtonIcon.png")) , homebutton_img(homebutton_imgdata) - , exitHome("Press to return to HBL") + , exitHome(gettext("Press to return to HBL")) , plusbutton_imgdata(Resources::GetImageData("PlusButtonIcon.png")) , plusbutton_img(plusbutton_imgdata) - , exitPlus("Press to apply patches") + , exitPlus(gettext("Press to apply patches")) , wpadTouchTrigger(GuiTrigger::CHANNEL_2 | GuiTrigger::CHANNEL_3 | GuiTrigger::CHANNEL_4 | GuiTrigger::CHANNEL_5, GuiTrigger::BUTTON_A) { append(&background_img); diff --git a/src/resources/filelist.h b/src/resources/filelist.h index 3d8e73f..faa9b0f 100644 --- a/src/resources/filelist.h +++ b/src/resources/filelist.h @@ -1,7 +1,7 @@ /**************************************************************************** * Loadiine resource files. * This file is generated automatically. - * Includes 98 files. + * Includes 95 files. * * NOTE: * Any manual modification of this file will be overwriten by the generation. @@ -293,21 +293,12 @@ extern const u32 selectorSmall_png_size; extern const u8 seperator_png[]; extern const u32 seperator_png_size; -extern const u8 settingButton_png[]; -extern const u32 settingButton_png_size; - -extern const u8 settingSelectedButton_png[]; -extern const u32 settingSelectedButton_png_size; - extern const u8 TVElementControllerBG_png[]; extern const u32 TVElementControllerBG_png_size; extern const u8 TVElementControllerBGSelected_png[]; extern const u32 TVElementControllerBGSelected_png_size; -extern const u8 twittergithub_png[]; -extern const u32 twittergithub_png_size; - extern const u8 TwitterIcon_png[]; extern const u32 TwitterIcon_png_size; @@ -407,11 +398,8 @@ static RecourceFile RecourceList[] = {"selectorBig.png", selectorBig_png, selectorBig_png_size, NULL, 0}, {"selectorSmall.png", selectorSmall_png, selectorSmall_png_size, NULL, 0}, {"seperator.png", seperator_png, seperator_png_size, NULL, 0}, - {"settingButton.png", settingButton_png, settingButton_png_size, NULL, 0}, - {"settingSelectedButton.png", settingSelectedButton_png, settingSelectedButton_png_size, NULL, 0}, {"TVElementControllerBG.png", TVElementControllerBG_png, TVElementControllerBG_png_size, NULL, 0}, {"TVElementControllerBGSelected.png", TVElementControllerBGSelected_png, TVElementControllerBGSelected_png_size, NULL, 0}, - {"twittergithub.png", twittergithub_png, twittergithub_png_size, NULL, 0}, {"TwitterIcon.png", TwitterIcon_png, TwitterIcon_png_size, NULL, 0}, {"windowSplitter.png", windowSplitter_png, windowSplitter_png_size, NULL, 0}, {NULL, NULL, 0, NULL, 0} diff --git a/updatelang.sh b/updatelang.sh new file mode 100644 index 0000000..4914433 --- /dev/null +++ b/updatelang.sh @@ -0,0 +1,9 @@ +#! /bin/bash +# +find . -iname "*.cpp" | xargs xgettext -o languages/english.lang -j +for fn in `find languages/*.lang`; do + if [ "$fn" != "languages/english.lang" ]; then + msgmerge --output-file=$fn $fn languages/english.lang + fi + +done \ No newline at end of file