Compare commits

...

4 Commits

10 changed files with 238 additions and 46 deletions

153
locale/pl.xml Normal file
View File

@ -0,0 +1,153 @@
<!--
Polygun locale
Language: PL
Last translator: mrkubax10 <mrkubax10@onet.pl>
-->
<locale>
<!-- src/game/screens/game_session_screen.cpp:284 -->
<tr>
<msgid>Place Block</msgid>
<msgstr>Postaw blok</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:216 -->
<tr>
<msgid>Joining to server</msgid>
<msgstr>Dołączanie do serwera</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:217 -->
<tr>
<msgid>Joining to server polygun://%s:%d...</msgid>
<msgstr>Dołączanie do serwera polygun://%s:%d...</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:225 -->
<tr>
<msgid>Connect to server</msgid>
<msgstr>Łączenie z serwerem</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:225 -->
<tr>
<msgid>Failed to connect to polygun://</msgid>
<msgstr>Nie można połączyć się z polygun://</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:228 -->
<tr>
<msgid>Timed out</msgid>
<msgstr>Upłynął czas połączenia</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:228 -->
<tr>
<msgid>Lost connection with polygun://</msgid>
<msgstr>Utracono połączenie z polygun://</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:260 -->
<tr>
<msgid>Debug</msgid>
<msgstr>Debugowanie</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:269 -->
<tr>
<msgid>Frame Times</msgid>
<msgstr>Czas klatek</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:271 -->
<tr>
<msgid>Application average %.3f ms/frame (%.1f FPS)</msgid>
<msgstr>Średnia aplikacji %.3f ms/klatkę (%.1f klatek na sekundę)</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:273 -->
<tr>
<msgid>Player Pos: %.3f, %.3f, %.3f</msgid>
<msgstr>Pozycja gracza: %.3f, %.3f, %.3f</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp: 275 -->
<tr>
<msgid>Player Rot: %.3f, %.3f, %.3f</msgid>
<msgstr>Obrót gracza: %.3f, %.3f, %.3f</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:276 -->
<tr>
<msgid>ID</msgid>
<msgstr>ID</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:277 -->
<tr>
<msgid>X</msgid>
<msgstr>X</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:278 -->
<tr>
<msgid>Y</msgid>
<msgstr>Y</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:279 -->
<tr>
<msgid>Z</msgid>
<msgstr>Z</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:282 -->
<tr>
<msgid>FOV</msgid>
<msgstr>Pole widzenia</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:289 -->
<tr>
<msgid>Quit Game</msgid>
<msgstr>Wyjdź z gry</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:308 -->
<tr>
<msgid>clear color</msgid>
<msgstr>Kolor czyszczenia</msgstr>
</tr>
<!-- src/game/screens/game_session_screen.cpp:483 -->
<tr>
<msgid>OK</msgid>
<msgstr>OK</msgstr>
</tr>
<!-- src/game/screens/main_menu_screen.cpp:56 -->
<tr>
<msgid>Temporary main menu</msgid>
<msgstr>Tymczasowe menu główne</msgstr>
</tr>
<!-- src/game/screens/main_menu_screen.cpp:62 -->
<tr>
<msgid>Nickname</msgid>
<msgstr>Nick</msgstr>
</tr>
<!-- src/game/screens/main_menu_screen.cpp:65 -->
<tr>
<msgid>Multiplayer</msgid>
<msgstr>Tryb wieloosobowy</msgstr>
</tr>
<!-- src/game/screens/main_menu_screen.cpp:66 -->
<tr>
<msgid>Server address</msgid>
<msgstr>Adres serwera</msgstr>
</tr>
<!-- src/game/screens/main_menu_screen.cpp:67 -->
<tr>
<msgid>Server port</msgid>
<msgstr>Port serwera</msgstr>
</tr>
<!-- src/game/screens/main_menu_screen.cpp:68 -->
<tr>
<msgid>Connect</msgid>
<msgstr>Połącz</msgstr>
</tr>
<!-- src/game/screens/main_menu_screen.cpp:75 -->
<tr>
<msgid>Host game</msgid>
<msgstr>Hostuj grę</msgstr>
</tr>
<!-- src/game/screens/main_menu_screen.cpp:78 -->
<tr>
<msgid>Host</msgid>
<msgstr>Hostuj</msgstr>
</tr>
<!-- src/game/screens/main_menu_screen.cpp:85 -->
<tr>
<msgid>Host (server not compiled in)</msgid>
<msgstr>Hostuj (serwer nie wkompilowany)</msgstr>
</tr>
</locale>

View File

@ -35,31 +35,37 @@ Dictionary::Dictionary() :
{}
void Dictionary::load_from_file(const std::string& path) {
xml::XMLNode root_node;
xml::XMLNode* root_node;
if(!xml::parse_file(path, root_node)) {
LOG_ERROR("Failed to load translation '%s'", path.c_str());
delete root_node;
return;
}
if(root_node.get_name()!="locale") {
if(root_node->get_name()!="locale") {
LOG_ERROR("Failed to load translation '%s': not a locale file", path.c_str());
delete root_node;
return;
}
m_data.clear();
for(xml::XMLNode* node = root_node.next_node(); node; node = root_node.next_node()) {
for(xml::XMLNode* node = root_node->next_node(); node; node = root_node->next_node()) {
if(node->get_name()!="tr") {
LOG_ERROR("Invalid tag '%s' in locale file '%s'", node->get_name().c_str(), path.c_str());
delete root_node;
return;
}
xml::XMLNode* msgid = node->next_node("msgid");
xml::XMLNode* msgstr = node->next_node("msgstr");
if(!msgid || !msgstr) {
LOG_ERROR("Invalid locale entry in locale file '%s'", path.c_str());
delete root_node;
return;
}
m_data[msgid->get_text()] = msgstr->get_text();
}
delete root_node;
}
const std::string& Dictionary::get(const std::string& msgid) {

View File

@ -42,8 +42,8 @@ TranslationManager::TranslationManager(const std::string& locale_directory) :
m_dictionary()
{}
const std::string& TranslationManager::translate(const std::string& msgid) {
return m_dictionary.get(msgid);
const char* TranslationManager::translate(const std::string& msgid) {
return m_dictionary.get(msgid).c_str();
}
void TranslationManager::set_locale(const std::string& name) {

View File

@ -33,7 +33,7 @@ namespace polygun::locale {
TranslationManager(const std::string& locale_directory);
~TranslationManager() = default;
const std::string& translate(const std::string& msgid);
const char* translate(const std::string& msgid);
void set_locale(const std::string& name);

View File

@ -58,7 +58,7 @@ bool polygun::xml::tokenize(std::istream& stream, std::vector<polygun::xml::XMLT
while(!stream.eof()) {
prev_ch = ch;
ch = stream.get();
if(ch<0)
if(ch==-1)
break;
if(isspace(ch)) {
while(!stream.eof() && isspace(ch = stream.get()));
@ -111,7 +111,7 @@ bool polygun::xml::tokenize(std::istream& stream, std::vector<polygun::xml::XMLT
output.push_back(XMLToken(XMLToken::XML_TOKEN_TYPE_SLASH, "", current_line, current_column));
break;
case '?':
if(!prev_ch!='<') {
if(prev_ch!='<') {
LOG_ERROR("Unexpected '?' at %zu:%zu", current_line, current_column);
return false;
}

View File

@ -31,7 +31,7 @@ SOFTWARE.
#include "common/xml/lexer.hpp"
#include "common/logger.hpp"
bool polygun::xml::parse(std::istream& stream, XMLNode& output) {
bool polygun::xml::parse(std::istream& stream, XMLNode*& output) {
std::vector<XMLToken> tokens;
if(!tokenize(stream, tokens))
return false;
@ -118,23 +118,22 @@ bool polygun::xml::parse(std::istream& stream, XMLNode& output) {
}
}
if(!node_stack.empty()) {
LOG_ERROR("Unclosed tag '%s'", node_stack.back()->get_name());
LOG_ERROR("Unclosed tag '%s'", node_stack.back()->get_name().c_str());
return false;
}
if(last_node) {
output = *last_node;
delete last_node;
output = last_node;
}
return true;
}
bool polygun::xml::parse_string(const std::string& str, polygun::xml::XMLNode& output) {
bool polygun::xml::parse_string(const std::string& str, polygun::xml::XMLNode*& output) {
std::stringstream ss;
ss<<str;
return parse(ss, output);
}
bool polygun::xml::parse_file(const std::string& path, polygun::xml::XMLNode& output) {
bool polygun::xml::parse_file(const std::string& path, polygun::xml::XMLNode*& output) {
std::ifstream file(path);
if(!file.good()) {
LOG_ERROR("While parsing XML file '%s': failed to open file", path.c_str());

View File

@ -30,9 +30,9 @@ SOFTWARE.
namespace polygun::xml {
class XMLNode;
bool parse(std::istream& stream, XMLNode& output);
bool parse_string(const std::string& str, XMLNode& output);
bool parse_file(const std::string& path, XMLNode& output);
bool parse(std::istream& stream, XMLNode*& output);
bool parse_string(const std::string& str, XMLNode*& output);
bool parse_file(const std::string& path, XMLNode*& output);
}
#endif // POLYGUN_XML_PARSER_HPP

View File

@ -28,6 +28,7 @@ SOFTWARE.
#include "common/network/network_manager.hpp"
#include "common/logger.hpp"
#include "common/locale/util.hpp"
#include "game/engine/engine.hpp"
#include "game/renderer/shader.hpp"
#include "game/renderer/mesh.hpp"
@ -217,8 +218,8 @@ void GameSessionScreen::render() {
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::Begin("Joining to server");
ImGui::Text("Joining to server polygun://%s:%d...", m_ip.c_str(), m_port);
ImGui::Begin(_("Joining to server"));
ImGui::Text(_("Joining to server polygun://%s:%d..."), m_ip.c_str(), m_port);
ImGui::End();
ImGui::Render();
@ -226,10 +227,10 @@ void GameSessionScreen::render() {
ImGui::EndFrame();
break;
case GameState::GAME_STATE_FAILED:
show_imgui_error_message("Connect to server", std::string("Failed to connect to polygun://")+m_ip+":"+std::to_string(m_port));
show_imgui_error_message(_("Connect to server"), std::string(_("Failed to connect to polygun://"))+m_ip+":"+std::to_string(m_port));
break;
case GameState::GAME_STATE_TIMED_OUT:
show_imgui_error_message("Timed out", std::string("Lost connection with polygun://")+m_ip+":"+std::to_string(m_port));
show_imgui_error_message("Timed out", std::string(_("Lost connection with polygun://"))+m_ip+":"+std::to_string(m_port));
break;
case GameState::GAME_STATE_FINISHED:
break;
@ -261,7 +262,7 @@ void GameSessionScreen::render() {
// imgui
ImGui::Begin("Debug");
ImGui::Begin(_("Debug"));
// display frame rate in chart
static float values[90] = { 0 };
@ -270,27 +271,27 @@ void GameSessionScreen::render() {
values_offset = (values_offset + 1) % IM_ARRAYSIZE(values);
ImGui::PlotLines("Frame Times", values, IM_ARRAYSIZE(values), values_offset, NULL, 0.0f, 100.0f, ImVec2(0, 80));
ImGui::PlotLines(_("Frame Times"), values, IM_ARRAYSIZE(values), values_offset, NULL, 0.0f, 100.0f, ImVec2(0, 80));
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::Text(_("Application average %.3f ms/frame (%.1f FPS)"), 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
// Camera pos
ImGui::Text("Player Pos: %.3f, %.3f, %.3f", m_camera.m_position.x, m_camera.m_position.y, m_camera.m_position.z);
ImGui::Text(_("Player Pos: %.3f, %.3f, %.3f"), m_camera.m_position.x, m_camera.m_position.y, m_camera.m_position.z);
// Camera rot
ImGui::Text("Player Rot: %.3f, %.3f", m_camera.m_yaw, m_camera.m_pitch);
ImGui::InputInt("ID",&id_d);
ImGui::InputInt("X", &x_d);
ImGui::InputInt("Y", &y_d);
ImGui::InputInt("Z", &z_d);
ImGui::Text(_("Player Rot: %.3f, %.3f"), m_camera.m_yaw, m_camera.m_pitch);
ImGui::InputInt(_("ID"),&id_d);
ImGui::InputInt(_("X"), &x_d);
ImGui::InputInt(_("Y"), &y_d);
ImGui::InputInt(_("Z"), &z_d);
// camera fov
ImGui::InputFloat("FOV", &m_camera.m_fov);
ImGui::InputFloat(_("FOV"), &m_camera.m_fov);
if (ImGui::Button("Place Block"))
if (ImGui::Button(_("Place Block")))
m_chnk.add_node(id_d, glm::vec3(x_d, y_d, z_d));
ImGui::NewLine();
if(ImGui::Button("Quit Game"))
if(ImGui::Button(_("Quit Game")))
m_engine->get_screen_manager().pop_screen();
// greedy meshing debug test
@ -309,7 +310,7 @@ void GameSessionScreen::render() {
// }
//}
ImGui::ColorEdit3("clear color", (float*)&clearcolor);
ImGui::ColorEdit3(_("clear color"), (float*)&clearcolor);
ImGui::End();
@ -484,7 +485,7 @@ void GameSessionScreen::show_imgui_error_message(const std::string& title, const
ImGui::Begin(title.c_str(), std::make_unique<bool>(true).get(), ImGuiWindowFlags_AlwaysAutoResize);
ImGui::Text(msg.c_str());
if(ImGui::Button("OK"))
if(ImGui::Button(_("OK")))
m_engine->get_screen_manager().pop_screen();
ImGui::End();

View File

@ -27,6 +27,7 @@ SOFTWARE.
#include "game/engine/engine.hpp"
#include "game/renderer/texture.hpp"
#include "game/screens/game_session_screen.hpp"
#include "common/locale/util.hpp"
#include "vendor/imgui_internal.h"
using namespace polygun::screens;
@ -52,36 +53,36 @@ void MainMenuScreen::render() {
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::Begin("Temporary main menu");
ImGui::Begin(_("Temporary main menu"));
ImGui::Text("PolyGun");
ImGui::NewLine();
ImGui::NewLine();
ImGui::InputText("Nickname", m_player_nick, IM_ARRAYSIZE(m_player_nick));
ImGui::InputText(_("Nickname"), m_player_nick, IM_ARRAYSIZE(m_player_nick));
ImGui::NewLine();
ImGui::Text("Multiplayer");
ImGui::InputText("Server address", m_multiplayer_ip, IM_ARRAYSIZE(m_multiplayer_ip));
ImGui::InputInt("Server port", &m_multiplayer_port);
if(ImGui::Button("Connect") && strlen(m_multiplayer_ip)>0 && m_multiplayer_port>0 && strlen(m_player_nick)>0) {
ImGui::Text(_("Multiplayer"));
ImGui::InputText(_("Server address"), m_multiplayer_ip, IM_ARRAYSIZE(m_multiplayer_ip));
ImGui::InputInt(_("Server port"), &m_multiplayer_port);
if(ImGui::Button(_("Connect")) && strlen(m_multiplayer_ip)>0 && m_multiplayer_port>0 && strlen(m_player_nick)>0) {
std::unique_ptr<GameSessionScreen> game_session_screen = std::make_unique<GameSessionScreen>(m_multiplayer_ip, m_multiplayer_port, m_player_nick);
m_engine->get_screen_manager().push_screen(std::move(game_session_screen));
}
ImGui::NewLine();
ImGui::Text("Host game");
ImGui::Text(_("Host game"));
#if defined(BUILD_SERVER)
// TODO: Map select there
if(ImGui::Button("Host") && strlen(m_player_nick)>0) {
if(ImGui::Button(_("Host")) && strlen(m_player_nick)>0) {
// TODO: Start server
std::unique_ptr<GameSessionScreen> game_session_screen = std::make_unique<GameSessionScreen>("127.0.0.1", 1337, m_player_nick, true);
m_engine->get_screen_manager().push_screen(std::move(game_session_screen));
}
#else
//ImGui::BeginDisabled();
ImGui::Button("Host (server not compiled in)");
ImGui::Button(_("Host (server not compiled in)"));
//ImGui::EndDisabled();
#endif

View File

@ -143,14 +143,46 @@ void Server::command_thread_func() {
#if defined(__unix__)
int byte_count = 0;
ioctl(0, FIONREAD, &byte_count);
if(byte_count>0)
if(byte_count>0) {
has_input_data = true;
getline(std::cin, line);
}
#elif defined(_WIN32)
// FIXME: Support Unicode characters there
// Note: this code is very hacky but it works
HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD records[4];
DWORD record_count;
ReadConsoleInput(stdin_handle, records, sizeof(records)/sizeof(INPUT_RECORD), &record_count);
for(DWORD i = 0; i<record_count; i++) {
if(records[i].EventType==KEY_EVENT && records[i].Event.KeyEvent.bKeyDown) {
CHAR ch = records[i].Event.KeyEvent.uChar.AsciiChar;
if(isprint(ch)) {
line+=ch;
std::cout<<ch;
std::cout.flush();
}
else if(ch==8 && !line.empty()) {
line.back()=' ';
std::cout<<"\r> "<<line;
line.pop_back();
std::cout<<"\r> "<<line;
}
else if(ch==13) {
std::cout<<std::endl;
has_input_data = true;
break;
}
}
}
#endif
if(has_input_data) {
getline(std::cin, line);
parser.parse(line);
has_input_data = false;
show_input_prompt = true;
#if defined(_WIN32)
line.clear();
#endif
}
}
}