From 250c934b9e02e2e1ed82275968faa8a0e4b5ad9d Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Mon, 9 Oct 2017 00:36:31 +0200 Subject: [PATCH 001/109] Added fonts configurability by a separate file --- src/CMakeLists.txt | 2 + src/app/app.h | 1 + src/common/font_file.cpp | 285 +++++++++++++++++++++++++++++++++++ src/common/font_file.h | 147 ++++++++++++++++++ src/graphics/engine/text.cpp | 16 +- 5 files changed, 446 insertions(+), 5 deletions(-) create mode 100644 src/common/font_file.cpp create mode 100644 src/common/font_file.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e0857506..1cf50289 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -106,6 +106,8 @@ set(BASE_SOURCES common/error.h common/event.cpp common/event.h + common/font_file.h + common/font_file.cpp common/global.h common/image.cpp common/image.h diff --git a/src/app/app.h b/src/app/app.h index 20721e24..3835b418 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -44,6 +44,7 @@ class CSoundInterface; class CInput; class CPathManager; class CConfigFile; +class CFontConfigFile; class CSystemUtils; struct SystemTimeStamp; diff --git a/src/common/font_file.cpp b/src/common/font_file.cpp new file mode 100644 index 00000000..0b234d02 --- /dev/null +++ b/src/common/font_file.cpp @@ -0,0 +1,285 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * 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 http://gnu.org/licenses + */ + +#include "common/font_file.h" + +#include "common/logger.h" +#include "common/make_unique.h" + +#include "common/resources/inputstream.h" +#include "common/resources/outputstream.h" + +#include "common/system/system.h" + +#include +#include +#include +#include +#include + +namespace bp = boost::property_tree; + +CFontConfigFile::CFontConfigFile() + : m_needsSave(false) + , m_useCurrentDirectory(false) + , m_loaded(false) +{ +} + +CFontConfigFile::~CFontConfigFile() +{ + if (m_needsSave) + { + GetLogger()->Warn("Font config file was not properly saved! Saving now...\n"); + Save(); + } +} + +bool CFontConfigFile::Init() +{ + try + { + std::unique_ptr stream; + bool good; + if (m_useCurrentDirectory) + { + auto inputStream = MakeUnique("./fonts.ini"); + good = inputStream->good(); + stream = std::move(inputStream); + } + else + { + auto inputStream = MakeUnique("fonts.ini"); + good = inputStream->is_open(); + stream = std::move(inputStream); + } + + if (good) + { + bp::ini_parser::read_ini(*stream, m_propertyTree); + m_loaded = true; + } + else + { + return false; + } + } + catch (std::exception & e) + { + GetLogger()->Error("Error on parsing config file: %s\n", e.what()); + return false; + } + return true; +} + +bool CFontConfigFile::Save() +{ + if (m_needsSave) + { + try + { + std::unique_ptr stream; + bool good; + if (m_useCurrentDirectory) + { + auto outputStream = MakeUnique("./fonts.ini"); + good = outputStream->good(); + stream = std::move(outputStream); + } + else + { + auto outputStream = MakeUnique("fonts.ini"); + good = outputStream->is_open(); + stream = std::move(outputStream); + } + + if (good) + { + bp::ini_parser::write_ini(*stream, m_propertyTree); + m_needsSave = false; + } + else + { + GetLogger()->Error("Error on storing fonts config file: failed to open file\n"); + return false; + } + } + catch (std::exception & e) + { + GetLogger()->Error("Error on storing fonts config file: %s\n", e.what()); + return false; + } + } + return true; +} + +std::string CFontConfigFile::GetCommonFont() +{ + try + { + std::string path = std::string("/fonts/") + m_propertyTree.get("FONT_COMMON"); + return path; + } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + SetCommonFont("dvu_sans.ttf"); + return "/fonts/dvu_sans.ttf"; + } + return ""; +} + +bool CFontConfigFile::SetCommonFont(std::string filename) +{ + try + { + m_propertyTree.put("FONT_COMMON", filename); + m_needsSave = true; + } + catch (std::exception & e) + { + GetLogger()->Error("Error on editing config file: %s\n", e.what()); + return false; + } + return true; +} + +std::string CFontConfigFile::GetCommonBoldFont() +{ + try + { + std::string path = std::string("/fonts/") + m_propertyTree.get("FONT_COMMON_BOLD"); + return path; + } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + SetCommonBoldFont("dvu_sans_bold.ttf"); + return "/fonts/dvu_sans_bold.ttf"; + } + return ""; +} + +bool CFontConfigFile::SetCommonBoldFont(std::string filename) +{ + try + { + m_propertyTree.put("FONT_COMMON_BOLD", filename); + m_needsSave = true; + } + catch (std::exception & e) + { + GetLogger()->Error("Error on editing config file: %s\n", e.what()); + return false; + } + return true; +} + +std::string CFontConfigFile::GetCommonItalicFont() +{ + try + { + std::string path = std::string("/fonts/") + m_propertyTree.get("FONT_COMMON_ITALIC"); + return path; + } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + SetCommonItalicFont("dvu_sans_italic.ttf"); + return "/fonts/dvu_sans_italic.ttf"; + } + return ""; +} + +bool CFontConfigFile::SetCommonItalicFont(std::string filename) +{ + try + { + m_propertyTree.put("FONT_COMMON_ITALIC", filename); + m_needsSave = true; + } + catch (std::exception & e) + { + GetLogger()->Error("Error on editing config file: %s\n", e.what()); + return false; + } + return true; +} + +std::string CFontConfigFile::GetStudioFont() +{ + try + { + std::string path = std::string("/fonts/") + m_propertyTree.get("FONT_STUDIO"); + return path; + } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + SetStudioFont("dvu_sans_mono.ttf"); + return "/fonts/dvu_sans_mono.ttf"; + } + return ""; +} + +bool CFontConfigFile::SetStudioFont(std::string filename) +{ + try + { + m_propertyTree.put("FONT_STUDIO", filename); + m_needsSave = true; + } + catch (std::exception & e) + { + GetLogger()->Error("Error on editing config file: %s\n", e.what()); + return false; + } + return true; +} + +std::string CFontConfigFile::GetStudioBoldFont() +{ + try + { + std::string path = std::string("/fonts/") + m_propertyTree.get("FONT_STUDIO_BOLD"); + return path; + } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + SetStudioBoldFont("dvu_sans_mono_bold.ttf"); + return "/fonts/dvu_sans_mono_bold.ttf"; + } + return ""; +} + +bool CFontConfigFile::SetStudioBoldFont(std::string filename) +{ + try + { + m_propertyTree.put("FONT_STUDIO_BOLD", filename); + m_needsSave = true; + } + catch (std::exception & e) + { + GetLogger()->Error("Error on editing config file: %s\n", e.what()); + return false; + } + return true; +} diff --git a/src/common/font_file.h b/src/common/font_file.h new file mode 100644 index 00000000..c5d2869d --- /dev/null +++ b/src/common/font_file.h @@ -0,0 +1,147 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * 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 http://gnu.org/licenses + */ + + /** + * \file common/font_file.h + * \brief Class for loading fonts from /data/fonts/fonts.ini + */ + +#pragma once + +#include "common/singleton.h" + +#include + +#include + +/** +* \class CFontConfigFile +* +* \brief Class for loading config file +* +*/ + +class CFontConfigFile : public CSingleton +{ +public: + CFontConfigFile(); + virtual ~CFontConfigFile(); + + /** Loads fonts.ini + * \return return true on success + */ + bool Init(); + + /** Saves fonts.ini + * \return return true on success + */ + bool Save(); + + /** Reads common font from file + * \return return path to font file + */ + + std::string GetCommonFont(); + + /** Writes common font to file + * \return return true on success + */ + + bool SetCommonFont(std::string filename); + + /** Reads common bold font from file + * \return return path to font file + */ + + std::string GetCommonBoldFont(); + + /** Writes common bold font to file + * \return return true on success + */ + + bool SetCommonBoldFont(std::string filename); + + /** Reads common italic font from file + * \return return path to font file + */ + + std::string GetCommonItalicFont(); + + /** Writes common italic font to file + * \return return true on success + */ + + bool SetCommonItalicFont(std::string filename); + + /** Reads studio font from file + * \return return path to font file + */ + + std::string GetStudioFont(); + + /** Writes studio font to file + * \return return true on success + */ + + bool SetStudioFont(std::string filename); + + /** Reads studio bold font from file + * \return returns path to font file + */ + + std::string GetStudioBoldFont(); + + /** Writes studio bold font to file + * \return return true on success + */ + + bool SetStudioBoldFont(std::string filename); + +private: + boost::property_tree::ptree m_propertyTree; + bool m_needsSave; + bool m_useCurrentDirectory; + bool m_loaded; + + /*std::string m_colobotFont; + std::string m_colobotFontb; + std::string m_colobotFonti; + + std::string m_courierFont; + std::string m_courierFontb;*/ +}; + +/** + * \enum Fonts + * \brief enum of types of fonts used in game + *//* +enum Fonts +{ + FONT_COLOBOT = 0, + FONT_COLOBOT_BOLD = 1, + FONT_COLOBOT_ITALIC = 2, + FONT_COURIER = 3, + FONT_COURIER_BOLD = 4 +};*/ + +//! Global function to get config file instance +inline CFontConfigFile & GetFontConfigFile() +{ + return CFontConfigFile::GetInstance(); +} \ No newline at end of file diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 53bd7f6a..aa7008d1 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -22,6 +22,7 @@ #include "app/app.h" +#include "common/font_file.h" #include "common/image.h" #include "common/logger.h" #include "common/stringutils.h" @@ -116,18 +117,23 @@ CText::~CText() bool CText::Create() { + CFontConfigFile fontconfig; + if (!GetFontConfigFile().Init()) + { + GetLogger()->Warn("Error on parsing fonts config file: failed to open file\n"); + } if (TTF_Init() != 0) { m_error = std::string("TTF_Init error: ") + std::string(TTF_GetError()); return false; } - m_fonts[FONT_COLOBOT] = MakeUnique("fonts/dvu_sans.ttf"); - m_fonts[FONT_COLOBOT_BOLD] = MakeUnique("fonts/dvu_sans_bold.ttf"); - m_fonts[FONT_COLOBOT_ITALIC] = MakeUnique("fonts/dvu_sans_italic.ttf"); + m_fonts[FONT_COLOBOT] = MakeUnique(GetFontConfigFile().GetCommonFont()); + m_fonts[FONT_COLOBOT_BOLD] = MakeUnique(GetFontConfigFile().GetCommonBoldFont()); + m_fonts[FONT_COLOBOT_ITALIC] = MakeUnique(GetFontConfigFile().GetCommonItalicFont()); - m_fonts[FONT_COURIER] = MakeUnique("fonts/dvu_sans_mono.ttf"); - m_fonts[FONT_COURIER_BOLD] = MakeUnique("fonts/dvu_sans_mono_bold.ttf"); + m_fonts[FONT_COURIER] = MakeUnique(GetFontConfigFile().GetStudioFont()); + m_fonts[FONT_COURIER_BOLD] = MakeUnique(GetFontConfigFile().GetStudioBoldFont()); for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it) { From cf46c2457a5f0d951d9974503b488129c4a00659 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Wed, 11 Oct 2017 17:02:09 +0200 Subject: [PATCH 002/109] Moved file font.ini to /fonts/ directory Separated SatCom font from Colobot font --- src/common/font_file.cpp | 138 ++++------------------------------- src/common/font_file.h | 69 ++---------------- src/graphics/engine/text.cpp | 2 + src/graphics/engine/text.h | 4 +- src/ui/displayinfo.cpp | 2 +- 5 files changed, 27 insertions(+), 188 deletions(-) diff --git a/src/common/font_file.cpp b/src/common/font_file.cpp index 0b234d02..bd7fd583 100644 --- a/src/common/font_file.cpp +++ b/src/common/font_file.cpp @@ -44,11 +44,6 @@ CFontConfigFile::CFontConfigFile() CFontConfigFile::~CFontConfigFile() { - if (m_needsSave) - { - GetLogger()->Warn("Font config file was not properly saved! Saving now...\n"); - Save(); - } } bool CFontConfigFile::Init() @@ -59,13 +54,13 @@ bool CFontConfigFile::Init() bool good; if (m_useCurrentDirectory) { - auto inputStream = MakeUnique("./fonts.ini"); + auto inputStream = MakeUnique("/fonts/fonts.ini"); good = inputStream->good(); stream = std::move(inputStream); } else { - auto inputStream = MakeUnique("fonts.ini"); + auto inputStream = MakeUnique("/fonts/fonts.ini"); good = inputStream->is_open(); stream = std::move(inputStream); } @@ -73,6 +68,7 @@ bool CFontConfigFile::Init() if (good) { bp::ini_parser::read_ini(*stream, m_propertyTree); + GetLogger()->Debug("Fonts config file loaded correctly. \n"); m_loaded = true; } else @@ -88,198 +84,92 @@ bool CFontConfigFile::Init() return true; } -bool CFontConfigFile::Save() -{ - if (m_needsSave) - { - try - { - std::unique_ptr stream; - bool good; - if (m_useCurrentDirectory) - { - auto outputStream = MakeUnique("./fonts.ini"); - good = outputStream->good(); - stream = std::move(outputStream); - } - else - { - auto outputStream = MakeUnique("fonts.ini"); - good = outputStream->is_open(); - stream = std::move(outputStream); - } - - if (good) - { - bp::ini_parser::write_ini(*stream, m_propertyTree); - m_needsSave = false; - } - else - { - GetLogger()->Error("Error on storing fonts config file: failed to open file\n"); - return false; - } - } - catch (std::exception & e) - { - GetLogger()->Error("Error on storing fonts config file: %s\n", e.what()); - return false; - } - } - return true; -} - std::string CFontConfigFile::GetCommonFont() { try { - std::string path = std::string("/fonts/") + m_propertyTree.get("FONT_COMMON"); + std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommon"); return path; } catch (std::exception & e) { GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - SetCommonFont("dvu_sans.ttf"); return "/fonts/dvu_sans.ttf"; } return ""; } -bool CFontConfigFile::SetCommonFont(std::string filename) -{ - try - { - m_propertyTree.put("FONT_COMMON", filename); - m_needsSave = true; - } - catch (std::exception & e) - { - GetLogger()->Error("Error on editing config file: %s\n", e.what()); - return false; - } - return true; -} - std::string CFontConfigFile::GetCommonBoldFont() { try { - std::string path = std::string("/fonts/") + m_propertyTree.get("FONT_COMMON_BOLD"); + std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommonBold"); return path; } catch (std::exception & e) { GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - SetCommonBoldFont("dvu_sans_bold.ttf"); return "/fonts/dvu_sans_bold.ttf"; } return ""; } -bool CFontConfigFile::SetCommonBoldFont(std::string filename) -{ - try - { - m_propertyTree.put("FONT_COMMON_BOLD", filename); - m_needsSave = true; - } - catch (std::exception & e) - { - GetLogger()->Error("Error on editing config file: %s\n", e.what()); - return false; - } - return true; -} - std::string CFontConfigFile::GetCommonItalicFont() { try { - std::string path = std::string("/fonts/") + m_propertyTree.get("FONT_COMMON_ITALIC"); + std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommonItalic"); return path; } catch (std::exception & e) { GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - SetCommonItalicFont("dvu_sans_italic.ttf"); return "/fonts/dvu_sans_italic.ttf"; } return ""; } -bool CFontConfigFile::SetCommonItalicFont(std::string filename) -{ - try - { - m_propertyTree.put("FONT_COMMON_ITALIC", filename); - m_needsSave = true; - } - catch (std::exception & e) - { - GetLogger()->Error("Error on editing config file: %s\n", e.what()); - return false; - } - return true; -} - std::string CFontConfigFile::GetStudioFont() { try { - std::string path = std::string("/fonts/") + m_propertyTree.get("FONT_STUDIO"); + std::string path = std::string("/fonts/") + m_propertyTree.get("FontStudio"); return path; } catch (std::exception & e) { GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - SetStudioFont("dvu_sans_mono.ttf"); return "/fonts/dvu_sans_mono.ttf"; } return ""; } -bool CFontConfigFile::SetStudioFont(std::string filename) -{ - try - { - m_propertyTree.put("FONT_STUDIO", filename); - m_needsSave = true; - } - catch (std::exception & e) - { - GetLogger()->Error("Error on editing config file: %s\n", e.what()); - return false; - } - return true; -} - std::string CFontConfigFile::GetStudioBoldFont() { try { - std::string path = std::string("/fonts/") + m_propertyTree.get("FONT_STUDIO_BOLD"); + std::string path = std::string("/fonts/") + m_propertyTree.get("FontStudioBold"); return path; } catch (std::exception & e) { GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - SetStudioBoldFont("dvu_sans_mono_bold.ttf"); return "/fonts/dvu_sans_mono_bold.ttf"; } return ""; } -bool CFontConfigFile::SetStudioBoldFont(std::string filename) +std::string CFontConfigFile::GetSatComFont() { try { - m_propertyTree.put("FONT_STUDIO_BOLD", filename); - m_needsSave = true; + std::string path = std::string("/fonts/") + m_propertyTree.get("FontSatCom"); + return path; } catch (std::exception & e) { - GetLogger()->Error("Error on editing config file: %s\n", e.what()); - return false; + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + return "/fonts/dvu_sans.ttf"; } - return true; + return ""; } diff --git a/src/common/font_file.h b/src/common/font_file.h index c5d2869d..d6a320a3 100644 --- a/src/common/font_file.h +++ b/src/common/font_file.h @@ -47,99 +47,44 @@ public: * \return return true on success */ bool Init(); - - /** Saves fonts.ini - * \return return true on success - */ - bool Save(); - + /** Reads common font from file * \return return path to font file */ - std::string GetCommonFont(); - - /** Writes common font to file - * \return return true on success - */ - - bool SetCommonFont(std::string filename); - + /** Reads common bold font from file * \return return path to font file */ - std::string GetCommonBoldFont(); - - /** Writes common bold font to file - * \return return true on success - */ - - bool SetCommonBoldFont(std::string filename); - + /** Reads common italic font from file * \return return path to font file */ - std::string GetCommonItalicFont(); - - /** Writes common italic font to file - * \return return true on success - */ - - bool SetCommonItalicFont(std::string filename); - + /** Reads studio font from file * \return return path to font file */ - std::string GetStudioFont(); - /** Writes studio font to file - * \return return true on success - */ - - bool SetStudioFont(std::string filename); - /** Reads studio bold font from file * \return returns path to font file */ - std::string GetStudioBoldFont(); - /** Writes studio bold font to file - * \return return true on success + /** Reads satcom font from file + * \return returns path to font file */ - - bool SetStudioBoldFont(std::string filename); + std::string GetSatComFont(); private: boost::property_tree::ptree m_propertyTree; bool m_needsSave; bool m_useCurrentDirectory; bool m_loaded; - - /*std::string m_colobotFont; - std::string m_colobotFontb; - std::string m_colobotFonti; - - std::string m_courierFont; - std::string m_courierFontb;*/ }; -/** - * \enum Fonts - * \brief enum of types of fonts used in game - *//* -enum Fonts -{ - FONT_COLOBOT = 0, - FONT_COLOBOT_BOLD = 1, - FONT_COLOBOT_ITALIC = 2, - FONT_COURIER = 3, - FONT_COURIER_BOLD = 4 -};*/ - //! Global function to get config file instance inline CFontConfigFile & GetFontConfigFile() { diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index aa7008d1..6443a6f1 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -131,6 +131,8 @@ bool CText::Create() m_fonts[FONT_COLOBOT] = MakeUnique(GetFontConfigFile().GetCommonFont()); m_fonts[FONT_COLOBOT_BOLD] = MakeUnique(GetFontConfigFile().GetCommonBoldFont()); m_fonts[FONT_COLOBOT_ITALIC] = MakeUnique(GetFontConfigFile().GetCommonItalicFont()); + + m_fonts[FONT_SATCOM] = MakeUnique(GetFontConfigFile().GetSatComFont()); m_fonts[FONT_COURIER] = MakeUnique(GetFontConfigFile().GetStudioFont()); m_fonts[FONT_COURIER_BOLD] = MakeUnique(GetFontConfigFile().GetStudioBoldFont()); diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h index f6414c00..275885e9 100644 --- a/src/graphics/engine/text.h +++ b/src/graphics/engine/text.h @@ -88,7 +88,9 @@ enum FontType //! Alias for bold courier font FONT_COURIER_BOLD = FONT_COURIER | FONT_BOLD, - // 0x02 left for possible another font + //! SatCom font used for interface + + FONT_SATCOM = 0x02, //! Pseudo-font loaded from textures for buttons, icons, etc. FONT_BUTTON = 0x03, diff --git a/src/ui/displayinfo.cpp b/src/ui/displayinfo.cpp index 76aee701..8ae66ad5 100644 --- a/src/ui/displayinfo.cpp +++ b/src/ui/displayinfo.cpp @@ -383,7 +383,7 @@ void CDisplayInfo::StartDisplayInfo(std::string filename, int index, bool bSoluc edit->SetState(STATE_SHADOW); edit->SetMultiFont(true); edit->SetMaxChar(10000); - edit->SetFontType(Gfx::FONT_COLOBOT); + edit->SetFontType(Gfx::FONT_SATCOM); edit->SetSoluceMode(bSoluce); edit->ReadText(filename.c_str()); edit->HyperHome(filename.c_str()); From 054d1c3e54f22255d701af41ea56464a26af9bdc Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Wed, 11 Oct 2017 17:10:04 +0200 Subject: [PATCH 003/109] Changed in-engine fonts names --- src/graphics/engine/engine.cpp | 12 +++++----- src/graphics/engine/particle.cpp | 2 +- src/graphics/engine/text.cpp | 38 +++++++++++++++--------------- src/graphics/engine/text.h | 10 ++++---- src/level/robotmain.cpp | 8 +++---- src/ui/controls/control.cpp | 2 +- src/ui/controls/edit.cpp | 12 +++++----- src/ui/debug_menu.cpp | 2 +- src/ui/displaytext.cpp | 2 +- src/ui/maindialog.cpp | 2 +- src/ui/screen/screen.cpp | 2 +- src/ui/screen/screen_io_write.cpp | 2 +- src/ui/screen/screen_main_menu.cpp | 2 +- src/ui/screen/screen_quit.cpp | 10 ++++---- src/ui/studio.cpp | 4 ++-- 15 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index a1458384..4f43622e 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -5045,7 +5045,7 @@ void CEngine::DrawStats() if (!m_showStats) return; - float height = m_text->GetAscent(FONT_COLOBOT, 13.0f); + float height = m_text->GetAscent(FONT_COMMON, 13.0f); float width = 0.4f; const int TOTAL_LINES = 22; @@ -5072,13 +5072,13 @@ void CEngine::DrawStats() auto drawStatsLine = [&](const std::string& name, const std::string& value, const std::string& value2) { if (!name.empty()) - m_text->DrawText(name+":", FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + m_text->DrawText(name+":", FONT_COMMON, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); pos.x += 0.25f; if (!value.empty()) - m_text->DrawText(value, FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + m_text->DrawText(value, FONT_COMMON, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); pos.x += 0.15f; if (!value2.empty()) - m_text->DrawText(value2, FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_RIGHT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + m_text->DrawText(value2, FONT_COMMON, 12.0f, pos, 1.0f, TEXT_ALIGN_RIGHT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); pos.x -= 0.4f; pos.y -= height; }; @@ -5146,8 +5146,8 @@ void CEngine::DrawTimer() { SetState(ENG_RSTATE_TEXT); - Math::Point pos(0.98f, 0.98f-m_text->GetAscent(FONT_COLOBOT, 15.0f)); - m_text->DrawText(m_timerText, FONT_COLOBOT, 15.0f, pos, 1.0f, TEXT_ALIGN_RIGHT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + Math::Point pos(0.98f, 0.98f-m_text->GetAscent(FONT_COMMON, 15.0f)); + m_text->DrawText(m_timerText, FONT_COMMON, 15.0f, pos, 1.0f, TEXT_ALIGN_RIGHT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); } void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector& triangles) diff --git a/src/graphics/engine/particle.cpp b/src/graphics/engine/particle.cpp index f5c254e3..1dcaf014 100644 --- a/src/graphics/engine/particle.cpp +++ b/src/graphics/engine/particle.cpp @@ -3301,7 +3301,7 @@ void CParticle::DrawParticleCylinder(int i) void CParticle::DrawParticleText(int i) { - CharTexture tex = m_engine->GetText()->GetCharTexture(static_cast(m_particle[i].text), FONT_COURIER, FONT_SIZE_BIG*2.0f); + CharTexture tex = m_engine->GetText()->GetCharTexture(static_cast(m_particle[i].text), FONT_STUDIO, FONT_SIZE_BIG*2.0f); if (tex.id == 0) return; m_device->SetTexture(0, tex.id); diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 6443a6f1..605f73b4 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -104,7 +104,7 @@ CText::CText(CEngine* engine) m_defaultSize = 12.0f; m_tabSize = 4; - m_lastFontType = FONT_COLOBOT; + m_lastFontType = FONT_COMMON; m_lastFontSize = 0; m_lastCachedFont = nullptr; } @@ -128,14 +128,14 @@ bool CText::Create() return false; } - m_fonts[FONT_COLOBOT] = MakeUnique(GetFontConfigFile().GetCommonFont()); - m_fonts[FONT_COLOBOT_BOLD] = MakeUnique(GetFontConfigFile().GetCommonBoldFont()); - m_fonts[FONT_COLOBOT_ITALIC] = MakeUnique(GetFontConfigFile().GetCommonItalicFont()); + m_fonts[FONT_COMMON] = MakeUnique(GetFontConfigFile().GetCommonFont()); + m_fonts[FONT_COMMON_BOLD] = MakeUnique(GetFontConfigFile().GetCommonBoldFont()); + m_fonts[FONT_COMMON_ITALIC] = MakeUnique(GetFontConfigFile().GetCommonItalicFont()); m_fonts[FONT_SATCOM] = MakeUnique(GetFontConfigFile().GetSatComFont()); - m_fonts[FONT_COURIER] = MakeUnique(GetFontConfigFile().GetStudioFont()); - m_fonts[FONT_COURIER_BOLD] = MakeUnique(GetFontConfigFile().GetStudioBoldFont()); + m_fonts[FONT_STUDIO] = MakeUnique(GetFontConfigFile().GetStudioFont()); + m_fonts[FONT_STUDIO_BOLD] = MakeUnique(GetFontConfigFile().GetStudioBoldFont()); for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it) { @@ -153,7 +153,7 @@ void CText::Destroy() m_fonts.clear(); m_lastCachedFont = nullptr; - m_lastFontType = FONT_COLOBOT; + m_lastFontType = FONT_COMMON; m_lastFontSize = 0; TTF_Quit(); @@ -188,7 +188,7 @@ void CText::FlushCache() } m_lastCachedFont = nullptr; - m_lastFontType = FONT_COLOBOT; + m_lastFontType = FONT_COMMON; m_lastFontSize = 0; } @@ -271,8 +271,8 @@ void CText::SizeText(const std::string &text, std::vector::iterato end.x -= sw; } - start.y -= GetDescent(FONT_COLOBOT, size); - end.y += GetAscent(FONT_COLOBOT, size); + start.y -= GetDescent(FONT_COMMON, size); + end.y += GetAscent(FONT_COMMON, size); } void CText::SizeText(const std::string &text, FontType font, @@ -352,7 +352,7 @@ float CText::GetStringWidth(const std::string &text, unsigned int fmtIndex = 0; while (index < text.length()) { - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; if (format + fmtIndex != end) font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); @@ -399,7 +399,7 @@ float CText::GetCharWidth(UTF8Char ch, FontType font, float size, float offset) if (font == FONT_BUTTON) { Math::IntPoint windowSize = m_engine->GetWindowSize(); - float height = GetHeight(FONT_COLOBOT, size); + float height = GetHeight(FONT_COMMON, size); float width = height*(static_cast(windowSize.y)/windowSize.x); return width; } @@ -441,7 +441,7 @@ int CText::GetCharWidthInt(UTF8Char ch, FontType font, float size, float offset) if (font == FONT_BUTTON) { Math::IntPoint windowSize = m_engine->GetWindowSize(); - int height = GetHeightInt(FONT_COLOBOT, size); + int height = GetHeightInt(FONT_COMMON, size); int width = height*(static_cast(windowSize.y)/windowSize.x); return width; } @@ -487,7 +487,7 @@ int CText::Justify(const std::string &text, std::vector::iterator unsigned int fmtIndex = 0; while (index < text.length()) { - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; if (format + fmtIndex != end) font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); @@ -571,7 +571,7 @@ int CText::Detect(const std::string &text, std::vector::iterator f unsigned int fmtIndex = 0; while (index < text.length()) { - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; if (format + fmtIndex != end) font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); @@ -708,7 +708,7 @@ void CText::DrawString(const std::string &text, std::vector::itera StringToUTFCharList(text, chars, format, end); for (auto it = chars.begin(); it != chars.end(); ++it) { - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; if (format + fmtIndex != end) font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); @@ -779,7 +779,7 @@ void CText::DrawString(const std::string &text, std::vector::itera if (eol != 0) { - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; UTF8Char ch = TranslateSpecialChar(eol); color = Color(1.0f, 0.0f, 0.0f); DrawCharAndAdjustPos(ch, font, size, pos, color); @@ -818,7 +818,7 @@ void CText::StringToUTFCharList(const std::string &text, std::vector & { UTF8Char ch; - FontType font = FONT_COLOBOT; + FontType font = FONT_COMMON; if (format + index != end) font = static_cast(*(format + index) & FONT_MASK_FONT); @@ -923,7 +923,7 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::I if (font == FONT_BUTTON) { Math::IntPoint windowSize = m_engine->GetWindowSize(); - int height = GetHeightInt(FONT_COLOBOT, size); + int height = GetHeightInt(FONT_COMMON, size); int width = height * (static_cast(windowSize.y)/windowSize.x); Math::IntPoint p1(pos.x, pos.y - height); diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h index 275885e9..32d50d1f 100644 --- a/src/graphics/engine/text.h +++ b/src/graphics/engine/text.h @@ -77,16 +77,16 @@ enum FontType FONT_ITALIC = 0x08, //! Default colobot font used for interface - FONT_COLOBOT = 0x00, + FONT_COMMON = 0x00, //! Alias for bold colobot font - FONT_COLOBOT_BOLD = FONT_COLOBOT | FONT_BOLD, + FONT_COMMON_BOLD = FONT_COMMON | FONT_BOLD, //! Alias for italic colobot font - FONT_COLOBOT_ITALIC = FONT_COLOBOT | FONT_ITALIC, + FONT_COMMON_ITALIC = FONT_COMMON | FONT_ITALIC, //! Courier (monospace) font used mainly in code editor (only regular & bold) - FONT_COURIER = 0x01, + FONT_STUDIO = 0x01, //! Alias for bold courier font - FONT_COURIER_BOLD = FONT_COURIER | FONT_BOLD, + FONT_STUDIO_BOLD = FONT_STUDIO | FONT_BOLD, //! SatCom font used for interface diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index a92b10b2..6592a234 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -585,7 +585,7 @@ void CRobotMain::ChangePhase(Phase phase) ddim.x = dim.x*15; ddim.y = dim.y*3.0f; pe = m_interface->CreateEdit(pos, ddim, 0, EVENT_EDIT0); pe->SetGenericMode(true); - pe->SetFontType(Gfx::FONT_COLOBOT); + pe->SetFontType(Gfx::FONT_COMMON); pe->SetEditCap(false); pe->SetHighlightCap(false); pe->ReadText(std::string("help/") + m_app->GetLanguageChar() + std::string("/win.txt")); @@ -2116,7 +2116,7 @@ void CRobotMain::CreateTooltip(Math::Point pos, const std::string& text) Math::Point start, end; - m_engine->GetText()->SizeText(text, Gfx::FONT_COLOBOT, Gfx::FONT_SIZE_SMALL, + m_engine->GetText()->SizeText(text, Gfx::FONT_COMMON, Gfx::FONT_SIZE_SMALL, corner, Gfx::TEXT_ALIGN_LEFT, start, end); @@ -2151,7 +2151,7 @@ void CRobotMain::CreateTooltip(Math::Point pos, const std::string& text) pw->SetState(Ui::STATE_SHADOW); pw->SetTrashEvent(false); - pos.y -= m_engine->GetText()->GetHeight(Gfx::FONT_COLOBOT, Gfx::FONT_SIZE_SMALL) / 2.0f; + pos.y -= m_engine->GetText()->GetHeight(Gfx::FONT_COMMON, Gfx::FONT_SIZE_SMALL) / 2.0f; pw->CreateLabel(pos, dim, -1, EVENT_LABEL2, text); } } @@ -5813,7 +5813,7 @@ void CRobotMain::CreateCodeBattleInterface() int numTeams = m_scoreboard ? GetAllTeams().size() : 0; assert(numTeams < EVENT_SCOREBOARD_MAX-EVENT_SCOREBOARD+1); - float textHeight = m_engine->GetText()->GetHeight(Gfx::FONT_COLOBOT, Gfx::FONT_SIZE_SMALL); + float textHeight = m_engine->GetText()->GetHeight(Gfx::FONT_COMMON, Gfx::FONT_SIZE_SMALL); ddim.x = 100.0f/640.0f; ddim.y = 100.0f/480.0f + numTeams * textHeight; diff --git a/src/ui/controls/control.cpp b/src/ui/controls/control.cpp index e0b8ccf9..a9e5a372 100644 --- a/src/ui/controls/control.cpp +++ b/src/ui/controls/control.cpp @@ -43,7 +43,7 @@ CControl::CControl() m_eventType = EVENT_NULL; m_state = STATE_ENABLE|STATE_VISIBLE|STATE_GLINT; m_fontSize = Gfx::FONT_SIZE_SMALL; - m_fontType = Gfx::FONT_COLOBOT; + m_fontType = Gfx::FONT_COMMON; m_textAlign = Gfx::TEXT_ALIGN_CENTER; //instead m_justify m_bFocus = false; m_bCapture = false; diff --git a/src/ui/controls/edit.cpp b/src/ui/controls/edit.cpp index 7d08b260..05e7c786 100644 --- a/src/ui/controls/edit.cpp +++ b/src/ui/controls/edit.cpp @@ -106,7 +106,7 @@ CEdit::CEdit() { m_len = 0; - m_fontType = Gfx::FONT_COURIER; + m_fontType = Gfx::FONT_STUDIO; m_bEdit = true; m_bHilite = true; m_bInsideScroll = true; @@ -1323,13 +1323,13 @@ void CEdit::SetText(const std::string& text, bool bNew) if ( text[i+1] == 'n' ) // normal ? { font &= ~Gfx::FONT_MASK_FONT; - font |= Gfx::FONT_COLOBOT; + font |= Gfx::FONT_COMMON; i += 2; } else if ( text[i+1] == 'c' ) // cbot ? { font &= ~Gfx::FONT_MASK_FONT; - font |= Gfx::FONT_COURIER; + font |= Gfx::FONT_STUDIO; i += 2; } else if ( text[i+1] == 'b' ) // big title ? @@ -1519,7 +1519,7 @@ bool CEdit::ReadText(std::string filename) if ( m_bSoluce || !bInSoluce ) { font &= ~Gfx::FONT_MASK_FONT; - font |= Gfx::FONT_COLOBOT; + font |= Gfx::FONT_COMMON; inCbot = false; } i += 3; @@ -1529,7 +1529,7 @@ bool CEdit::ReadText(std::string filename) if ( m_bSoluce || !bInSoluce ) { font &= ~Gfx::FONT_MASK_FONT; - font |= Gfx::FONT_COURIER; + font |= Gfx::FONT_STUDIO; if (!inCbot) { if (inCbotBackground) @@ -1633,7 +1633,7 @@ bool CEdit::ReadText(std::string filename) //? iWidth = m_lineHeight*RetValueParam(buffer.data()+i+7, 1); iWidth = static_cast(GetValueParam(buffer.data()+i+7, 1)); - iWidth *= m_engine->GetText()->GetHeight(Gfx::FONT_COLOBOT, Gfx::FONT_SIZE_SMALL); + iWidth *= m_engine->GetText()->GetHeight(Gfx::FONT_COMMON, Gfx::FONT_SIZE_SMALL); iLines = GetValueParam(buffer.data()+i+7, 2); // A part of image per line of text. diff --git a/src/ui/debug_menu.cpp b/src/ui/debug_menu.cpp index a6eb6f63..fe5b97cd 100644 --- a/src/ui/debug_menu.cpp +++ b/src/ui/debug_menu.cpp @@ -65,7 +65,7 @@ void CDebugMenu::ToggleInterface() { CreateInterface(); CLabel* pl = m_interface->CreateLabel(Math::Point(0.0f, 0.9f), Math::Point(1.0f, 0.1f), -1, EVENT_LABEL19, "??"); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); } else { diff --git a/src/ui/displaytext.cpp b/src/ui/displaytext.cpp index f0d5bd92..4a5dcfcb 100644 --- a/src/ui/displaytext.cpp +++ b/src/ui/displaytext.cpp @@ -197,7 +197,7 @@ void CDisplayText::DisplayText(const char *text, Math::Vector goal, float height } hBox = 0.045f; - hLine = m_engine->GetText()->GetHeight(Gfx::FONT_COLOBOT, FONTSIZE); + hLine = m_engine->GetText()->GetHeight(Gfx::FONT_COMMON, FONTSIZE); nLine = 0; for ( i=0 ; iCreateLabel(pos, ddim, -1, EVENT_DIALOG_LABEL, text); - pl->SetFontType(Gfx::FONT_COLOBOT_BOLD); + pl->SetFontType(Gfx::FONT_COMMON_BOLD); //TODO: Add \n support in CLabel pos.y -= ddim.y; pl = pw->CreateLabel(pos, ddim, -1, EVENT_DIALOG_LABEL1, details); diff --git a/src/ui/screen/screen.cpp b/src/ui/screen/screen.cpp index 202d5e17..c526d994 100644 --- a/src/ui/screen/screen.cpp +++ b/src/ui/screen/screen.cpp @@ -71,7 +71,7 @@ void CScreen::CreateVersionDisplay() ddim.x = 90.0f/640.0f; ddim.y = 10.0f/480.0f; CLabel* pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, COLOBOT_VERSION_DISPLAY); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(9.0f); } } diff --git a/src/ui/screen/screen_io_write.cpp b/src/ui/screen/screen_io_write.cpp index f65fab38..567890f4 100644 --- a/src/ui/screen/screen_io_write.cpp +++ b/src/ui/screen/screen_io_write.cpp @@ -85,7 +85,7 @@ void CScreenIOWrite::CreateInterface() ddim.y = 18.0f/480.0f; pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_IONAME); pe->SetState(STATE_SHADOW); - pe->SetFontType(Gfx::FONT_COLOBOT); + pe->SetFontType(Gfx::FONT_COMMON); pe->SetMaxChar(35); IOReadName(); diff --git a/src/ui/screen/screen_main_menu.cpp b/src/ui/screen/screen_main_menu.cpp index ea8a29c2..d1c1c96e 100644 --- a/src/ui/screen/screen_main_menu.cpp +++ b/src/ui/screen/screen_main_menu.cpp @@ -159,7 +159,7 @@ void CScreenMainMenu::CreateInterface() pg->SetState(STATE_SHADOW); pos.y -= 5.0f/480.0f; pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, "TerranovaTeam"); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(Gfx::FONT_SIZE_SMALL); // SatCom button diff --git a/src/ui/screen/screen_quit.cpp b/src/ui/screen/screen_quit.cpp index 0651a364..8d57c10a 100644 --- a/src/ui/screen/screen_quit.cpp +++ b/src/ui/screen/screen_quit.cpp @@ -61,7 +61,7 @@ void CScreenQuit::CreateInterface() pe->SetGenericMode(true); pe->SetEditCap(false); pe->SetHighlightCap(false); - pe->SetFontType(Gfx::FONT_COURIER); + pe->SetFontType(Gfx::FONT_STUDIO); pe->SetFontSize(Gfx::FONT_SIZE_SMALL); pe->ReadText(std::string("help/") + m_app->GetLanguageChar() + std::string("/authors.txt")); @@ -71,13 +71,13 @@ void CScreenQuit::CreateInterface() ddim.y = 16.0f/480.0f; GetResource(RES_TEXT, RT_GENERIC_DEV1, name); pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(Gfx::FONT_SIZE_SMALL); pos.y = 13.0f/480.0f; GetResource(RES_TEXT, RT_GENERIC_DEV2, name); pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(Gfx::FONT_SIZE_SMALL); pos.x = 355.0f/640.0f; @@ -86,13 +86,13 @@ void CScreenQuit::CreateInterface() ddim.y = 16.0f/480.0f; GetResource(RES_TEXT, RT_GENERIC_EDIT1, name); pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL3, name); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(Gfx::FONT_SIZE_SMALL); pos.y = 13.0f/480.0f; GetResource(RES_TEXT, RT_GENERIC_EDIT2, name); pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL4, name); - pl->SetFontType(Gfx::FONT_COURIER); + pl->SetFontType(Gfx::FONT_STUDIO); pl->SetFontSize(Gfx::FONT_SIZE_SMALL); pos.x = 306.0f/640.0f; diff --git a/src/ui/studio.cpp b/src/ui/studio.cpp index e3545cbb..35d920a8 100644 --- a/src/ui/studio.cpp +++ b/src/ui/studio.cpp @@ -606,7 +606,7 @@ void CStudio::StartEditScript(CScript *script, std::string name, Program* progra edit->SetState(STATE_SHADOW); edit->SetInsideScroll(false); //? if ( m_bRunning ) edit->SetEdit(false); - edit->SetFontType(Gfx::FONT_COURIER); + edit->SetFontType(Gfx::FONT_STUDIO); edit->SetFontStretch(1.0f); edit->SetDisplaySpec(true); edit->SetAutoIndent(m_engine->GetEditIndentMode()); @@ -618,7 +618,7 @@ void CStudio::StartEditScript(CScript *script, std::string name, Program* progra list = pw->CreateList(pos, dim, 1, EVENT_STUDIO_LIST, 1.2f); list->SetState(STATE_SHADOW); - list->SetFontType(Gfx::FONT_COURIER); + list->SetFontType(Gfx::FONT_STUDIO); list->SetSelectCap(false); list->SetFontSize(Gfx::FONT_SIZE_SMALL*0.85f); //? list->SetFontStretch(1.0f); From dd9439aed2fcebe7a21cb48036e5b3045d812757 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Sun, 15 Oct 2017 22:47:32 +0200 Subject: [PATCH 004/109] Renamed font_file to font_config --- src/CMakeLists.txt | 4 ++-- src/common/{font_file.cpp => font_config.cpp} | 2 +- src/common/{font_file.h => font_config.h} | 2 +- src/graphics/engine/text.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename src/common/{font_file.cpp => font_config.cpp} (99%) rename src/common/{font_file.h => font_config.h} (98%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1cf50289..37d6cb04 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -106,8 +106,8 @@ set(BASE_SOURCES common/error.h common/event.cpp common/event.h - common/font_file.h - common/font_file.cpp + common/font_config.h + common/font_config.cpp common/global.h common/image.cpp common/image.h diff --git a/src/common/font_file.cpp b/src/common/font_config.cpp similarity index 99% rename from src/common/font_file.cpp rename to src/common/font_config.cpp index bd7fd583..e4dc51b1 100644 --- a/src/common/font_file.cpp +++ b/src/common/font_config.cpp @@ -17,7 +17,7 @@ * along with this program. If not, see http://gnu.org/licenses */ -#include "common/font_file.h" +#include "common/font_config.h" #include "common/logger.h" #include "common/make_unique.h" diff --git a/src/common/font_file.h b/src/common/font_config.h similarity index 98% rename from src/common/font_file.h rename to src/common/font_config.h index d6a320a3..cbe0863e 100644 --- a/src/common/font_file.h +++ b/src/common/font_config.h @@ -18,7 +18,7 @@ */ /** - * \file common/font_file.h + * \file common/font_config.h * \brief Class for loading fonts from /data/fonts/fonts.ini */ diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 605f73b4..6ecf9284 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -22,7 +22,7 @@ #include "app/app.h" -#include "common/font_file.h" +#include "common/font_config.h" #include "common/image.h" #include "common/logger.h" #include "common/stringutils.h" From 52d9330114a0e005a0a4575675d2c9fbd1e05b82 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Sun, 15 Oct 2017 23:31:06 +0200 Subject: [PATCH 005/109] Replaced multiple methods with one --- src/common/font_config.cpp | 172 ++++++++++++++++++----------------- src/common/font_config.h | 31 +------ src/graphics/engine/text.cpp | 16 ++-- 3 files changed, 99 insertions(+), 120 deletions(-) diff --git a/src/common/font_config.cpp b/src/common/font_config.cpp index e4dc51b1..11d55833 100644 --- a/src/common/font_config.cpp +++ b/src/common/font_config.cpp @@ -27,6 +27,8 @@ #include "common/system/system.h" +#include "graphics/engine/text.h" + #include #include #include @@ -84,92 +86,92 @@ bool CFontConfigFile::Init() return true; } -std::string CFontConfigFile::GetCommonFont() +std::string CFontConfigFile::GetFont(Gfx::FontType type) { - try + switch(type) { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommon"); - return path; + case Gfx::FONT_COMMON: + { + try + { + std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommon"); + return path; + } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + return "/fonts/dvu_sans.ttf"; + } + } + case Gfx::FONT_COMMON_BOLD: + { + try + { + std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommonBold"); + return path; + } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + return "/fonts/dvu_sans_bold.ttf"; + } + } + case Gfx::FONT_COMMON_ITALIC: + { + try + { + std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommonItalic"); + return path; + } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + return "/fonts/dvu_sans_italic.ttf"; + } + } + case Gfx::FONT_STUDIO: + { + try + { + std::string path = std::string("/fonts/") + m_propertyTree.get("FontStudio"); + return path; + } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + return "/fonts/dvu_sans_mono.ttf"; + } + } + case Gfx::FONT_STUDIO_BOLD: + { + try + { + std::string path = std::string("/fonts/") + m_propertyTree.get("FontStudioBold"); + return path; + } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + return "/fonts/dvu_sans_mono_bold.ttf"; + } + } + case Gfx::FONT_SATCOM: + { + try + { + std::string path = std::string("/fonts/") + m_propertyTree.get("FontSatCom"); + return path; + } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + return "/fonts/dvu_sans.ttf"; + } + } + default: + { + GetLogger()->Debug("Incorrect font type: %i.\n", type); + return nullptr; + } } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans.ttf"; - } - return ""; -} - -std::string CFontConfigFile::GetCommonBoldFont() -{ - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommonBold"); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans_bold.ttf"; - } - return ""; -} - -std::string CFontConfigFile::GetCommonItalicFont() -{ - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommonItalic"); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans_italic.ttf"; - } - return ""; -} - -std::string CFontConfigFile::GetStudioFont() -{ - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontStudio"); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans_mono.ttf"; - } - return ""; -} - -std::string CFontConfigFile::GetStudioBoldFont() -{ - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontStudioBold"); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans_mono_bold.ttf"; - } - return ""; -} - -std::string CFontConfigFile::GetSatComFont() -{ - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontSatCom"); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans.ttf"; - } - return ""; } diff --git a/src/common/font_config.h b/src/common/font_config.h index cbe0863e..cbe2d3d9 100644 --- a/src/common/font_config.h +++ b/src/common/font_config.h @@ -26,6 +26,8 @@ #include "common/singleton.h" +#include "graphics/engine/text.h" + #include #include @@ -48,35 +50,10 @@ public: */ bool Init(); - /** Reads common font from file + /** Reads given font from file * \return return path to font file */ - std::string GetCommonFont(); - - /** Reads common bold font from file - * \return return path to font file - */ - std::string GetCommonBoldFont(); - - /** Reads common italic font from file - * \return return path to font file - */ - std::string GetCommonItalicFont(); - - /** Reads studio font from file - * \return return path to font file - */ - std::string GetStudioFont(); - - /** Reads studio bold font from file - * \return returns path to font file - */ - std::string GetStudioBoldFont(); - - /** Reads satcom font from file - * \return returns path to font file - */ - std::string GetSatComFont(); + std::string GetFont(Gfx::FontType type); private: boost::property_tree::ptree m_propertyTree; diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 6ecf9284..016b1d22 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -127,16 +127,16 @@ bool CText::Create() m_error = std::string("TTF_Init error: ") + std::string(TTF_GetError()); return false; } - - m_fonts[FONT_COMMON] = MakeUnique(GetFontConfigFile().GetCommonFont()); - m_fonts[FONT_COMMON_BOLD] = MakeUnique(GetFontConfigFile().GetCommonBoldFont()); - m_fonts[FONT_COMMON_ITALIC] = MakeUnique(GetFontConfigFile().GetCommonItalicFont()); - m_fonts[FONT_SATCOM] = MakeUnique(GetFontConfigFile().GetSatComFont()); - - m_fonts[FONT_STUDIO] = MakeUnique(GetFontConfigFile().GetStudioFont()); - m_fonts[FONT_STUDIO_BOLD] = MakeUnique(GetFontConfigFile().GetStudioBoldFont()); + m_fonts[FONT_COMMON] = MakeUnique(GetFontConfigFile().GetFont(FONT_COMMON)); + m_fonts[FONT_COMMON_BOLD] = MakeUnique(GetFontConfigFile().GetFont(FONT_COMMON_BOLD)); + m_fonts[FONT_COMMON_ITALIC] = MakeUnique(GetFontConfigFile().GetFont(FONT_COMMON_ITALIC)); + + m_fonts[FONT_SATCOM] = MakeUnique(GetFontConfigFile().GetFont(FONT_SATCOM)); + m_fonts[FONT_STUDIO] = MakeUnique(GetFontConfigFile().GetFont(FONT_STUDIO)); + m_fonts[FONT_STUDIO_BOLD] = MakeUnique(GetFontConfigFile().GetFont(FONT_STUDIO_BOLD)); + for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it) { FontType type = (*it).first; From 1e614d64d0df42dc1d36142d33fce3efc798f58f Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Sun, 15 Oct 2017 23:35:09 +0200 Subject: [PATCH 006/109] Removed unnecessary variable --- src/common/font_config.cpp | 16 +++------------- src/common/font_config.h | 1 - 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/common/font_config.cpp b/src/common/font_config.cpp index 11d55833..16017d8e 100644 --- a/src/common/font_config.cpp +++ b/src/common/font_config.cpp @@ -39,7 +39,6 @@ namespace bp = boost::property_tree; CFontConfigFile::CFontConfigFile() : m_needsSave(false) - , m_useCurrentDirectory(false) , m_loaded(false) { } @@ -54,18 +53,9 @@ bool CFontConfigFile::Init() { std::unique_ptr stream; bool good; - if (m_useCurrentDirectory) - { - auto inputStream = MakeUnique("/fonts/fonts.ini"); - good = inputStream->good(); - stream = std::move(inputStream); - } - else - { - auto inputStream = MakeUnique("/fonts/fonts.ini"); - good = inputStream->is_open(); - stream = std::move(inputStream); - } + auto inputStream = MakeUnique("/fonts/fonts.ini"); + good = inputStream->is_open(); + stream = std::move(inputStream); if (good) { diff --git a/src/common/font_config.h b/src/common/font_config.h index cbe2d3d9..892f9db3 100644 --- a/src/common/font_config.h +++ b/src/common/font_config.h @@ -58,7 +58,6 @@ public: private: boost::property_tree::ptree m_propertyTree; bool m_needsSave; - bool m_useCurrentDirectory; bool m_loaded; }; From 94cacdae96ca17741ea5f60dac34a79ecb74c36b Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Sun, 15 Oct 2017 23:46:15 +0200 Subject: [PATCH 007/109] Removed singletone from FontConfig Also renamed class so it now matches better with class file name --- src/app/app.h | 1 - src/common/font_config.cpp | 8 ++++---- src/common/font_config.h | 14 ++++---------- src/graphics/engine/text.cpp | 16 ++++++++-------- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/app/app.h b/src/app/app.h index 3835b418..20721e24 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -44,7 +44,6 @@ class CSoundInterface; class CInput; class CPathManager; class CConfigFile; -class CFontConfigFile; class CSystemUtils; struct SystemTimeStamp; diff --git a/src/common/font_config.cpp b/src/common/font_config.cpp index 16017d8e..b4487f1a 100644 --- a/src/common/font_config.cpp +++ b/src/common/font_config.cpp @@ -37,17 +37,17 @@ namespace bp = boost::property_tree; -CFontConfigFile::CFontConfigFile() +CFontConfig::CFontConfig() : m_needsSave(false) , m_loaded(false) { } -CFontConfigFile::~CFontConfigFile() +CFontConfig::~CFontConfig() { } -bool CFontConfigFile::Init() +bool CFontConfig::Init() { try { @@ -76,7 +76,7 @@ bool CFontConfigFile::Init() return true; } -std::string CFontConfigFile::GetFont(Gfx::FontType type) +std::string CFontConfig::GetFont(Gfx::FontType type) { switch(type) { diff --git a/src/common/font_config.h b/src/common/font_config.h index 892f9db3..594b4ce8 100644 --- a/src/common/font_config.h +++ b/src/common/font_config.h @@ -33,17 +33,17 @@ #include /** -* \class CFontConfigFile +* \class CFontConfig * * \brief Class for loading config file * */ -class CFontConfigFile : public CSingleton +class CFontConfig { public: - CFontConfigFile(); - virtual ~CFontConfigFile(); + CFontConfig(); + virtual ~CFontConfig(); /** Loads fonts.ini * \return return true on success @@ -60,9 +60,3 @@ private: bool m_needsSave; bool m_loaded; }; - -//! Global function to get config file instance -inline CFontConfigFile & GetFontConfigFile() -{ - return CFontConfigFile::GetInstance(); -} \ No newline at end of file diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 016b1d22..8a023d67 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -117,8 +117,8 @@ CText::~CText() bool CText::Create() { - CFontConfigFile fontconfig; - if (!GetFontConfigFile().Init()) + CFontConfig fontConfig; + if (!fontConfig.Init()) { GetLogger()->Warn("Error on parsing fonts config file: failed to open file\n"); } @@ -128,14 +128,14 @@ bool CText::Create() return false; } - m_fonts[FONT_COMMON] = MakeUnique(GetFontConfigFile().GetFont(FONT_COMMON)); - m_fonts[FONT_COMMON_BOLD] = MakeUnique(GetFontConfigFile().GetFont(FONT_COMMON_BOLD)); - m_fonts[FONT_COMMON_ITALIC] = MakeUnique(GetFontConfigFile().GetFont(FONT_COMMON_ITALIC)); + m_fonts[FONT_COMMON] = MakeUnique(fontConfig.GetFont(FONT_COMMON)); + m_fonts[FONT_COMMON_BOLD] = MakeUnique(fontConfig.GetFont(FONT_COMMON_BOLD)); + m_fonts[FONT_COMMON_ITALIC] = MakeUnique(fontConfig.GetFont(FONT_COMMON_ITALIC)); - m_fonts[FONT_SATCOM] = MakeUnique(GetFontConfigFile().GetFont(FONT_SATCOM)); + m_fonts[FONT_SATCOM] = MakeUnique(fontConfig.GetFont(FONT_SATCOM)); - m_fonts[FONT_STUDIO] = MakeUnique(GetFontConfigFile().GetFont(FONT_STUDIO)); - m_fonts[FONT_STUDIO_BOLD] = MakeUnique(GetFontConfigFile().GetFont(FONT_STUDIO_BOLD)); + m_fonts[FONT_STUDIO] = MakeUnique(fontConfig.GetFont(FONT_STUDIO)); + m_fonts[FONT_STUDIO_BOLD] = MakeUnique(fontConfig.GetFont(FONT_STUDIO_BOLD)); for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it) { From 76a8335501d92464b5a768537a52f79f27db6ff8 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Wed, 18 Oct 2017 12:01:34 +0200 Subject: [PATCH 008/109] Reworked GetFont method --- src/common/font_config.cpp | 107 ++++++++----------------------------- src/common/font_config.h | 1 + 2 files changed, 24 insertions(+), 84 deletions(-) diff --git a/src/common/font_config.cpp b/src/common/font_config.cpp index b4487f1a..4768cbc6 100644 --- a/src/common/font_config.cpp +++ b/src/common/font_config.cpp @@ -29,6 +29,7 @@ #include "graphics/engine/text.h" +#include #include #include #include @@ -41,6 +42,20 @@ CFontConfig::CFontConfig() : m_needsSave(false) , m_loaded(false) { + //default fonts + m_defaultFont[Gfx::FONT_COMMON] = "/fonts/dvu_sans.ttf"; + m_defaultFont[Gfx::FONT_COMMON_BOLD] = "/fonts/dvu_sans_bold.ttf"; + m_defaultFont[Gfx::FONT_COMMON_ITALIC] = "/fonts/dvu_sans_italic.ttf"; + m_defaultFont[Gfx::FONT_STUDIO] = "/fonts/dvu_sans_mono.ttf"; + m_defaultFont[Gfx::FONT_STUDIO_BOLD] = "/fonts/dvu_sans_mono_bold.ttf"; + m_defaultFont[Gfx::FONT_SATCOM] = "/fonts/dvu_sans.ttf"; + + m_font[Gfx::FONT_COMMON] = "FontCommon"; + m_font[Gfx::FONT_COMMON_BOLD] = "FontCommonBold"; + m_font[Gfx::FONT_COMMON_ITALIC] = "FontCommonItalic"; + m_font[Gfx::FONT_STUDIO] = "FontStudio"; + m_font[Gfx::FONT_STUDIO_BOLD] = "FontStudioBold"; + m_font[Gfx::FONT_SATCOM] = "FontSatCom"; } CFontConfig::~CFontConfig() @@ -78,90 +93,14 @@ bool CFontConfig::Init() std::string CFontConfig::GetFont(Gfx::FontType type) { - switch(type) + try { - case Gfx::FONT_COMMON: - { - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommon"); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans.ttf"; - } - } - case Gfx::FONT_COMMON_BOLD: - { - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommonBold"); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans_bold.ttf"; - } - } - case Gfx::FONT_COMMON_ITALIC: - { - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontCommonItalic"); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans_italic.ttf"; - } - } - case Gfx::FONT_STUDIO: - { - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontStudio"); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans_mono.ttf"; - } - } - case Gfx::FONT_STUDIO_BOLD: - { - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontStudioBold"); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans_mono_bold.ttf"; - } - } - case Gfx::FONT_SATCOM: - { - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get("FontSatCom"); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return "/fonts/dvu_sans.ttf"; - } - } - default: - { - GetLogger()->Debug("Incorrect font type: %i.\n", type); - return nullptr; - } + std::string path = std::string("/fonts/") + m_propertyTree.get(m_font[type]); + return path; } + catch (std::exception & e) + { + GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); + return m_defaultFont[type]; + } } diff --git a/src/common/font_config.h b/src/common/font_config.h index 594b4ce8..c28ea445 100644 --- a/src/common/font_config.h +++ b/src/common/font_config.h @@ -59,4 +59,5 @@ private: boost::property_tree::ptree m_propertyTree; bool m_needsSave; bool m_loaded; + std::map m_font, m_defaultFont; }; From 1539e94b09fc608ea66b110dc5b4d3e9a9c802c7 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Wed, 18 Oct 2017 20:40:07 +0200 Subject: [PATCH 009/109] Changed defaultFont to const map --- src/common/font_config.cpp | 24 ++++++------------------ src/common/font_config.h | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/common/font_config.cpp b/src/common/font_config.cpp index 4768cbc6..3d3ad6f0 100644 --- a/src/common/font_config.cpp +++ b/src/common/font_config.cpp @@ -42,14 +42,6 @@ CFontConfig::CFontConfig() : m_needsSave(false) , m_loaded(false) { - //default fonts - m_defaultFont[Gfx::FONT_COMMON] = "/fonts/dvu_sans.ttf"; - m_defaultFont[Gfx::FONT_COMMON_BOLD] = "/fonts/dvu_sans_bold.ttf"; - m_defaultFont[Gfx::FONT_COMMON_ITALIC] = "/fonts/dvu_sans_italic.ttf"; - m_defaultFont[Gfx::FONT_STUDIO] = "/fonts/dvu_sans_mono.ttf"; - m_defaultFont[Gfx::FONT_STUDIO_BOLD] = "/fonts/dvu_sans_mono_bold.ttf"; - m_defaultFont[Gfx::FONT_SATCOM] = "/fonts/dvu_sans.ttf"; - m_font[Gfx::FONT_COMMON] = "FontCommon"; m_font[Gfx::FONT_COMMON_BOLD] = "FontCommonBold"; m_font[Gfx::FONT_COMMON_ITALIC] = "FontCommonItalic"; @@ -93,14 +85,10 @@ bool CFontConfig::Init() std::string CFontConfig::GetFont(Gfx::FontType type) { - try - { - std::string path = std::string("/fonts/") + m_propertyTree.get(m_font[type]); - return path; - } - catch (std::exception & e) - { - GetLogger()->Log(m_loaded ? LOG_INFO : LOG_TRACE, "Error on parsing config file: %s. Default font will be used instead.\n", e.what()); - return m_defaultFont[type]; - } + return std::string("/fonts/") + m_propertyTree.get(m_font[type], GetDefaultFont(type)); } + +std::string CFontConfig::GetDefaultFont(Gfx::FontType type) const +{ + return defaultFont.at(type); +} \ No newline at end of file diff --git a/src/common/font_config.h b/src/common/font_config.h index c28ea445..5ce91aaf 100644 --- a/src/common/font_config.h +++ b/src/common/font_config.h @@ -39,6 +39,16 @@ * */ +const std::map defaultFont = +{ + { Gfx::FONT_COMMON, "dvu_sans.ttf" }, + { Gfx::FONT_COMMON_BOLD, "dvu_sans_bold.ttf" }, + { Gfx::FONT_COMMON_ITALIC, "dvu_sans_italic.ttf" }, + { Gfx::FONT_STUDIO, "dvu_sans_mono.ttf" }, + { Gfx::FONT_STUDIO_BOLD, "dvu_sans_mono_bold.ttf" }, + { Gfx::FONT_SATCOM, "dvu_sans.ttf" }, +}; + class CFontConfig { public: @@ -55,9 +65,14 @@ public: */ std::string GetFont(Gfx::FontType type); + /** Const type method to read filenames of fonts from defaultFont map + * used as a fallback if it wasn't possible to read font from fonts.ini + * \return return filename of default path + */ + std::string GetDefaultFont(Gfx::FontType type) const; private: boost::property_tree::ptree m_propertyTree; bool m_needsSave; bool m_loaded; - std::map m_font, m_defaultFont; + std::map m_font; }; From 3801ab87a2de0a494da77865f0713c37fc5463c1 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Mon, 23 Oct 2017 19:08:28 +0200 Subject: [PATCH 010/109] Changed m_font map to const fontType map --- src/common/font_config.cpp | 13 ++++++------- src/common/font_config.h | 18 +++++++++++++++++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/common/font_config.cpp b/src/common/font_config.cpp index 3d3ad6f0..8dd59eaa 100644 --- a/src/common/font_config.cpp +++ b/src/common/font_config.cpp @@ -42,12 +42,6 @@ CFontConfig::CFontConfig() : m_needsSave(false) , m_loaded(false) { - m_font[Gfx::FONT_COMMON] = "FontCommon"; - m_font[Gfx::FONT_COMMON_BOLD] = "FontCommonBold"; - m_font[Gfx::FONT_COMMON_ITALIC] = "FontCommonItalic"; - m_font[Gfx::FONT_STUDIO] = "FontStudio"; - m_font[Gfx::FONT_STUDIO_BOLD] = "FontStudioBold"; - m_font[Gfx::FONT_SATCOM] = "FontSatCom"; } CFontConfig::~CFontConfig() @@ -85,10 +79,15 @@ bool CFontConfig::Init() std::string CFontConfig::GetFont(Gfx::FontType type) { - return std::string("/fonts/") + m_propertyTree.get(m_font[type], GetDefaultFont(type)); + return std::string("/fonts/") + m_propertyTree.get(GetFontType(type), GetDefaultFont(type)); } std::string CFontConfig::GetDefaultFont(Gfx::FontType type) const { return defaultFont.at(type); +} + +std::string CFontConfig::GetFontType(Gfx::FontType type) const +{ + return fontType.at(type); } \ No newline at end of file diff --git a/src/common/font_config.h b/src/common/font_config.h index 5ce91aaf..a91e5fa0 100644 --- a/src/common/font_config.h +++ b/src/common/font_config.h @@ -49,6 +49,16 @@ const std::map defaultFont = { Gfx::FONT_SATCOM, "dvu_sans.ttf" }, }; +const std::map fontType = +{ + { Gfx::FONT_COMMON, "FontCommon" }, + { Gfx::FONT_COMMON_BOLD, "FontCommonBold" }, + { Gfx::FONT_COMMON_ITALIC, "FontCommonItalic" }, + { Gfx::FONT_STUDIO, "FontStudio" }, + { Gfx::FONT_STUDIO_BOLD, "FontStudioBold" }, + { Gfx::FONT_SATCOM, "FontSatCom" }, +}; + class CFontConfig { public: @@ -70,9 +80,15 @@ public: * \return return filename of default path */ std::string GetDefaultFont(Gfx::FontType type) const; + + /** Const type method converting Gfx::FontType to string + * \return return id of font used in fonts.ini file + */ + + std::string GetFontType(Gfx::FontType type) const; + private: boost::property_tree::ptree m_propertyTree; bool m_needsSave; bool m_loaded; - std::map m_font; }; From ff97df74c6580e0a37bc8cad9be6b4c749eae7dd Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Sat, 28 Oct 2017 22:22:22 +0200 Subject: [PATCH 011/109] Added support for italic and bold variants of studio and satcom fonts They aren't currently used anywhere --- src/common/font_config.h | 6 ++++++ src/graphics/engine/text.cpp | 14 ++++++-------- src/graphics/engine/text.h | 13 +++++++++---- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/common/font_config.h b/src/common/font_config.h index a91e5fa0..1c786f93 100644 --- a/src/common/font_config.h +++ b/src/common/font_config.h @@ -46,7 +46,10 @@ const std::map defaultFont = { Gfx::FONT_COMMON_ITALIC, "dvu_sans_italic.ttf" }, { Gfx::FONT_STUDIO, "dvu_sans_mono.ttf" }, { Gfx::FONT_STUDIO_BOLD, "dvu_sans_mono_bold.ttf" }, + { Gfx::FONT_STUDIO_ITALIC, "dvu_sans_mono_italic.ttf" }, { Gfx::FONT_SATCOM, "dvu_sans.ttf" }, + { Gfx::FONT_SATCOM_BOLD, "dvu_sans_bold.ttf" }, + { Gfx::FONT_SATCOM_ITALIC, "dvu_sans_italic.ttf" }, }; const std::map fontType = @@ -56,7 +59,10 @@ const std::map fontType = { Gfx::FONT_COMMON_ITALIC, "FontCommonItalic" }, { Gfx::FONT_STUDIO, "FontStudio" }, { Gfx::FONT_STUDIO_BOLD, "FontStudioBold" }, + { Gfx::FONT_STUDIO_ITALIC, "FontStudioItalic" }, { Gfx::FONT_SATCOM, "FontSatCom" }, + { Gfx::FONT_SATCOM_BOLD, "FontSatComBold" }, + { Gfx::FONT_SATCOM_ITALIC, "FontSatComItalic" }, }; class CFontConfig diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 8a023d67..5638c61b 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -128,14 +128,12 @@ bool CText::Create() return false; } - m_fonts[FONT_COMMON] = MakeUnique(fontConfig.GetFont(FONT_COMMON)); - m_fonts[FONT_COMMON_BOLD] = MakeUnique(fontConfig.GetFont(FONT_COMMON_BOLD)); - m_fonts[FONT_COMMON_ITALIC] = MakeUnique(fontConfig.GetFont(FONT_COMMON_ITALIC)); - - m_fonts[FONT_SATCOM] = MakeUnique(fontConfig.GetFont(FONT_SATCOM)); - - m_fonts[FONT_STUDIO] = MakeUnique(fontConfig.GetFont(FONT_STUDIO)); - m_fonts[FONT_STUDIO_BOLD] = MakeUnique(fontConfig.GetFont(FONT_STUDIO_BOLD)); + for (auto type : {FONT_COMMON, FONT_STUDIO, FONT_SATCOM}) + { + m_fonts[static_cast(type)] = MakeUnique(fontConfig.GetFont(type)); + m_fonts[static_cast(type|FONT_BOLD)] = MakeUnique(fontConfig.GetFont(static_cast(type|FONT_BOLD))); + m_fonts[static_cast(type|FONT_ITALIC)] = MakeUnique(fontConfig.GetFont(static_cast(type|FONT_ITALIC))); + } for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it) { diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h index 32d50d1f..0c5da66c 100644 --- a/src/graphics/engine/text.h +++ b/src/graphics/engine/text.h @@ -83,14 +83,19 @@ enum FontType //! Alias for italic colobot font FONT_COMMON_ITALIC = FONT_COMMON | FONT_ITALIC, - //! Courier (monospace) font used mainly in code editor (only regular & bold) + //! Studio font used mainly in code editor FONT_STUDIO = 0x01, - //! Alias for bold courier font + //! Alias for bold studio font FONT_STUDIO_BOLD = FONT_STUDIO | FONT_BOLD, + //! Alias for italic studio font (at this point not used anywhere) + FONT_STUDIO_ITALIC = FONT_STUDIO | FONT_ITALIC, - //! SatCom font used for interface - + //! SatCom font used for interface (currently bold and italic wariants aren't used anywhere) FONT_SATCOM = 0x02, + //! Alias for bold satcom font + FONT_SATCOM_BOLD = FONT_SATCOM | FONT_BOLD, + //! Alias for italic satcom font + FONT_SATCOM_ITALIC = FONT_SATCOM | FONT_ITALIC, //! Pseudo-font loaded from textures for buttons, icons, etc. FONT_BUTTON = 0x03, From 0179e4c78665a459f56763f2c177fdb63dc82d90 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Sat, 28 Oct 2017 22:24:11 +0200 Subject: [PATCH 012/109] Cleaned unused values from CFontConfig --- src/common/font_config.cpp | 3 --- src/common/font_config.h | 2 -- 2 files changed, 5 deletions(-) diff --git a/src/common/font_config.cpp b/src/common/font_config.cpp index 8dd59eaa..bad11446 100644 --- a/src/common/font_config.cpp +++ b/src/common/font_config.cpp @@ -39,8 +39,6 @@ namespace bp = boost::property_tree; CFontConfig::CFontConfig() - : m_needsSave(false) - , m_loaded(false) { } @@ -62,7 +60,6 @@ bool CFontConfig::Init() { bp::ini_parser::read_ini(*stream, m_propertyTree); GetLogger()->Debug("Fonts config file loaded correctly. \n"); - m_loaded = true; } else { diff --git a/src/common/font_config.h b/src/common/font_config.h index 1c786f93..368707fe 100644 --- a/src/common/font_config.h +++ b/src/common/font_config.h @@ -95,6 +95,4 @@ public: private: boost::property_tree::ptree m_propertyTree; - bool m_needsSave; - bool m_loaded; }; From f01e2b7e0149f49b09a13d7639f733b0919a131b Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Tue, 7 Nov 2017 19:29:51 +0100 Subject: [PATCH 013/109] Moved fonts maps from header file to source file --- src/common/font_config.cpp | 26 ++++++++++++++++++++++++++ src/common/font_config.h | 24 ------------------------ 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/common/font_config.cpp b/src/common/font_config.cpp index bad11446..e021ec0b 100644 --- a/src/common/font_config.cpp +++ b/src/common/font_config.cpp @@ -38,6 +38,32 @@ namespace bp = boost::property_tree; +const std::map defaultFont = +{ + { Gfx::FONT_COMMON, "dvu_sans.ttf" }, + { Gfx::FONT_COMMON_BOLD, "dvu_sans_bold.ttf" }, + { Gfx::FONT_COMMON_ITALIC, "dvu_sans_italic.ttf" }, + { Gfx::FONT_STUDIO, "dvu_sans_mono.ttf" }, + { Gfx::FONT_STUDIO_BOLD, "dvu_sans_mono_bold.ttf" }, + { Gfx::FONT_STUDIO_ITALIC, "dvu_sans_mono_italic.ttf" }, + { Gfx::FONT_SATCOM, "dvu_sans.ttf" }, + { Gfx::FONT_SATCOM_BOLD, "dvu_sans_bold.ttf" }, + { Gfx::FONT_SATCOM_ITALIC, "dvu_sans_italic.ttf" }, +}; + +const std::map fontType = +{ + { Gfx::FONT_COMMON, "FontCommon" }, + { Gfx::FONT_COMMON_BOLD, "FontCommonBold" }, + { Gfx::FONT_COMMON_ITALIC, "FontCommonItalic" }, + { Gfx::FONT_STUDIO, "FontStudio" }, + { Gfx::FONT_STUDIO_BOLD, "FontStudioBold" }, + { Gfx::FONT_STUDIO_ITALIC, "FontStudioItalic" }, + { Gfx::FONT_SATCOM, "FontSatCom" }, + { Gfx::FONT_SATCOM_BOLD, "FontSatComBold" }, + { Gfx::FONT_SATCOM_ITALIC, "FontSatComItalic" }, +}; + CFontConfig::CFontConfig() { } diff --git a/src/common/font_config.h b/src/common/font_config.h index 368707fe..96d9efe3 100644 --- a/src/common/font_config.h +++ b/src/common/font_config.h @@ -39,31 +39,7 @@ * */ -const std::map defaultFont = -{ - { Gfx::FONT_COMMON, "dvu_sans.ttf" }, - { Gfx::FONT_COMMON_BOLD, "dvu_sans_bold.ttf" }, - { Gfx::FONT_COMMON_ITALIC, "dvu_sans_italic.ttf" }, - { Gfx::FONT_STUDIO, "dvu_sans_mono.ttf" }, - { Gfx::FONT_STUDIO_BOLD, "dvu_sans_mono_bold.ttf" }, - { Gfx::FONT_STUDIO_ITALIC, "dvu_sans_mono_italic.ttf" }, - { Gfx::FONT_SATCOM, "dvu_sans.ttf" }, - { Gfx::FONT_SATCOM_BOLD, "dvu_sans_bold.ttf" }, - { Gfx::FONT_SATCOM_ITALIC, "dvu_sans_italic.ttf" }, -}; -const std::map fontType = -{ - { Gfx::FONT_COMMON, "FontCommon" }, - { Gfx::FONT_COMMON_BOLD, "FontCommonBold" }, - { Gfx::FONT_COMMON_ITALIC, "FontCommonItalic" }, - { Gfx::FONT_STUDIO, "FontStudio" }, - { Gfx::FONT_STUDIO_BOLD, "FontStudioBold" }, - { Gfx::FONT_STUDIO_ITALIC, "FontStudioItalic" }, - { Gfx::FONT_SATCOM, "FontSatCom" }, - { Gfx::FONT_SATCOM_BOLD, "FontSatComBold" }, - { Gfx::FONT_SATCOM_ITALIC, "FontSatComItalic" }, -}; class CFontConfig { From da1b7e8c2d16c7f989d8cba7b5f9ecf28c88e4e2 Mon Sep 17 00:00:00 2001 From: B-CE <36107363+B-CE@users.noreply.github.com> Date: Mon, 19 Feb 2018 00:35:01 +0100 Subject: [PATCH 014/109] Fixes #274 : pasting tabs --- src/ui/controls/edit.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/ui/controls/edit.cpp b/src/ui/controls/edit.cpp index f5e02671..5a117ad9 100644 --- a/src/ui/controls/edit.cpp +++ b/src/ui/controls/edit.cpp @@ -2537,6 +2537,8 @@ bool CEdit::Paste() { char c; char* text; + int iTabToInsert=0; + int iTmp; //temp for tab space equivalant insertion if ( !m_bEdit ) { @@ -2551,20 +2553,36 @@ bool CEdit::Paste() } UndoMemorize(OPERUNDO_SPEC); - for ( unsigned int i = 0; i < strlen(text); i++ ) + for (unsigned int i = 0; iGetEditIndentValue()*iTabToInsert; iTmp>0; --iTmp) + InsertOne(' '); + iTabToInsert=0; } InsertOne(c); } - + if (0=m_len || '\n'!=m_text[m_cursor1])) + for (iTmp=m_engine->GetEditIndentValue() ; iTmp>0; --iTmp) + InsertOne(' '); SDL_free(text); Justif(); ColumnFix(); @@ -2869,7 +2887,7 @@ int CEdit::IndentTabCount() return nb; } -// Adds or removes qq tabs. +// Adds or removes some tabs. void CEdit::IndentTabAdjust(int number) { From db72a3631593757c003da16f0a9056b0ce47dfde Mon Sep 17 00:00:00 2001 From: krzys-h Date: Tue, 8 May 2018 19:44:24 +0200 Subject: [PATCH 015/109] Fix code style --- src/CBot/CBotToken.cpp | 12 +++++++----- src/level/parser/parserparam.cpp | 4 ++-- src/level/scoreboard.h | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/CBot/CBotToken.cpp b/src/CBot/CBotToken.cpp index 9663e299..ea31fad9 100644 --- a/src/CBot/CBotToken.cpp +++ b/src/CBot/CBotToken.cpp @@ -26,7 +26,8 @@ namespace CBot { -namespace { +namespace +{ template boost::bimap makeBimap(std::initializer_list::value_type> list) { @@ -449,10 +450,11 @@ std::unique_ptr CBotToken::CompileTokens(const std::string& program) //////////////////////////////////////////////////////////////////////////////// int CBotToken::GetKeyWord(const std::string& w) { - auto it = KEYWORDS.right.find(w); - if (it != KEYWORDS.right.end()) { - return it->second; - } + auto it = KEYWORDS.right.find(w); + if (it != KEYWORDS.right.end()) + { + return it->second; + } return -1; } diff --git a/src/level/parser/parserparam.cpp b/src/level/parser/parserparam.cpp index 751654c2..48cc9ae8 100644 --- a/src/level/parser/parserparam.cpp +++ b/src/level/parser/parserparam.cpp @@ -957,9 +957,9 @@ int CLevelParserParam::AsResearchFlag(int def) SortType CLevelParserParam::ToSortType(std::string value) { - if (value == "Points" ) return SortType::SORT_POINTS; + if (value == "Points") return SortType::SORT_POINTS; if (value == "Name" ) return SortType::SORT_ID; - return SortType::SORT_ID; + return SortType::SORT_ID; } SortType CLevelParserParam::AsSortType() diff --git a/src/level/scoreboard.h b/src/level/scoreboard.h index c9be19fb..7ed67ad1 100644 --- a/src/level/scoreboard.h +++ b/src/level/scoreboard.h @@ -39,7 +39,7 @@ class CObject; struct Score { int points = 0; //! Team score - float time = 0; //! Time when points were scored + float time = 0; //! Time when points were scored }; enum class SortType From dd40c4d4eef164e36dd27e0db083566422a58479 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Tue, 8 May 2018 19:54:25 +0200 Subject: [PATCH 016/109] Make magnifyDamage=0 for fragile objects actually work This fixes a bug in 36d2cf14b8432ac54571fab98c2a92a25751fd2b --- src/object/old_object.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 80b65c4d..23a303aa 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -1089,6 +1089,10 @@ void COldObject::Read(CLevelParserLine* line) { SetRange(line->GetParam("range")->AsFloat(30.0f)); } + if (Implements(ObjectInterfaceType::Fragile)) + { + SetMagnifyDamage(line->GetParam("magnifyDamage")->AsFloat(1.0f)); // TODO: This is a temporary hack for now - CFragileObject doesn't have SetMagnifyDamage ~krzys_h + } if (Implements(ObjectInterfaceType::Shielded)) { SetShield(line->GetParam("shield")->AsFloat(1.0f)); From 05bdd74bef0d65c532bce50d241ba6d0603b056a Mon Sep 17 00:00:00 2001 From: krzys-h Date: Tue, 8 May 2018 20:27:11 +0200 Subject: [PATCH 017/109] Update data submodule --- data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data b/data index b2792c32..10b07763 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit b2792c325a6e6871311207559199f77f35bbe524 +Subproject commit 10b07763fb68f53840d402ad36817e86603c63a6 From f03c3dbc10d7052bd28556b044ad0edfd778350e Mon Sep 17 00:00:00 2001 From: krzys-h Date: Tue, 8 May 2018 23:44:23 +0200 Subject: [PATCH 018/109] Implement ScoreboardObjectRule --- src/level/robotmain.cpp | 11 +++++++++++ src/level/scene_conditions.cpp | 24 ++++++++++++------------ src/level/scene_conditions.h | 7 +++---- src/level/scoreboard.cpp | 28 ++++++++++++++++++++++++++++ src/level/scoreboard.h | 22 ++++++++++++++++++++++ 5 files changed, 76 insertions(+), 16 deletions(-) diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index ceb8daa9..441b244d 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -2527,6 +2527,8 @@ bool CRobotMain::EventFrame(const Event &event) { CheckEndMission(true); UpdateAudio(true); + if (m_scoreboard) + m_scoreboard->UpdateObjectCount(); } if (m_winDelay > 0.0f && !m_editLock) @@ -3608,6 +3610,15 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) m_scoreboard->AddKillRule(std::move(rule)); continue; } + if (line->GetCommand() == "ScoreboardObjectRule" && !resetObject) + { + if (!m_scoreboard) + throw CLevelParserException("ScoreboardObjectRule encountered but scoreboard is not enabled"); + auto rule = MakeUnique(); + rule->Read(line.get()); + m_scoreboard->AddObjectRule(std::move(rule)); + continue; + } if (line->GetCommand() == "ScoreboardEndTakeRule" && !resetObject) { if (!m_scoreboard) diff --git a/src/level/scene_conditions.cpp b/src/level/scene_conditions.cpp index 3ab32dac..263ee399 100644 --- a/src/level/scene_conditions.cpp +++ b/src/level/scene_conditions.cpp @@ -112,6 +112,18 @@ bool CObjectCondition::CheckForObject(CObject* obj) return false; } +int CObjectCondition::CountObjects() +{ + int nb = 0; + for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) + { + if (!obj->GetActive()) continue; + if (!CheckForObject(obj)) continue; + nb ++; + } + return nb; +} + void CSceneCondition::Read(CLevelParserLine* line) { CObjectCondition::Read(line); @@ -124,18 +136,6 @@ void CSceneCondition::Read(CLevelParserLine* line) this->max = line->GetParam("max")->AsInt(9999); } -int CSceneCondition::CountObjects() -{ - int nb = 0; - for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) - { - if (!obj->GetActive()) continue; - if (!CheckForObject(obj)) continue; - nb ++; - } - return nb; -} - bool CSceneCondition::Check() { int nb = CountObjects(); diff --git a/src/level/scene_conditions.h b/src/level/scene_conditions.h index 412a45b3..218c668d 100644 --- a/src/level/scene_conditions.h +++ b/src/level/scene_conditions.h @@ -58,6 +58,9 @@ public: //! Checks if this condition is met bool CheckForObject(CObject* obj); + + //! Count all object matching the conditions + int CountObjects(); }; /** @@ -75,10 +78,6 @@ public: //! Checks if this condition is met bool Check(); - -protected: - //! Count all object matching the conditions - int CountObjects(); }; /** diff --git a/src/level/scoreboard.cpp b/src/level/scoreboard.cpp index bfadc4d0..0c2f5d87 100644 --- a/src/level/scoreboard.cpp +++ b/src/level/scoreboard.cpp @@ -43,6 +43,13 @@ void CScoreboard::CScoreboardKillRule::Read(CLevelParserLine* line) CObjectCondition::Read(line); } +void CScoreboard::CScoreboardObjectRule::Read(CLevelParserLine* line) +{ + CScoreboardRule::Read(line); + CObjectCondition::Read(line); + this->winTeam = line->GetParam("winTeam")->AsInt(); +} + void CScoreboard::CScoreboardEndTakeRule::Read(CLevelParserLine* line) { CScoreboardRule::Read(line); @@ -55,6 +62,11 @@ void CScoreboard::AddKillRule(std::unique_ptr rule) m_rulesKill.push_back(std::move(rule)); } +void CScoreboard::AddObjectRule(std::unique_ptr rule) +{ + m_rulesObject.push_back(std::move(rule)); +} + void CScoreboard::AddEndTakeRule(std::unique_ptr rule) { m_rulesEndTake.push_back(std::move(rule)); @@ -75,6 +87,22 @@ void CScoreboard::ProcessKill(CObject* target, CObject* killer) } } +void CScoreboard::UpdateObjectCount() +{ + for (auto& rule : m_rulesObject) + { + assert(rule->winTeam != 0); + int count = rule->CountObjects(); + int countDiff = count - rule->lastCount; + printf("%d %d\n", count, countDiff); + if (countDiff != 0) + { + rule->lastCount = count; + AddPoints(rule->winTeam, rule->score * countDiff); + } + } +} + void CScoreboard::ProcessEndTake(int team) { if (team == 0) return; diff --git a/src/level/scoreboard.h b/src/level/scoreboard.h index 7ed67ad1..313e326c 100644 --- a/src/level/scoreboard.h +++ b/src/level/scoreboard.h @@ -64,6 +64,7 @@ enum class SortType * ScoreboardSortType sort=Name // sort teams alphabetically, another option is sort=Points, sorting teams in order of points * ScoreboardKillRule type=WheeledShooter team=1 score=500 // destruction of team 1's WheeledShooter gives 100 points to the team that destroyed it * ScoreboardKillRule type=TargetBot score=100 // destruction of TargetBot (any team) gives 100 points + * ScoreboardObjectRule pos=0.0;0.5 dist=5.0 type=Titanium winTeam=1 score=5 // each Titanium within 5 meters of 0;0 gives team 1 5 points, losing Titanium gives -5 * ScoreboardEndTakeRule score=1000 // completion of EndMissionTake objectives for any team results in 1000 points for that team * \endcode */ @@ -102,6 +103,22 @@ public: void Read(CLevelParserLine* line) override; }; + /** + * \class CScoreboardObjectRule + * \brief Scoreboard rule for counting objects + * \see CScoreboard::AddObjectRule() + */ + class CScoreboardObjectRule final : public CScoreboardRule, public CObjectCondition + { + public: + int winTeam = 0; + + //! Read from line in scene file + void Read(CLevelParserLine* line) override; + + int lastCount = 0; + }; + /** * \class CScoreboardEndTakeRule * \brief Scoreboard rule for EndMissionTake rewards @@ -120,6 +137,8 @@ public: public: //! Add ScoreboardKillRule void AddKillRule(std::unique_ptr rule); + //! Add ScoreboardObjectRule + void AddObjectRule(std::unique_ptr rule); //! Add ScoreboardEndTakeRule void AddEndTakeRule(std::unique_ptr rule); @@ -127,6 +146,8 @@ public: //! \param target The object that has just been destroyed //! \param killer The object that caused the destruction, can be null void ProcessKill(CObject* target, CObject* killer = nullptr); + //! Updates the object count rules + void UpdateObjectCount(); //! Called after EndTake contition has been met, used to handle ScoreboardEndTakeRule void ProcessEndTake(int team); @@ -139,6 +160,7 @@ public: private: std::vector> m_rulesKill = {}; + std::vector> m_rulesObject = {}; std::vector> m_rulesEndTake = {}; std::map m_score; int m_finishCounter = 0; From 0baf9f8077c4681c37107c21859987c3dc2474df Mon Sep 17 00:00:00 2001 From: krzys-h Date: Tue, 8 May 2018 23:47:50 +0200 Subject: [PATCH 019/109] Don't commit code in a hurry like that... --- src/level/scoreboard.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/level/scoreboard.cpp b/src/level/scoreboard.cpp index 0c2f5d87..18ad9684 100644 --- a/src/level/scoreboard.cpp +++ b/src/level/scoreboard.cpp @@ -94,7 +94,6 @@ void CScoreboard::UpdateObjectCount() assert(rule->winTeam != 0); int count = rule->CountObjects(); int countDiff = count - rule->lastCount; - printf("%d %d\n", count, countDiff); if (countDiff != 0) { rule->lastCount = count; From a3def6d6835f90ea482467f4bb64cdb36d1cfc6d Mon Sep 17 00:00:00 2001 From: krzys-h Date: Tue, 8 May 2018 23:57:13 +0200 Subject: [PATCH 020/109] Disallow firendly fire in ScoreboardKillRule --- src/level/scoreboard.cpp | 3 +++ src/level/scoreboard.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/level/scoreboard.cpp b/src/level/scoreboard.cpp index 18ad9684..78afa482 100644 --- a/src/level/scoreboard.cpp +++ b/src/level/scoreboard.cpp @@ -41,6 +41,7 @@ void CScoreboard::CScoreboardKillRule::Read(CLevelParserLine* line) { CScoreboardRule::Read(line); CObjectCondition::Read(line); + this->friendlyFire = line->GetParam("friendlyFire")->AsBool(false); } void CScoreboard::CScoreboardObjectRule::Read(CLevelParserLine* line) @@ -82,6 +83,8 @@ void CScoreboard::ProcessKill(CObject* target, CObject* killer) killer->GetTeam() != 0 && rule->CheckForObject(target)) { + if (killer->GetTeam() == target->GetTeam() && !rule->friendlyFire) + continue; AddPoints(killer->GetTeam(), rule->score); } } diff --git a/src/level/scoreboard.h b/src/level/scoreboard.h index 313e326c..4a094912 100644 --- a/src/level/scoreboard.h +++ b/src/level/scoreboard.h @@ -99,6 +99,8 @@ public: class CScoreboardKillRule final : public CScoreboardRule, public CObjectCondition { public: + bool friendlyFire = false; + //! Read from line in scene file void Read(CLevelParserLine* line) override; }; From 807d6e40e3cd8900c5f5bd72b3c9010c86f2602a Mon Sep 17 00:00:00 2001 From: AbigailBuccaneer Date: Wed, 9 May 2018 08:49:23 +0100 Subject: [PATCH 021/109] Fix -Wsuggest-override compile errors in tests Fixes #1160 --- test/unit/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index c21fb600..cd606397 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -63,3 +63,9 @@ add_test( COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/colobot_ut WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ) + +# GoogleTest isn't compatible with -Wsuggest-override -Werror: +# see https://github.com/google/googletest/issues/1063 +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) + target_compile_options(colobot_ut PRIVATE "-Wno-suggest-override") +endif() From 94a18e9648dc5deb46297c99f0460ca15e93010e Mon Sep 17 00:00:00 2001 From: krzys-h Date: Wed, 9 May 2018 17:23:27 +0200 Subject: [PATCH 022/109] Add version override to release script NOT TESTED! --- tools/release.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/tools/release.py b/tools/release.py index 6ab155af..03e83b6f 100755 --- a/tools/release.py +++ b/tools/release.py @@ -25,6 +25,16 @@ import sys import subprocess import io +version_override = None +if len(sys.argv) > 1: + m = re.match(r'^(.*?)\.(.*?)\.(.*)$', sys.argv[1]) + if m is None: + print('\033[1;31m[!] Unable to parse version override argument\033[0m') + sys.exit(1) + version_override = (m.group(1), m.group(2), m.group(3)) + print('\033[1;34m[*] Version override: '+('%s.%s.%s' % version_override)+'\033[0m') + + try: git_root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).strip() except subprocess.CalledProcessError: @@ -65,16 +75,24 @@ data = open('CMakeLists.txt', 'r').readlines() for i in range(len(data)): m = re.match(r'^set\(COLOBOT_VERSION_(MAJOR|MINOR|REVISION)( +)([0-9]+)\)$', data[i]) if m: - x = int(m.group(3)) + x = m.group(3) if m.group(1) == 'MAJOR': - major = x + if version_override is None: + major = x + else: + major = version_override[0] elif m.group(1) == 'MINOR': - minor = x + if version_override is None: + minor = x + else: + minor = version_override[1] elif m.group(1) == 'REVISION': - # Increase revision number - x += 1 - revision = x - data[i] = 'set(COLOBOT_VERSION_'+m.group(1)+m.group(2)+str(x)+')\n' + if version_override is None: + # Increase revision number + revision = str(int(x) + 1) + else: + revision = version_override[2] + data[i] = 'set(COLOBOT_VERSION_'+m.group(1)+m.group(2)+x+')\n' m = re.match(r'^(#?)set\(COLOBOT_VERSION_(UNRELEASED|RELEASE_CODENAME)( +)"(.+)"\)$', data[i]) if m: @@ -84,8 +102,8 @@ for i in range(len(data)): data[i] = ('#' if comment else '')+'set(COLOBOT_VERSION_'+m.group(2)+m.group(3)+'"'+m.group(4)+'")\n' subprocess.check_call(['git', 'checkout', 'master']) -version = '%d.%d.%d%s' % (major, minor, revision, codename) -version_human = '%s %d.%d.%d' % (codename.strip('-'), major, minor, revision) +version = '%s.%s.%s%s' % (major, minor, revision, codename) +version_human = '%s %s.%s.%s' % (codename.strip('-'), major, minor, revision) print('\033[1;32m[+] Building version '+version+'\033[0m') print('\033[1;34m[*] Merge data...\033[0m') From abe489e2944f8f4f98283e2367dc02a8862c932f Mon Sep 17 00:00:00 2001 From: krzys-h Date: Wed, 9 May 2018 17:47:21 +0200 Subject: [PATCH 023/109] Add EndMissionTimeout --- po/colobot.pot | 4 +++ po/cs.po | 4 +++ po/de.po | 4 +++ po/fr.po | 13 +++++---- po/pl.po | 4 +++ po/ru.po | 4 +++ src/common/restext.cpp | 1 + src/common/restext.h | 3 +- src/level/robotmain.cpp | 63 +++++++++++++++++++++++++++++++---------- src/level/robotmain.h | 1 + 10 files changed, 79 insertions(+), 22 deletions(-) diff --git a/po/colobot.pot b/po/colobot.pot index 419b88e9..5d71af8c 100644 --- a/po/colobot.pot +++ b/po/colobot.pot @@ -266,6 +266,10 @@ msgstr "" msgid "The battle has ended" msgstr "" +#, c-format +msgid "Time: %s" +msgstr "" + #, c-format msgid "%s: %d pts" msgstr "" diff --git a/po/cs.po b/po/cs.po index 867a8482..555df720 100644 --- a/po/cs.po +++ b/po/cs.po @@ -1546,6 +1546,10 @@ msgstr "Úder (\\key action;)" msgid "Thumper" msgstr "Buchar" +#, c-format +msgid "Time: %s" +msgstr "" + msgid "Titanium" msgstr "Titan" diff --git a/po/de.po b/po/de.po index 1c839a09..553ead83 100644 --- a/po/de.po +++ b/po/de.po @@ -1563,6 +1563,10 @@ msgstr "Stampfen (\\key action;)" msgid "Thumper" msgstr "Stampfer" +#, c-format +msgid "Time: %s" +msgstr "" + msgid "Titanium" msgstr "Titan" diff --git a/po/fr.po b/po/fr.po index 1dd2d7f4..ce3f5fdf 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1,7 +1,6 @@ # Didier Raboud , 2012, 2015, 2016. # Martin Quinson , 2016 # B-CE, 2018 - msgid "" msgstr "" "Project-Id-Version: Colobot 0.1.11\n" @@ -174,10 +173,10 @@ msgstr "Sang\\Afficher du sang quand le cosmonaute est touché" msgid "Blue" msgstr "Bleue" + # tocheck : for team (fem): bleue # tocheck : for flag/pen/bot (masc): bleu # + capital also to check - msgid "Blue flag" msgstr "Drapeau bleu" @@ -566,8 +565,8 @@ msgstr "Séquences cinématiques\\Films avant ou après une mission" msgid "Finish" msgstr "But/Objectif" -# OBJECT_END : GoalArea +# OBJECT_END : GoalArea msgid "Fixed mine" msgstr "Mine fixe" @@ -857,7 +856,6 @@ msgstr "Chargement du terrain" # msgstr "" # msgid "Speed 6.0x\\Sextuple speed" # msgstr "" - msgid "Lower speed\\Decrease speed by half" msgstr "Moins rapide\\Diminuer la vitesse de moitié" @@ -1257,8 +1255,8 @@ msgstr "Robot recycleur" msgid "Red" msgstr "Rouge" -# toCheck : capital (for team?) +# toCheck : capital (for team?) msgid "Red flag" msgstr "Drapeau rouge" @@ -1568,6 +1566,10 @@ msgstr "Secoue (\\key action;)" msgid "Thumper" msgstr "Robot secoueur" +#, c-format +msgid "Time: %s" +msgstr "" + msgid "Titanium" msgstr "Titane" @@ -2048,4 +2050,3 @@ msgstr "epsitec.com" #~ msgid "\\c; (none)\\n;\n" #~ msgstr "\\c; (aucun)\\n;\n" - diff --git a/po/pl.po b/po/pl.po index bb288518..f9f76de8 100644 --- a/po/pl.po +++ b/po/pl.po @@ -1545,6 +1545,10 @@ msgstr "Uderz (\\key action;)" msgid "Thumper" msgstr "Uderzacz" +#, c-format +msgid "Time: %s" +msgstr "Czas: %s" + msgid "Titanium" msgstr "Tytan" diff --git a/po/ru.po b/po/ru.po index f2b25354..0763e742 100644 --- a/po/ru.po +++ b/po/ru.po @@ -1576,6 +1576,10 @@ msgstr "Удар (\\key action;)" msgid "Thumper" msgstr "Ударник" +#, c-format +msgid "Time: %s" +msgstr "" + msgid "Titanium" msgstr "Титан" diff --git a/src/common/restext.cpp b/src/common/restext.cpp index c5704362..9bac8434 100644 --- a/src/common/restext.cpp +++ b/src/common/restext.cpp @@ -145,6 +145,7 @@ void InitializeRestext() stringsText[RT_SCOREBOARD_RESULTS] = TR("Results"); stringsText[RT_SCOREBOARD_RESULTS_TEXT]= TR("The battle has ended"); + stringsText[RT_SCOREBOARD_RESULTS_TIME]= TR("Time: %s"); stringsText[RT_SCOREBOARD_RESULTS_LINE]= TR("%s: %d pts"); diff --git a/src/common/restext.h b/src/common/restext.h index 80808468..6acfb610 100644 --- a/src/common/restext.h +++ b/src/common/restext.h @@ -142,7 +142,8 @@ enum ResTextType RT_SCOREBOARD_RESULTS = 230, RT_SCOREBOARD_RESULTS_TEXT= 231, - RT_SCOREBOARD_RESULTS_LINE= 232, + RT_SCOREBOARD_RESULTS_TIME= 232, + RT_SCOREBOARD_RESULTS_LINE= 233, RT_MAX //! < number of values diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 441b244d..03fb5314 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -2703,6 +2703,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) m_endTake.clear(); m_endTakeImmediat = false; m_endTakeResearch = 0; + m_endTakeTimeout = -1.0f; m_endTakeWinDelay = 2.0f; m_endTakeLostDelay = 2.0f; m_teamFinished.clear(); @@ -3584,6 +3585,11 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) m_endTakeResearch |= line->GetParam("type")->AsResearchFlag(); continue; } + if (line->GetCommand() == "EndMissionTimeout" && !resetObject) + { + m_endTakeTimeout = line->GetParam("time")->AsFloat(); + continue; + } if (line->GetCommand() == "Scoreboard" && !resetObject) { @@ -3597,7 +3603,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) if (line->GetCommand() == "ScoreboardSortType" && !resetObject) { - m_scoreboard->SetSortType(static_cast(line->GetParam("sort")->AsSortType() ) ); + m_scoreboard->SetSortType(line->GetParam("sort")->AsSortType()); continue; } @@ -4979,6 +4985,22 @@ Error CRobotMain::ProcessEndMissionTakeForGroup(std::vector //! If return value is different than ERR_MISSION_NOTERM, assume the mission is finished and pass on the result Error CRobotMain::ProcessEndMissionTake() { + bool timeout = false; + if (m_missionResult != INFO_LOST && m_missionResult != INFO_LOSTq) + { + if (m_endTakeTimeout >= 0.0f) + { + // Use the mission timer if available, or global mission time otherwise + // Useful for exercises where the time starts when you start the program, not the mission itself + float currentTime = m_missionTimerEnabled ? m_missionTimer : m_gameTime; + if (currentTime > m_endTakeTimeout) + { + m_missionResult = INFO_LOST; + timeout = true; + } + } + } + // Sort end conditions by teams std::map> teamsEndTake; for (std::unique_ptr& endTake : m_endTake) @@ -4989,21 +5011,43 @@ Error CRobotMain::ProcessEndMissionTake() if (!usesTeamConditions) { - m_missionResult = ProcessEndMissionTakeForGroup(teamsEndTake[0]); + if (!timeout) + m_missionResult = ProcessEndMissionTakeForGroup(teamsEndTake[0]); + + if (m_missionResult != INFO_LOST && m_missionResult != INFO_LOSTq) + { + if (m_endTakeResearch != 0) + { + if (m_endTakeResearch != (m_endTakeResearch&m_researchDone[0])) + { + m_missionResult = ERR_MISSION_NOTERM; + } + } + } } else { + assert(m_endTakeResearch == 0); // TODO: Add support for per-team EndTakeResearch + // Special handling for teams m_missionResult = ERR_MISSION_NOTERM; - if (GetAllActiveTeams().empty()) + if (GetAllActiveTeams().empty() || timeout) { GetLogger()->Info("All teams died, mission ended\n"); if (m_scoreboard) { std::string title, text, details_line; GetResource(RES_TEXT, RT_SCOREBOARD_RESULTS, title); - GetResource(RES_TEXT, RT_SCOREBOARD_RESULTS_TEXT, text); + if (m_missionTimerEnabled && m_missionTimerStarted) + { + GetResource(RES_TEXT, RT_SCOREBOARD_RESULTS_TIME, text); + text = StrUtils::Format(text.c_str(), TimeFormat(m_missionTimer).c_str()); + } + else + { + GetResource(RES_TEXT, RT_SCOREBOARD_RESULTS_TEXT, text); + } GetResource(RES_TEXT, RT_SCOREBOARD_RESULTS_LINE, details_line); std::string details = ""; for (int team : GetAllTeams()) @@ -5086,17 +5130,6 @@ Error CRobotMain::ProcessEndMissionTake() } } - if (m_missionResult != INFO_LOST && m_missionResult != INFO_LOSTq) - { - if (m_endTakeResearch != 0) - { - if (m_endTakeResearch != (m_endTakeResearch&m_researchDone[0])) - { - m_missionResult = ERR_MISSION_NOTERM; - } - } - } - return ERR_MISSION_NOTERM; } diff --git a/src/level/robotmain.h b/src/level/robotmain.h index 1e19d514..7f0111ea 100644 --- a/src/level/robotmain.h +++ b/src/level/robotmain.h @@ -672,6 +672,7 @@ protected: //! If true, the mission ends immediately after completing the requirements without requiring SpaceShip takeoff bool m_endTakeImmediat = false; long m_endTakeResearch = 0; + float m_endTakeTimeout = -1.0f; float m_endTakeWinDelay = 0.0f; float m_endTakeLostDelay = 0.0f; //! Set to true for teams that have already finished From c027b54add0853c02a10598b0ee847cc8d77e605 Mon Sep 17 00:00:00 2001 From: AbigailBuccaneer Date: Fri, 4 May 2018 18:13:24 +0100 Subject: [PATCH 024/109] Don't create a color renderbuffer for shadow map When rendering the shadow map offscreen using framebuffer objects, it's not necessary to create a color renderbuffer. Currently FramebufferParams only lets you choose between a renderbuffer and a texture for both color and depth attachments. This changes that, and now you can ask for a texture, a renderbuffer, or nothing. This improves performance. On my computer, with an 8192x8192 shadow map, this improves overall frame time by 8.0%. --- src/graphics/core/framebuffer.h | 13 +++++++++---- src/graphics/engine/engine.cpp | 3 ++- src/graphics/opengl/glframebuffer.cpp | 24 ++++++++++++++++-------- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/graphics/core/framebuffer.h b/src/graphics/core/framebuffer.h index e668b036..3c5e6de8 100644 --- a/src/graphics/core/framebuffer.h +++ b/src/graphics/core/framebuffer.h @@ -41,10 +41,15 @@ struct FramebufferParams int depth = 16; //! Requested number of samples for multisampling int samples = 1; - //! true requests color texture - bool colorTexture = false; - //! true requests depth texture - bool depthTexture = false; + + enum class AttachmentType + { + Texture, + Renderbuffer, + None, + }; + AttachmentType colorAttachment = AttachmentType::Renderbuffer; + AttachmentType depthAttachment = AttachmentType::Renderbuffer; //! Loads default values void LoadDefault() diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 40d4d1d1..4dfec9ca 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -3786,7 +3786,8 @@ void CEngine::RenderShadowMap() FramebufferParams params; params.width = params.height = width; params.depth = depth = 32; - params.depthTexture = true; + params.colorAttachment = FramebufferParams::AttachmentType::None; + params.depthAttachment = FramebufferParams::AttachmentType::Texture; CFramebuffer *framebuffer = m_device->CreateFramebuffer("shadow", params); if (framebuffer == nullptr) diff --git a/src/graphics/opengl/glframebuffer.cpp b/src/graphics/opengl/glframebuffer.cpp index c58d90d7..75fe020a 100644 --- a/src/graphics/opengl/glframebuffer.cpp +++ b/src/graphics/opengl/glframebuffer.cpp @@ -55,7 +55,7 @@ bool CGLFramebuffer::Create() glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); // create color texture - if (m_params.colorTexture) + if (m_params.colorAttachment == FramebufferParams::AttachmentType::Texture) { GLint previous; glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous); @@ -76,7 +76,7 @@ bool CGLFramebuffer::Create() glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorTexture, 0); } // create color renderbuffer - else + else if (m_params.colorAttachment == FramebufferParams::AttachmentType::Renderbuffer) { glGenRenderbuffers(1, &m_colorRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); @@ -92,6 +92,10 @@ bool CGLFramebuffer::Create() glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRenderbuffer); } + else + { + glDrawBuffer(GL_NONE); + } GLuint depthFormat = 0; @@ -104,7 +108,7 @@ bool CGLFramebuffer::Create() } // create depth texture - if (m_params.depthTexture) + if (m_params.depthAttachment == FramebufferParams::AttachmentType::Texture) { GLint previous; glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous); @@ -132,7 +136,7 @@ bool CGLFramebuffer::Create() GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0); } // create depth renderbuffer - else + else if (m_params.depthAttachment == FramebufferParams::AttachmentType::Renderbuffer) { glGenRenderbuffers(1, &m_depthRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer); @@ -323,7 +327,7 @@ bool CGLFramebufferEXT::Create() glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); // create color texture - if (m_params.colorTexture) + if (m_params.colorAttachment == FramebufferParams::AttachmentType::Texture) { GLint previous; glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous); @@ -346,7 +350,7 @@ bool CGLFramebufferEXT::Create() GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_colorTexture, 0); } // create color renderbuffer - else + else if (m_params.colorAttachment == FramebufferParams::AttachmentType::Renderbuffer) { glGenRenderbuffersEXT(1, &m_colorRenderbuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_colorRenderbuffer); @@ -363,6 +367,10 @@ bool CGLFramebufferEXT::Create() glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_colorRenderbuffer); } + else + { + glDrawBuffer(GL_NONE); + } GLuint depthFormat = 0; @@ -375,7 +383,7 @@ bool CGLFramebufferEXT::Create() } // create depth texture - if (m_params.depthTexture) + if (m_params.depthAttachment == FramebufferParams::AttachmentType::Texture) { GLint previous; glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous); @@ -403,7 +411,7 @@ bool CGLFramebufferEXT::Create() GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, m_depthTexture, 0); } // create depth renderbuffer - else + else if (m_params.depthAttachment == FramebufferParams::AttachmentType::Renderbuffer) { glGenRenderbuffersEXT(1, &m_depthRenderbuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthRenderbuffer); From 1ed3f4b21550eb7478100e3fce4d5b9fabb05c06 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Wed, 9 May 2018 18:28:25 +0200 Subject: [PATCH 025/109] Add EndMissionTeams immediateWin=true; make the teams on win screen sorted --- src/level/parser/parserparam.cpp | 12 +++++----- src/level/parser/parserparam.h | 6 ++--- src/level/robotmain.cpp | 41 ++++++++++++++++++-------------- src/level/robotmain.h | 1 + src/level/scoreboard.cpp | 29 ++++++++++++++++++---- src/level/scoreboard.h | 40 ++++++++++++++++++------------- 6 files changed, 81 insertions(+), 48 deletions(-) diff --git a/src/level/parser/parserparam.cpp b/src/level/parser/parserparam.cpp index 48cc9ae8..c4ee9b31 100644 --- a/src/level/parser/parserparam.cpp +++ b/src/level/parser/parserparam.cpp @@ -955,21 +955,21 @@ int CLevelParserParam::AsResearchFlag(int def) return AsResearchFlag(); } -SortType CLevelParserParam::ToSortType(std::string value) +CScoreboard::SortType CLevelParserParam::ToSortType(std::string value) { - if (value == "Points") return SortType::SORT_POINTS; - if (value == "Name" ) return SortType::SORT_ID; - return SortType::SORT_ID; + if (value == "Points") return CScoreboard::SortType::SORT_POINTS; + if (value == "Name" ) return CScoreboard::SortType::SORT_ID; + return CScoreboard::SortType::SORT_ID; } -SortType CLevelParserParam::AsSortType() +CScoreboard::SortType CLevelParserParam::AsSortType() { if (m_empty) throw CLevelParserExceptionMissingParam(this); return ToSortType(m_value); } -SortType CLevelParserParam::AsSortType(SortType def) +CScoreboard::SortType CLevelParserParam::AsSortType(CScoreboard::SortType def) { if (m_empty) return def; diff --git a/src/level/parser/parserparam.h b/src/level/parser/parserparam.h index d011c669..62838dc7 100644 --- a/src/level/parser/parserparam.h +++ b/src/level/parser/parserparam.h @@ -87,7 +87,7 @@ public: Gfx::EngineObjectType AsTerrainType(); int AsBuildFlag(); int AsResearchFlag(); - SortType AsSortType(); + CScoreboard::SortType AsSortType(); Gfx::PyroType AsPyroType(); Gfx::CameraType AsCameraType(); MissionType AsMissionType(); @@ -111,7 +111,7 @@ public: Gfx::EngineObjectType AsTerrainType(Gfx::EngineObjectType def); int AsBuildFlag(int def); int AsResearchFlag(int def); - SortType AsSortType(SortType def); + CScoreboard::SortType AsSortType(CScoreboard::SortType def); Gfx::PyroType AsPyroType(Gfx::PyroType def); Gfx::CameraType AsCameraType(Gfx::CameraType def); MissionType AsMissionType(MissionType def); @@ -143,7 +143,7 @@ private: Gfx::EngineObjectType ToTerrainType(std::string value); int ToBuildFlag(std::string value); int ToResearchFlag(std::string value); - SortType ToSortType(std::string value); + CScoreboard::SortType ToSortType(std::string value); Gfx::PyroType ToPyroType(std::string value); Gfx::CameraType ToCameraType(std::string value); MissionType ToMissionType(std::string value); diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 03fb5314..5e6a548f 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -2704,6 +2704,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) m_endTakeImmediat = false; m_endTakeResearch = 0; m_endTakeTimeout = -1.0f; + m_endTakeTeamImmediateWin = false; m_endTakeWinDelay = 2.0f; m_endTakeLostDelay = 2.0f; m_teamFinished.clear(); @@ -3574,6 +3575,11 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) } continue; } + if (line->GetCommand() == "EndMissionTeams" && !resetObject) + { + m_endTakeTeamImmediateWin = line->GetParam("immediateWin")->AsBool(false); // false = finishing removes the team that finished, true = finishing for one team ends the whole game + continue; + } if (line->GetCommand() == "EndMissionDelay" && !resetObject) { m_endTakeWinDelay = line->GetParam("win")->AsFloat(2.0f); @@ -5050,11 +5056,11 @@ Error CRobotMain::ProcessEndMissionTake() } GetResource(RES_TEXT, RT_SCOREBOARD_RESULTS_LINE, details_line); std::string details = ""; - for (int team : GetAllTeams()) + for (std::pair team : m_scoreboard->GetSortedScores()) { if (!details.empty()) details += ", "; - details += StrUtils::Format(details_line.c_str(), GetTeamName(team).c_str(), m_scoreboard->GetScore(team).points); + details += StrUtils::Format(details_line.c_str(), GetTeamName(team.first).c_str(), team.second.points); } m_ui->GetDialog()->StartInformation( title, @@ -5125,6 +5131,18 @@ Error CRobotMain::ProcessEndMissionTake() m_scoreboard->ProcessEndTake(team); m_objMan->DestroyTeam(team, DestructionType::Win); m_teamFinished[team] = true; + if (m_endTakeTeamImmediateWin) + { + // All other teams fail + for(int other_team : GetAllActiveTeams()) + { + m_displayText->SetEnable(false); // To prevent "bot destroyed" messages + m_objMan->DestroyTeam(other_team); + m_displayText->SetEnable(true); + + m_teamFinished[other_team] = true; + } + } } } } @@ -6006,32 +6024,19 @@ void CRobotMain::UpdateCodeBattleInterface() Ui::CWindow* pw = static_cast(m_interface->SearchControl(EVENT_WINDOW6)); assert(pw != nullptr); - std::set teams = GetAllTeams(); - std::vector sortedTeams(teams.begin(), teams.end()); - if(m_scoreboard->GetSortType() == SortType::SORT_POINTS) - { - std::sort(sortedTeams.begin(), sortedTeams.end(), [this](int teamA, int teamB) - { - if (m_scoreboard->GetScore(teamA).points > m_scoreboard->GetScore(teamB).points) return true; //Team A have more points than B? - if (m_scoreboard->GetScore(teamA).points < m_scoreboard->GetScore(teamB).points) return false; //Team A have less points than B? - - if (m_scoreboard->GetScore(teamA).time < m_scoreboard->GetScore(teamB).time) return true; //Team A scored faster than B? - else return false; //Team A scored slower than B? - }); - } int i = 0; - for (int team : sortedTeams) + for (std::pair team : m_scoreboard->GetSortedScores()) { Ui::CControl* pl; pl = pw->SearchControl(static_cast(EVENT_SCOREBOARD+2*i+0)); assert(pl != nullptr); - pl->SetName(GetTeamName(team)); + pl->SetName(GetTeamName(team.first)); pl = pw->SearchControl(static_cast(EVENT_SCOREBOARD+2*i+1)); assert(pl != nullptr); - pl->SetName(StrUtils::ToString(m_scoreboard->GetScore(team).points)); + pl->SetName(StrUtils::ToString(team.second.points)); i++; } diff --git a/src/level/robotmain.h b/src/level/robotmain.h index 7f0111ea..d067d0e0 100644 --- a/src/level/robotmain.h +++ b/src/level/robotmain.h @@ -673,6 +673,7 @@ protected: bool m_endTakeImmediat = false; long m_endTakeResearch = 0; float m_endTakeTimeout = -1.0f; + bool m_endTakeTeamImmediateWin = false; float m_endTakeWinDelay = 0.0f; float m_endTakeLostDelay = 0.0f; //! Set to true for teams that have already finished diff --git a/src/level/scoreboard.cpp b/src/level/scoreboard.cpp index 78afa482..1df0d0a3 100644 --- a/src/level/scoreboard.cpp +++ b/src/level/scoreboard.cpp @@ -133,7 +133,7 @@ void CScoreboard::AddPoints(int team, int points) m_score[team].time = main->GetGameTime(); } -Score CScoreboard::GetScore(int team) +CScoreboard::Score CScoreboard::GetScore(int team) { return m_score[team]; } @@ -143,12 +143,33 @@ void CScoreboard::SetScore(int team, int points) m_score[team].points = points; } -SortType CScoreboard::GetSortType() +CScoreboard::SortType CScoreboard::GetSortType() { - return m_sorttype; + return m_sortType; } void CScoreboard::SetSortType(SortType type) { - m_sorttype = type; + m_sortType = type; +} + +std::vector> CScoreboard::GetSortedScores() +{ + CRobotMain* main = CRobotMain::GetInstancePointer(); + std::set teams = main->GetAllTeams(); + std::vector> sortedTeams(teams.size()); + std::transform(teams.begin(), teams.end(), sortedTeams.begin(), [&](int team) { + return *m_score.find(team); + }); + if (m_sortType == SortType::SORT_POINTS) + { + std::sort(sortedTeams.begin(), sortedTeams.end(), [&](std::pair teamA, std::pair teamB) + { + if (teamA.second.points > teamB.second.points) return true; // Team A have more points than B? + if (teamA.second.points < teamB.second.points) return false; // Team A have less points than B? + + return teamA.second.time < teamB.second.time; // Team A scored slower than B? + }); + } + return sortedTeams; } diff --git a/src/level/scoreboard.h b/src/level/scoreboard.h index 4a094912..98f94b60 100644 --- a/src/level/scoreboard.h +++ b/src/level/scoreboard.h @@ -32,22 +32,6 @@ class CObject; -/** - * \struct Score - * \brief Struct containing score of individual team and additional variables to allow sorting teams through different criteria -*/ -struct Score -{ - int points = 0; //! Team score - float time = 0; //! Time when points were scored -}; - -enum class SortType -{ - SORT_ID, //Sort by team ID - SORT_POINTS, //Sort by points -}; - /** * \class CScoreboard * \brief Scoreboard used to score complex code battles @@ -71,6 +55,26 @@ enum class SortType class CScoreboard { public: + /** + * \struct Score + * \brief Struct containing score of individual team and additional variables to allow sorting teams through different criteria + */ + struct Score + { + int points = 0; //!< Team score + float time = 0; //!< Time when points were scored + }; + + /** + * \enum SortType + * \brief Enum defining the scoreboard sorting criteria + */ + enum class SortType + { + SORT_ID, //!< Sort by team ID + SORT_POINTS, //!< Sort by points + }; + //! Creates the scoreboard //! The scoreboard exists only if enabled in level file CScoreboard() {}; @@ -160,11 +164,13 @@ public: SortType GetSortType(); void SetSortType(SortType type); + std::vector> GetSortedScores(); + private: std::vector> m_rulesKill = {}; std::vector> m_rulesObject = {}; std::vector> m_rulesEndTake = {}; std::map m_score; int m_finishCounter = 0; - SortType m_sorttype = SortType::SORT_ID; + SortType m_sortType = SortType::SORT_ID; }; From 85772376fa7d19e8f309a8e613c94dbfb8900881 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Wed, 9 May 2018 18:33:27 +0200 Subject: [PATCH 026/109] Merge ScoreboardSortType with main Scoreboard command --- src/level/robotmain.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 5e6a548f..f6679413 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -3603,16 +3603,11 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) { // Create the scoreboard m_scoreboard = MakeUnique(); + m_scoreboard->SetSortType(line->GetParam("sort")->AsSortType(CScoreboard::SortType::SORT_ID)); } continue; } - if (line->GetCommand() == "ScoreboardSortType" && !resetObject) - { - m_scoreboard->SetSortType(line->GetParam("sort")->AsSortType()); - continue; - } - if (line->GetCommand() == "ScoreboardKillRule" && !resetObject) { if (!m_scoreboard) From 10fc47476bd33eebdc6fd41b31d26cfe11e68dee Mon Sep 17 00:00:00 2001 From: krzys-h Date: Wed, 9 May 2018 18:34:27 +0200 Subject: [PATCH 027/109] Fix code style --- src/level/scoreboard.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/level/scoreboard.cpp b/src/level/scoreboard.cpp index 1df0d0a3..3fa006cb 100644 --- a/src/level/scoreboard.cpp +++ b/src/level/scoreboard.cpp @@ -158,7 +158,8 @@ std::vector> CScoreboard::GetSortedScores() CRobotMain* main = CRobotMain::GetInstancePointer(); std::set teams = main->GetAllTeams(); std::vector> sortedTeams(teams.size()); - std::transform(teams.begin(), teams.end(), sortedTeams.begin(), [&](int team) { + std::transform(teams.begin(), teams.end(), sortedTeams.begin(), [&](int team) + { return *m_score.find(team); }); if (m_sortType == SortType::SORT_POINTS) From 94b30c00a076a0f5c9eb35b50e98fc05d51ef001 Mon Sep 17 00:00:00 2001 From: AbigailBuccaneer Date: Thu, 3 May 2018 18:14:55 +0100 Subject: [PATCH 028/109] Remove code duplication in CGLxxDevice --- src/graphics/core/vertex.h | 13 ++ src/graphics/opengl/gl14device.cpp | 132 +--------------- src/graphics/opengl/gl14device.h | 44 ++++-- src/graphics/opengl/gl21device.cpp | 103 +----------- src/graphics/opengl/gl21device.h | 43 +++-- src/graphics/opengl/gl33device.cpp | 244 +++++------------------------ src/graphics/opengl/gl33device.h | 43 +++-- 7 files changed, 152 insertions(+), 470 deletions(-) diff --git a/src/graphics/core/vertex.h b/src/graphics/core/vertex.h index 1af5832e..30acc2af 100644 --- a/src/graphics/core/vertex.h +++ b/src/graphics/core/vertex.h @@ -92,6 +92,13 @@ struct VertexFormat VertexAttribute tex2{}; }; +enum VertexType +{ + VERTEX_TYPE_NORMAL, + VERTEX_TYPE_TEX2, + VERTEX_TYPE_COL, +}; + /** * \struct Vertex * \brief Vertex of a primitive @@ -105,6 +112,8 @@ struct VertexFormat */ struct Vertex { + static constexpr VertexType VERTEX_TYPE = VERTEX_TYPE_NORMAL; + Math::Vector coord; Math::Vector normal; Math::Point texCoord; @@ -137,6 +146,8 @@ struct Vertex */ struct VertexCol { + static constexpr VertexType VERTEX_TYPE = VERTEX_TYPE_COL; + Math::Vector coord; Color color; @@ -166,6 +177,8 @@ struct VertexCol */ struct VertexTex2 { + static constexpr VertexType VERTEX_TYPE = VERTEX_TYPE_TEX2; + Math::Vector coord; Math::Vector normal; Math::Point texCoord; diff --git a/src/graphics/opengl/gl14device.cpp b/src/graphics/opengl/gl14device.cpp index fc950f49..4304859e 100644 --- a/src/graphics/opengl/gl14device.cpp +++ b/src/graphics/opengl/gl14device.cpp @@ -1635,7 +1635,8 @@ void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, glDisableClientState(GL_COLOR_ARRAY); } -unsigned int CGL14Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +template +unsigned int CGL14Device::CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { unsigned int id = 0; if (m_vertexBufferType != VBT_DISPLAY_LIST) @@ -1644,7 +1645,7 @@ unsigned int CGL14Device::CreateStaticBuffer(PrimitiveType primitiveType, const VboObjectInfo info; info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; + info.vertexType = Vertex::VERTEX_TYPE; info.vertexCount = vertexCount; info.bufferId = 0; @@ -1669,75 +1670,8 @@ unsigned int CGL14Device::CreateStaticBuffer(PrimitiveType primitiveType, const return id; } -unsigned int CGL14Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) -{ - unsigned int id = 0; - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - id = ++m_lastVboId; - - VboObjectInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - info.bufferId = 0; - - m_glGenBuffers(1, &info.bufferId); - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); - - m_vboObjects[id] = info; - } - else - { - id = glGenLists(1); - - glNewList(id, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } - - return id; -} - -unsigned int CGL14Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) -{ - unsigned int id = 0; - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - id = ++m_lastVboId; - - VboObjectInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - info.bufferId = 0; - - m_glGenBuffers(1, &info.bufferId); - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); - - m_vboObjects[id] = info; - } - else - { - id = glGenLists(1); - - glNewList(id, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } - - return id; -} - -void CGL14Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +template +void CGL14Device::UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { if (m_vertexBufferType != VBT_DISPLAY_LIST) { @@ -1747,7 +1681,7 @@ void CGL14Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit VboObjectInfo& info = (*it).second; info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; + info.vertexType = Vertex::VERTEX_TYPE; info.vertexCount = vertexCount; m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); @@ -1764,60 +1698,6 @@ void CGL14Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit } } -void CGL14Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) -{ - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VboObjectInfo& info = (*it).second; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); - } - else - { - glNewList(bufferId, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } -} - -void CGL14Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) -{ - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VboObjectInfo& info = (*it).second; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); - } - else - { - glNewList(bufferId, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } -} - void CGL14Device::DrawStaticBuffer(unsigned int bufferId) { if (m_vertexBufferType != VBT_DISPLAY_LIST) diff --git a/src/graphics/opengl/gl14device.h b/src/graphics/opengl/gl14device.h index 7bc533af..d02f3550 100644 --- a/src/graphics/opengl/gl14device.h +++ b/src/graphics/opengl/gl14device.h @@ -139,12 +139,31 @@ public: virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices, int first[], int count[], int drawCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void DrawStaticBuffer(unsigned int bufferId) override; void DestroyStaticBuffer(unsigned int bufferId) override; @@ -214,6 +233,11 @@ private: //! Disables shadows void DisableShadows(); + template + unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + template + void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + private: //! Current config DeviceConfig m_config; @@ -260,14 +284,6 @@ private: //! Map of framebuffers std::map> m_framebuffers; - //! Type of vertex structure - enum VertexType - { - VERTEX_TYPE_NORMAL, - VERTEX_TYPE_TEX2, - VERTEX_TYPE_COL, - }; - //! Info about static VBO buffers struct VboObjectInfo { diff --git a/src/graphics/opengl/gl21device.cpp b/src/graphics/opengl/gl21device.cpp index f0bbdbb5..5fbc47eb 100644 --- a/src/graphics/opengl/gl21device.cpp +++ b/src/graphics/opengl/gl21device.cpp @@ -1443,13 +1443,15 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, glDisableClientState(GL_COLOR_ARRAY); } -unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) + +template +unsigned int CGL21Device::CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { unsigned int id = ++m_lastVboId; VboObjectInfo info; info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; + info.vertexType = Vertex::VERTEX_TYPE; info.vertexCount = vertexCount; info.bufferId = 0; info.size = vertexCount * sizeof(Vertex); @@ -1463,47 +1465,8 @@ unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const return id; } -unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) -{ - unsigned int id = ++m_lastVboId; - - VboObjectInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - info.bufferId = 0; - info.size = vertexCount * sizeof(VertexTex2); - - glGenBuffers(1, &info.bufferId); - BindVBO(info.bufferId); - glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); - - m_vboObjects[id] = info; - - return id; -} - -unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) -{ - unsigned int id = ++m_lastVboId; - - VboObjectInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - info.bufferId = 0; - info.size = vertexCount * sizeof(VertexCol); - - glGenBuffers(1, &info.bufferId); - BindVBO(info.bufferId); - glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); - - m_vboObjects[id] = info; - - return id; -} - -void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +template +void CGL21Device::UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { auto it = m_vboObjects.find(bufferId); if (it == m_vboObjects.end()) @@ -1513,7 +1476,7 @@ void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit VboObjectInfo& info = (*it).second; info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; + info.vertexType = Vertex::VERTEX_TYPE; info.vertexCount = vertexCount; BindVBO(info.bufferId); @@ -1529,58 +1492,6 @@ void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit } } -void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) -{ - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VboObjectInfo& info = (*it).second; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - - int newSize = vertexCount * sizeof(VertexTex2); - - BindVBO(info.bufferId); - - if (info.size < newSize) - { - glBufferData(GL_ARRAY_BUFFER, newSize, vertices, GL_STATIC_DRAW); - info.size = newSize; - } - else - { - glBufferSubData(GL_ARRAY_BUFFER, 0, newSize, vertices); - } -} - -void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) -{ - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VboObjectInfo& info = (*it).second; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - - int newSize = vertexCount * sizeof(VertexCol); - - BindVBO(info.bufferId); - - if (info.size < newSize) - { - glBufferData(GL_ARRAY_BUFFER, newSize, vertices, GL_STATIC_DRAW); - info.size = newSize; - } - else - { - glBufferSubData(GL_ARRAY_BUFFER, 0, newSize, vertices); - } -} - void CGL21Device::DrawStaticBuffer(unsigned int bufferId) { auto it = m_vboObjects.find(bufferId); diff --git a/src/graphics/opengl/gl21device.h b/src/graphics/opengl/gl21device.h index 6e1bf261..c5af3d7e 100644 --- a/src/graphics/opengl/gl21device.h +++ b/src/graphics/opengl/gl21device.h @@ -120,12 +120,30 @@ public: virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices, int first[], int count[], int drawCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } void DrawStaticBuffer(unsigned int bufferId) override; void DestroyStaticBuffer(unsigned int bufferId) override; @@ -192,6 +210,11 @@ private: //! Binds texture inline void BindTexture(int index, GLuint texture); + template + unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + template + void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + private: //! Current config DeviceConfig m_config; @@ -232,14 +255,6 @@ private: //! Map of framebuffers std::map> m_framebuffers; - //! Type of vertex structure - enum VertexType - { - VERTEX_TYPE_NORMAL, - VERTEX_TYPE_TEX2, - VERTEX_TYPE_COL, - }; - //! Info about static VBO buffers struct VboObjectInfo { diff --git a/src/graphics/opengl/gl33device.cpp b/src/graphics/opengl/gl33device.cpp index 776f1547..0eb70257 100644 --- a/src/graphics/opengl/gl33device.cpp +++ b/src/graphics/opengl/gl33device.cpp @@ -1358,27 +1358,12 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); } -unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +namespace { - unsigned int id = 0; - - id = ++m_lastVboId; - - VertexBufferInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; - info.vertexCount = vertexCount; - info.size = vertexCount * sizeof(Vertex); - - glGenVertexArrays(1, &info.vao); - BindVAO(info.vao); - - glGenBuffers(1, &info.vbo); - BindVBO(info.vbo); - - glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); - m_vboMemory += info.size; +template void SetVertexAttributes(); +template <> void SetVertexAttributes() +{ // Vertex coordinate glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, coord))); @@ -1398,33 +1383,10 @@ unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const // Texture coordinate 1 glDisableVertexAttribArray(4); glVertexAttrib2f(4, 0.0f, 0.0f); - - m_vboObjects[id] = info; - - return id; } -unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) +template <> void SetVertexAttributes() { - unsigned int id = 0; - - id = ++m_lastVboId; - - VertexBufferInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - info.size = vertexCount * sizeof(VertexTex2); - - glGenVertexArrays(1, &info.vao); - BindVAO(info.vao); - - glGenBuffers(1, &info.vbo); - BindVBO(info.vbo); - - glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); - m_vboMemory += info.size; - // Vertex coordinate glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, coord))); @@ -1444,31 +1406,10 @@ unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const // Texture coordinate 1 glEnableVertexAttribArray(4); glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, texCoord2))); - - m_vboObjects[id] = info; - - return id; } -unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) +template <> void SetVertexAttributes() { - unsigned int id = ++m_lastVboId; - - VertexBufferInfo info; - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - info.size = vertexCount * sizeof(VertexCol); - - glGenVertexArrays(1, &info.vao); - BindVAO(info.vao); - - glGenBuffers(1, &info.vbo); - BindVBO(info.vbo); - - glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); - m_vboMemory += info.size; - // Vertex coordinate glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast(offsetof(VertexCol, coord))); @@ -1488,13 +1429,40 @@ unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const // Texture coordinate 1 glDisableVertexAttribArray(4); glVertexAttrib2f(4, 0.0f, 0.0f); +} +} // namespace + +template +unsigned int CGL33Device::CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +{ + unsigned int id = 0; + + id = ++m_lastVboId; + + VertexBufferInfo info; + info.primitiveType = primitiveType; + info.vertexType = Vertex::VERTEX_TYPE; + info.vertexCount = vertexCount; + info.size = vertexCount * sizeof(Vertex); + + glGenVertexArrays(1, &info.vao); + BindVAO(info.vao); + + glGenBuffers(1, &info.vbo); + BindVBO(info.vbo); + + glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); + m_vboMemory += info.size; + + SetVertexAttributes(); m_vboObjects[id] = info; return id; } -void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +template +void CGL33Device::UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { auto it = m_vboObjects.find(bufferId); if (it == m_vboObjects.end()) @@ -1504,12 +1472,12 @@ void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit unsigned int size = vertexCount * sizeof(Vertex); - bool changed = (info.vertexType != VERTEX_TYPE_NORMAL) || (size > info.size); + bool changed = (info.vertexType != Vertex::VERTEX_TYPE) || (size > info.size); - if (info.vertexType != VERTEX_TYPE_NORMAL) CLogger::GetInstance().Debug("Changing static buffer type\n"); + if (info.vertexType != Vertex::VERTEX_TYPE) CLogger::GetInstance().Debug("Changing static buffer type\n"); info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_NORMAL; + info.vertexType = Vertex::VERTEX_TYPE; info.vertexCount = vertexCount; BindVBO(info.vbo); @@ -1531,143 +1499,7 @@ void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit { BindVAO(info.vao); - // Vertex coordinate - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, coord))); - - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, normal))); - - // Color - glDisableVertexAttribArray(2); - glVertexAttrib4f(2, 1.0f, 1.0f, 1.0f, 1.0f); - - // Texture coordinate 0 - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, texCoord))); - - // Texture coordinate 1 - glDisableVertexAttribArray(4); - glVertexAttrib2f(4, 0.0f, 0.0f); - } -} - -void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) -{ - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VertexBufferInfo& info = (*it).second; - - unsigned int size = vertexCount * sizeof(VertexTex2); - - bool changed = (info.vertexType != VERTEX_TYPE_TEX2) || (size > info.size); - - if (info.vertexType != VERTEX_TYPE_TEX2) CLogger::GetInstance().Debug("Changing static buffer type\n"); - - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_TEX2; - info.vertexCount = vertexCount; - - BindVBO(info.vbo); - - if (info.size < size) - { - CLogger::GetInstance().Debug("Resizing static buffer: %d->%d\n", info.size, size); - glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); - m_vboMemory -= info.size; - info.size = size; - m_vboMemory += info.size; - } - else - { - glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices); - } - - if (changed) // Update vertex array bindings - { - BindVAO(info.vao); - - // Vertex coordinate - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, coord))); - - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, normal))); - - // Color - glDisableVertexAttribArray(2); - glVertexAttrib4f(2, 1.0f, 1.0f, 1.0f, 1.0f); - - // Texture coordinate 0 - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, texCoord))); - - // Texture coordinate 1 - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, texCoord2))); - } -} - -void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) -{ - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VertexBufferInfo& info = (*it).second; - - unsigned int size = vertexCount * sizeof(VertexCol); - - bool changed = (info.vertexType != VERTEX_TYPE_COL) || (size > info.size); - - if (info.vertexType != VERTEX_TYPE_NORMAL) CLogger::GetInstance().Debug("Changing static buffer type\n"); - - info.primitiveType = primitiveType; - info.vertexType = VERTEX_TYPE_COL; - info.vertexCount = vertexCount; - - BindVBO(info.vbo); - - if (info.size < size) - { - CLogger::GetInstance().Debug("Resizing static buffer: %d->%d\n", info.size, size); - glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); - m_vboMemory -= info.size; - info.size = size; - m_vboMemory += info.size; - } - else - { - glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices); - } - - if (changed) // Update vertex array bindings - { - BindVAO(info.vao); - - // Vertex coordinate - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast(offsetof(VertexCol, coord))); - - // Normal - glDisableVertexAttribArray(1); - glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f); - - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast(offsetof(VertexCol, color))); - - // Texture coordinate 0 - glDisableVertexAttribArray(3); - glVertexAttrib2f(3, 0.0f, 0.0f); - - // Texture coordinate 1 - glDisableVertexAttribArray(4); - glVertexAttrib2f(4, 0.0f, 0.0f); + SetVertexAttributes(); } } diff --git a/src/graphics/opengl/gl33device.h b/src/graphics/opengl/gl33device.h index b0b452e0..0c73999c 100644 --- a/src/graphics/opengl/gl33device.h +++ b/src/graphics/opengl/gl33device.h @@ -135,12 +135,30 @@ public: virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices, int first[], int count[], int drawCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override; - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override; + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } + void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override + { + UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); + } void DrawStaticBuffer(unsigned int bufferId) override; void DestroyStaticBuffer(unsigned int bufferId) override; @@ -215,6 +233,11 @@ private: inline void UpdateVertexAttribute(int index, const VertexAttribute &attribute, int offset); + template + unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + template + void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + private: //! Current config DeviceConfig m_config; @@ -256,14 +279,6 @@ private: //! Free texture unit const int m_freeTexture = 3; - //! Type of vertex structure - enum VertexType - { - VERTEX_TYPE_NORMAL, - VERTEX_TYPE_TEX2, - VERTEX_TYPE_COL, - }; - //! Info about static VBO buffers struct VertexBufferInfo { From f8ebc6ec217d7787d2e2607931fe90e3e1235432 Mon Sep 17 00:00:00 2001 From: AbigailBuccaneer Date: Thu, 3 May 2018 18:21:21 +0100 Subject: [PATCH 029/109] Remove code for drawing dynamic vertex formats It's unused, and it's a bad idea - it's important for authoring tools and for performance that vertex formats are well-defined instead of dynamically created. --- src/graphics/core/device.h | 8 -- src/graphics/core/nulldevice.cpp | 10 -- src/graphics/core/nulldevice.h | 5 - src/graphics/core/vertex.h | 53 ---------- src/graphics/opengl/gl14device.cpp | 162 ----------------------------- src/graphics/opengl/gl14device.h | 5 - src/graphics/opengl/gl21device.cpp | 160 ---------------------------- src/graphics/opengl/gl21device.h | 5 - src/graphics/opengl/gl33device.cpp | 63 ----------- src/graphics/opengl/gl33device.h | 7 -- 10 files changed, 478 deletions(-) diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h index 3302488c..2cc94992 100644 --- a/src/graphics/core/device.h +++ b/src/graphics/core/device.h @@ -416,14 +416,6 @@ public: //! Sets only the texture wrap modes (for faster than thru stage params) virtual void SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wrapT) = 0; - //! Renders primitive composed of generic vertices - virtual void DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) = 0; - - //! Renders multiple primitives composed of generic vertices - virtual void DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) = 0; - //! Renders primitive composed of vertices with single texture virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) = 0; diff --git a/src/graphics/core/nulldevice.cpp b/src/graphics/core/nulldevice.cpp index 1fd1a09b..cf9f5a67 100644 --- a/src/graphics/core/nulldevice.cpp +++ b/src/graphics/core/nulldevice.cpp @@ -168,16 +168,6 @@ void CNullDevice::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i { } -void CNullDevice::DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) -{ -} - -void CNullDevice::DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) -{ -} - void CNullDevice::DrawPrimitives(PrimitiveType type, const Vertex *vertices, int first[], int count[], int drawCount, Color color) { diff --git a/src/graphics/core/nulldevice.h b/src/graphics/core/nulldevice.h index 4816251b..0d6c7ab8 100644 --- a/src/graphics/core/nulldevice.h +++ b/src/graphics/core/nulldevice.h @@ -81,11 +81,6 @@ public: void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override; - void DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) override; - void DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) override; - void DrawPrimitive(PrimitiveType type, const Vertex* vertices, int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; void DrawPrimitive(PrimitiveType type, const VertexTex2* vertices, int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; void DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount) override; diff --git a/src/graphics/core/vertex.h b/src/graphics/core/vertex.h index 30acc2af..e5b71733 100644 --- a/src/graphics/core/vertex.h +++ b/src/graphics/core/vertex.h @@ -39,59 +39,6 @@ namespace Gfx { - -/** -* \struct VertexAttribute -* \brief Vertex attribute -* -* This structure contains parameters for a vertex attribute. -*/ -struct VertexAttribute -{ - //! true enables vertex attribute - bool enabled = false; - //! true means normalized value (integer types only) - bool normalized = false; - //! Number of elements in the vertex attribute. - //! Valid values are 1, 2, 3, and 4. Depends on specific attribute. - unsigned char size = 0; - //! Type of values in vertex attribute - Type type = Type::UBYTE; - //! Offset to the vertex attribute - int offset = 0; - //! Stride of vertex attribute - int stride = 0; - //! Default values used when attribute is disabled - float values[4] = {0.0f, 0.0f, 0.0f, 0.0f}; -}; - -/** -* \struct VertexFormat -* \brief Vertex format -* -* This structure defines vertex formats for generic vertex arrays. -* -* It contains: -* - vertex coordinate specification -* - color specification -* - normal specification -* - texture coordinate 1 specification -* - texture coordinate 2 specification -*/ -struct VertexFormat -{ - //! Vertex coordinate - VertexAttribute vertex{}; - //! Color - VertexAttribute color{}; - //! Normal - VertexAttribute normal{}; - //! Texture coordinate 1 - VertexAttribute tex1{}; - //! Texture coordinate 2 - VertexAttribute tex2{}; -}; - enum VertexType { VERTEX_TYPE_NORMAL, diff --git a/src/graphics/opengl/gl14device.cpp b/src/graphics/opengl/gl14device.cpp index 4304859e..b427aae3 100644 --- a/src/graphics/opengl/gl14device.cpp +++ b/src/graphics/opengl/gl14device.cpp @@ -1371,168 +1371,6 @@ void CGL14Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i glDisableClientState(GL_COLOR_ARRAY); } -void CGL14Device::DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) -{ - const char *ptr = reinterpret_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(format.vertex.size, - TransformType(format.vertex.type), - format.vertex.stride, - ptr + format.vertex.offset); - - if (format.color.enabled) - { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(format.color.size, - TransformType(format.color.type), - format.color.stride, - ptr + format.color.offset); - } - else - glColor4fv(format.color.values); - - if (format.normal.enabled) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(TransformType(format.normal.type), - format.normal.stride, - ptr + format.normal.offset); - } - else - glNormal3fv(format.normal.values); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - if (format.tex1.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex1.size, - TransformType(format.tex1.type), - format.tex1.stride, - ptr + format.tex1.offset); - } - else - glTexCoord2fv(format.tex1.values); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - if (format.tex2.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex2.size, - TransformType(format.tex2.type), - format.tex2.stride, - ptr + format.tex2.offset); - } - else - glTexCoord2fv(format.tex2.values); - - glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - - if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY); - if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY); - - if (format.tex1.enabled) - { - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (format.tex2.enabled) - { - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - -void CGL14Device::DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) -{ - const char *ptr = reinterpret_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(format.vertex.size, - TransformType(format.vertex.type), - format.vertex.stride, - ptr + format.vertex.offset); - - if (format.color.enabled) - { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(format.color.size, - TransformType(format.color.type), - format.color.stride, - ptr + format.color.offset); - } - else - glColor4fv(format.color.values); - - if (format.normal.enabled) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(TransformType(format.normal.type), - format.normal.stride, - ptr + format.normal.offset); - } - else - glNormal3fv(format.normal.values); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - if (format.tex1.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex1.size, - TransformType(format.tex1.type), - format.tex1.stride, - ptr + format.tex1.offset); - } - else - glTexCoord2fv(format.tex1.values); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - if (format.tex2.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex2.size, - TransformType(format.tex2.type), - format.tex2.stride, - ptr + format.tex2.offset); - } - else - glTexCoord2fv(format.tex2.values); - - GLenum t = TranslateGfxPrimitive(type); - - if (m_multiDrawArrays) - { - glMultiDrawArrays(t, first, count, drawCount); - } - else - { - for (int i = 0; i < drawCount; i++) - glDrawArrays(t, first[i], count[i]); - } - - glDisableClientState(GL_VERTEX_ARRAY); - - if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY); - if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY); - - if (format.tex1.enabled) - { - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (format.tex2.enabled) - { - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - void CGL14Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, int first[], int count[], int drawCount, Color color) { diff --git a/src/graphics/opengl/gl14device.h b/src/graphics/opengl/gl14device.h index d02f3550..ffb86b95 100644 --- a/src/graphics/opengl/gl14device.h +++ b/src/graphics/opengl/gl14device.h @@ -119,11 +119,6 @@ public: void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override; - virtual void DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) override; - virtual void DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) override; - virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, diff --git a/src/graphics/opengl/gl21device.cpp b/src/graphics/opengl/gl21device.cpp index 5fbc47eb..9bd5301a 100644 --- a/src/graphics/opengl/gl21device.cpp +++ b/src/graphics/opengl/gl21device.cpp @@ -1199,166 +1199,6 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i glDisableClientState(GL_COLOR_ARRAY); } -void CGL21Device::DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) -{ - if (m_updateLights) UpdateLights(); - - BindVBO(0); - - const char *ptr = reinterpret_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(format.vertex.size, - TransformType(format.vertex.type), - format.vertex.stride, - ptr + format.vertex.offset); - - if (format.color.enabled) - { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(format.color.size, - TransformType(format.color.type), - format.color.stride, - ptr + format.color.offset); - } - else - glColor4fv(format.color.values); - - if (format.normal.enabled) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(TransformType(format.normal.type), - format.normal.stride, - ptr + format.normal.offset); - } - else - glNormal3fv(format.normal.values); - - glClientActiveTexture(GL_TEXTURE0); - if (format.tex1.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex1.size, - TransformType(format.tex1.type), - format.tex1.stride, - ptr + format.tex1.offset); - } - else - glTexCoord2fv(format.tex1.values); - - glClientActiveTexture(GL_TEXTURE1); - if (format.tex2.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex2.size, - TransformType(format.tex2.type), - format.tex2.stride, - ptr + format.tex2.offset); - } - else - glTexCoord2fv(format.tex2.values); - - glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - - if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY); - if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY); - - if (format.tex1.enabled) - { - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (format.tex2.enabled) - { - glClientActiveTexture(GL_TEXTURE1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - -void CGL21Device::DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) -{ - if (m_updateLights) UpdateLights(); - - BindVBO(0); - - const char *ptr = reinterpret_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(format.vertex.size, - TransformType(format.vertex.type), - format.vertex.stride, - ptr + format.vertex.offset); - - if (format.color.enabled) - { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(format.color.size, - TransformType(format.color.type), - format.color.stride, - ptr + format.color.offset); - } - else - glColor4fv(format.color.values); - - if (format.normal.enabled) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(TransformType(format.normal.type), - format.normal.stride, - ptr + format.normal.offset); - } - else - glNormal3fv(format.normal.values); - - glClientActiveTexture(GL_TEXTURE0); - if (format.tex1.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex1.size, - TransformType(format.tex1.type), - format.tex1.stride, - ptr + format.tex1.offset); - } - else - glTexCoord2fv(format.tex1.values); - - glClientActiveTexture(GL_TEXTURE1); - if (format.tex2.enabled) - { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(format.tex2.size, - TransformType(format.tex2.type), - format.tex2.stride, - ptr + format.tex2.offset); - } - else - glTexCoord2fv(format.tex2.values); - - glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); - - glDisableClientState(GL_VERTEX_ARRAY); - - if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY); - if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY); - - if (format.tex1.enabled) - { - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (format.tex2.enabled) - { - glClientActiveTexture(GL_TEXTURE1); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } -} - void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, int first[], int count[], int drawCount, Color color) { diff --git a/src/graphics/opengl/gl21device.h b/src/graphics/opengl/gl21device.h index c5af3d7e..873afdf7 100644 --- a/src/graphics/opengl/gl21device.h +++ b/src/graphics/opengl/gl21device.h @@ -100,11 +100,6 @@ public: void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override; - virtual void DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) override; - virtual void DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) override; - virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, diff --git a/src/graphics/opengl/gl33device.cpp b/src/graphics/opengl/gl33device.cpp index 0eb70257..0180f247 100644 --- a/src/graphics/opengl/gl33device.cpp +++ b/src/graphics/opengl/gl33device.cpp @@ -1158,50 +1158,6 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); } -void CGL33Device::DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) -{ - if (m_updateLights) UpdateLights(); - - DynamicBuffer& buffer = m_dynamicBuffer; - - BindVAO(buffer.vao); - BindVBO(buffer.vbo); - - unsigned int offset = UploadVertexData(buffer, vertices, size); - - // Update vertex attribute bindings - UpdateVertexAttribute(0, format.vertex, offset); - UpdateVertexAttribute(1, format.normal, offset); - UpdateVertexAttribute(2, format.color, offset); - UpdateVertexAttribute(3, format.tex1, offset); - UpdateVertexAttribute(4, format.tex2, offset); - - glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); -} - -void CGL33Device::DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) -{ - if (m_updateLights) UpdateLights(); - - DynamicBuffer& buffer = m_dynamicBuffer; - - BindVAO(buffer.vao); - BindVBO(buffer.vbo); - - unsigned int offset = UploadVertexData(buffer, vertices, size); - - // Update vertex attribute bindings - UpdateVertexAttribute(0, format.vertex, offset); - UpdateVertexAttribute(1, format.normal, offset); - UpdateVertexAttribute(2, format.color, offset); - UpdateVertexAttribute(3, format.tex1, offset); - UpdateVertexAttribute(4, format.tex2, offset); - - glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); -} - void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, int first[], int count[], int drawCount, Color color) { @@ -1924,25 +1880,6 @@ unsigned int CGL33Device::UploadVertexData(DynamicBuffer& buffer, const void* da return currentOffset; } -void CGL33Device::UpdateVertexAttribute(int index, const VertexAttribute &attribute, int offset) -{ - if (attribute.enabled) - { - glEnableVertexAttribArray(index); - glVertexAttribPointer(index, - attribute.size, - TranslateType(attribute.type), - attribute.normalized ? GL_TRUE : GL_FALSE, - attribute.stride, - reinterpret_cast(offset + attribute.offset)); - } - else - { - glDisableVertexAttribArray(index); - glVertexAttrib4fv(index, attribute.values); - } -} - bool CGL33Device::IsAnisotropySupported() { return m_capabilities.anisotropySupported; diff --git a/src/graphics/opengl/gl33device.h b/src/graphics/opengl/gl33device.h index 0c73999c..7b3aa26a 100644 --- a/src/graphics/opengl/gl33device.h +++ b/src/graphics/opengl/gl33device.h @@ -115,11 +115,6 @@ public: void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override; - virtual void DrawPrimitive(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int vertexCount) override; - virtual void DrawPrimitives(PrimitiveType type, const void *vertices, - int size, const VertexFormat &format, int first[], int count[], int drawCount) override; - virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, @@ -231,8 +226,6 @@ private: //! Uploads data to dynamic buffer and returns offset to it unsigned int UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size); - inline void UpdateVertexAttribute(int index, const VertexAttribute &attribute, int offset); - template unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); template From c9a8a242a084667336cda9032300cdfafc45f1ab Mon Sep 17 00:00:00 2001 From: AbigailBuccaneer Date: Fri, 4 May 2018 13:34:37 +0100 Subject: [PATCH 030/109] Remove CGL14Device's support for display lists Closes #1153. --- src/graphics/opengl/gl14device.cpp | 224 ++++++++++++----------------- src/graphics/opengl/gl14device.h | 13 -- 2 files changed, 93 insertions(+), 144 deletions(-) diff --git a/src/graphics/opengl/gl14device.cpp b/src/graphics/opengl/gl14device.cpp index b427aae3..2dfee282 100644 --- a/src/graphics/opengl/gl14device.cpp +++ b/src/graphics/opengl/gl14device.cpp @@ -257,7 +257,6 @@ bool CGL14Device::Create() if (glVersion >= 15) { GetLogger()->Info("Core VBO supported\n", glMajor, glMinor); - m_vertexBufferType = VBT_VBO_CORE; // Set function pointers m_glGenBuffers = glGenBuffers; @@ -269,7 +268,6 @@ bool CGL14Device::Create() else if (vboARB) // VBO ARB extension available { GetLogger()->Info("ARB VBO supported\n"); - m_vertexBufferType = VBT_VBO_ARB; // Set function pointers m_glGenBuffers = glGenBuffersARB; @@ -280,8 +278,11 @@ bool CGL14Device::Create() } else // no VBO support { - GetLogger()->Info("VBO not supported\n"); - m_vertexBufferType = VBT_DISPLAY_LIST; + m_errorMessage = "Your graphics card or drivers don't support OpenGL 1.5 or vertex buffer objects.\n" + "Ensure you have the latest graphics drivers for your graphics card.\n\n"; + GetLogger()->Error(m_errorMessage.c_str()); + m_errorMessage += GetHardwareInfo(); + return false; } // This is mostly done in all modern hardware by default @@ -1476,34 +1477,20 @@ void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, template unsigned int CGL14Device::CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { - unsigned int id = 0; - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - id = ++m_lastVboId; + unsigned int id = ++m_lastVboId; - VboObjectInfo info; - info.primitiveType = primitiveType; - info.vertexType = Vertex::VERTEX_TYPE; - info.vertexCount = vertexCount; - info.bufferId = 0; + VboObjectInfo info; + info.primitiveType = primitiveType; + info.vertexType = Vertex::VERTEX_TYPE; + info.vertexCount = vertexCount; + info.bufferId = 0; - m_glGenBuffers(1, &info.bufferId); - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); + m_glGenBuffers(1, &info.bufferId); + m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); + m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); + m_glBindBuffer(GL_ARRAY_BUFFER, 0); - m_vboObjects[id] = info; - } - else - { - id = glGenLists(1); - - glNewList(id, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } + m_vboObjects[id] = info; return id; } @@ -1511,126 +1498,101 @@ unsigned int CGL14Device::CreateStaticBufferImpl(PrimitiveType primitiveType, co template void CGL14Device::UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; + auto it = m_vboObjects.find(bufferId); + if (it == m_vboObjects.end()) + return; - VboObjectInfo& info = (*it).second; - info.primitiveType = primitiveType; - info.vertexType = Vertex::VERTEX_TYPE; - info.vertexCount = vertexCount; + VboObjectInfo& info = (*it).second; + info.primitiveType = primitiveType; + info.vertexType = Vertex::VERTEX_TYPE; + info.vertexCount = vertexCount; - m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); - m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); - m_glBindBuffer(GL_ARRAY_BUFFER, 0); - } - else - { - glNewList(bufferId, GL_COMPILE); - - DrawPrimitive(primitiveType, vertices, vertexCount); - - glEndList(); - } + m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); + m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); + m_glBindBuffer(GL_ARRAY_BUFFER, 0); } void CGL14Device::DrawStaticBuffer(unsigned int bufferId) { - if (m_vertexBufferType != VBT_DISPLAY_LIST) + auto it = m_vboObjects.find(bufferId); + if (it == m_vboObjects.end()) + return; + + m_glBindBuffer(GL_ARRAY_BUFFER, (*it).second.bufferId); + + if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) { - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, coord)); - m_glBindBuffer(GL_ARRAY_BUFFER, (*it).second.bufferId); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, normal)); - if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) - { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, texCoord)); - } - else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) - { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord2)); - } - else if ((*it).second.vertexType == VERTEX_TYPE_COL) - { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, color)); - } - - GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType); - glDrawArrays(mode, 0, (*it).second.vertexCount); - - if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 - } - else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - else if ((*it).second.vertexType == VERTEX_TYPE_COL) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - } - - m_glBindBuffer(GL_ARRAY_BUFFER, 0); + glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, texCoord)); } - else + else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) { - glCallList(bufferId); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, normal)); + + glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord)); + + glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord2)); } + else if ((*it).second.vertexType == VERTEX_TYPE_COL) + { + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, coord)); + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, color)); + } + + GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType); + glDrawArrays(mode, 0, (*it).second.vertexCount); + + if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) + { + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 + } + else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) + { + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 + + glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + else if ((*it).second.vertexType == VERTEX_TYPE_COL) + { + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } + + m_glBindBuffer(GL_ARRAY_BUFFER, 0); } void CGL14Device::DestroyStaticBuffer(unsigned int bufferId) { - if (m_vertexBufferType != VBT_DISPLAY_LIST) - { - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; + auto it = m_vboObjects.find(bufferId); + if (it == m_vboObjects.end()) + return; - m_glDeleteBuffers(1, &(*it).second.bufferId); + m_glDeleteBuffers(1, &(*it).second.bufferId); - m_vboObjects.erase(it); - } - else - { - glDeleteLists(bufferId, 1); - } + m_vboObjects.erase(it); } /* Based on libwine's implementation */ diff --git a/src/graphics/opengl/gl14device.h b/src/graphics/opengl/gl14device.h index ffb86b95..39785efd 100644 --- a/src/graphics/opengl/gl14device.h +++ b/src/graphics/opengl/gl14device.h @@ -43,17 +43,6 @@ namespace Gfx { -/** - \enum VertexBufferType - \brief Specifies type of vertex buffer to use - */ -enum VertexBufferType -{ - VBT_DISPLAY_LIST, //! use display lists - VBT_VBO_CORE, //! use core OpenGL 1.5 VBOs - VBT_VBO_ARB //! use ARB extension VBOs -}; - enum ShadowMappingSupport { SMS_NONE, //! No support for depth textures @@ -295,8 +284,6 @@ private: bool m_multiDrawArrays = false; //! Framebuffer support FramebufferSupport m_framebufferSupport = FBS_NONE; - //! Which vertex buffer type to use - VertexBufferType m_vertexBufferType = VBT_DISPLAY_LIST; //! Map of saved VBO objects std::map m_vboObjects; //! Last ID of VBO object From e481905a25d0c1c1f2de5d4e6a63f6417580b93f Mon Sep 17 00:00:00 2001 From: AbigailBuccaneer Date: Fri, 4 May 2018 14:46:27 +0100 Subject: [PATCH 031/109] Do less state setting in gl14 and gl21 --- src/graphics/opengl/gl14device.cpp | 219 +++++++++-------------------- src/graphics/opengl/gl21device.cpp | 218 +++++++++------------------- 2 files changed, 134 insertions(+), 303 deletions(-) diff --git a/src/graphics/opengl/gl14device.cpp b/src/graphics/opengl/gl14device.cpp index 2dfee282..3a8b6dca 100644 --- a/src/graphics/opengl/gl14device.cpp +++ b/src/graphics/opengl/gl14device.cpp @@ -1300,93 +1300,93 @@ void CGL14Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode else assert(false); } +namespace +{ +void SetVertexAttributes(const Vertex* bufferBase, const std::vector& textureRemapping) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, normal)); + + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[1]); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[0]); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, texCoord)); + + glDisableClientState(GL_COLOR_ARRAY); +} + +void SetVertexAttributes(const VertexTex2* bufferBase, const std::vector& textureRemapping) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, normal)); + + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[1]); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, texCoord2)); + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[0]); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, texCoord)); + + glDisableClientState(GL_COLOR_ARRAY); +} + +void SetVertexAttributes(const VertexCol* bufferBase, const std::vector& textureRemapping) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(bufferBase) + offsetof(VertexCol, coord)); + + glDisableClientState(GL_NORMAL_ARRAY); + + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[1]); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0 + textureRemapping[0]); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(bufferBase) + offsetof(VertexCol, color)); +} +} // namespace + void CGL14Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount, Color color) { - Vertex* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].texCoord)); - + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); glColor4fv(color.Array()); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 } void CGL14Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, Color color) { - VertexTex2* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord2)); - + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); glColor4fv(color.Array()); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); } void CGL14Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount) { - VertexCol* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].color)); + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); } void CGL14Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, int first[], int count[], int drawCount, Color color) { - Vertex* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].texCoord)); - + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); glColor4fv(color.Array()); GLenum t = TranslateGfxPrimitive(type); @@ -1400,31 +1400,13 @@ void CGL14Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, for (int i = 0; i < drawCount; i++) glDrawArrays(t, first[i], count[i]); } - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 } void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, int first[], int count[], int drawCount, Color color) { - VertexTex2* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord2)); - + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); glColor4fv(color.Array()); GLenum t = TranslateGfxPrimitive(type); @@ -1438,25 +1420,13 @@ void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, for (int i = 0; i < drawCount; i++) glDrawArrays(t, first[i], count[i]); } - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); } void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, int first[], int count[], int drawCount) { - VertexCol* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].color)); + m_glBindBuffer(GL_ARRAY_BUFFER, 0); + SetVertexAttributes(vertices, m_remap); GLenum t = TranslateGfxPrimitive(type); @@ -1469,9 +1439,6 @@ void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, for (int i = 0; i < drawCount; i++) glDrawArrays(t, first[i], count[i]); } - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); } template @@ -1522,66 +1489,20 @@ void CGL14Device::DrawStaticBuffer(unsigned int bufferId) if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, texCoord)); + SetVertexAttributes(static_cast(nullptr), m_remap); } else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, normal)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord)); - - glClientActiveTexture(GL_TEXTURE0 + m_remap[1]); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord2)); + SetVertexAttributes(static_cast(nullptr), m_remap); } else if ((*it).second.vertexType == VERTEX_TYPE_COL) { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, color)); + SetVertexAttributes(static_cast(nullptr), m_remap); } GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType); + glDrawArrays(mode, 0, (*it).second.vertexCount); - - if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 - } - else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0 + m_remap[0]); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - else if ((*it).second.vertexType == VERTEX_TYPE_COL) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - } - - m_glBindBuffer(GL_ARRAY_BUFFER, 0); } void CGL14Device::DestroyStaticBuffer(unsigned int bufferId) diff --git a/src/graphics/opengl/gl21device.cpp b/src/graphics/opengl/gl21device.cpp index 9bd5301a..41660578 100644 --- a/src/graphics/opengl/gl21device.cpp +++ b/src/graphics/opengl/gl21device.cpp @@ -1115,33 +1115,70 @@ void CGL21Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode else assert(false); } +namespace +{ +void SetVertexAttributes(const Vertex* bufferBase) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, normal)); + + glClientActiveTexture(GL_TEXTURE1); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(bufferBase) + offsetof(Vertex, texCoord)); + + glDisableClientState(GL_COLOR_ARRAY); +} + +void SetVertexAttributes(const VertexTex2* bufferBase) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, normal)); + + glClientActiveTexture(GL_TEXTURE1); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, texCoord2)); + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(bufferBase) + offsetof(VertexTex2, texCoord)); + + glDisableClientState(GL_COLOR_ARRAY); +} + +void SetVertexAttributes(const VertexCol* bufferBase) +{ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(bufferBase) + offsetof(VertexCol, coord)); + + glDisableClientState(GL_NORMAL_ARRAY); + + glClientActiveTexture(GL_TEXTURE1); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(bufferBase) + offsetof(VertexCol, color)); +} +} // namespace + void CGL21Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount, Color color) { if (m_updateLights) UpdateLights(); BindVBO(0); - - Vertex* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0); - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].texCoord)); - + SetVertexAttributes(vertices); glColor4fv(color.Array()); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 } void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, @@ -1150,33 +1187,10 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, if (m_updateLights) UpdateLights(); BindVBO(0); - - VertexTex2* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord)); - - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord2)); - + SetVertexAttributes(vertices); glColor4fv(color.Array()); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); } void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount) @@ -1184,19 +1198,8 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i if (m_updateLights) UpdateLights(); BindVBO(0); - - VertexCol* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].color)); - + SetVertexAttributes(vertices); glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); } void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, @@ -1205,26 +1208,10 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, if (m_updateLights) UpdateLights(); BindVBO(0); - - Vertex* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].texCoord)); - + SetVertexAttributes(vertices); glColor4fv(color.Array()); glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 } void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, @@ -1233,33 +1220,10 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, if (m_updateLights) UpdateLights(); BindVBO(0); - - VertexTex2* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].normal)); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord)); - - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord2)); - + SetVertexAttributes(vertices); glColor4fv(color.Array()); glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); } void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, @@ -1268,19 +1232,9 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, if (m_updateLights) UpdateLights(); BindVBO(0); - - VertexCol* vs = const_cast(vertices); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast(&vs[0].color)); + SetVertexAttributes(vertices); glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); } @@ -1344,64 +1298,20 @@ void CGL21Device::DrawStaticBuffer(unsigned int bufferId) if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, normal)); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, texCoord)); + SetVertexAttributes(static_cast(nullptr)); } else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, coord)); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, normal)); - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord)); - - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord2)); + SetVertexAttributes(static_cast(nullptr)); } else if ((*it).second.vertexType == VERTEX_TYPE_COL) { - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, coord)); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, color)); + SetVertexAttributes(static_cast(nullptr)); } GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType); + glDrawArrays(mode, 0, (*it).second.vertexCount); - - if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 - } - else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - else if ((*it).second.vertexType == VERTEX_TYPE_COL) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - } } void CGL21Device::DestroyStaticBuffer(unsigned int bufferId) From 319d8e6854fd5b6a3120144e99e0eef1353d41a1 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Wed, 9 May 2018 23:12:26 +0200 Subject: [PATCH 032/109] Fix delete() not returning sometimes, closes #1067 --- src/object/object_manager.cpp | 2 +- src/script/scriptfunc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/object/object_manager.cpp b/src/object/object_manager.cpp index c8d8cef7..0b4daed9 100644 --- a/src/object/object_manager.cpp +++ b/src/object/object_manager.cpp @@ -71,7 +71,7 @@ bool CObjectManager::DeleteObject(CObject* instance) it->second.reset(); m_shouldCleanRemovedObjects = true; return true; - } + } else assert(false); return false; } diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp index 7721e2b2..20a85bb2 100644 --- a/src/script/scriptfunc.cpp +++ b/src/script/scriptfunc.cpp @@ -657,7 +657,7 @@ bool CScriptFunctions::rDelete(CBotVar* var, CBotVar* result, int& exception, vo } CObject* obj = CObjectManager::GetInstancePointer()->GetObjectById(rank); - if ( obj == nullptr ) + if ( obj == nullptr || (obj->Implements(ObjectInterfaceType::Old) && dynamic_cast(obj)->IsDying()) ) { return true; } From ed397d2b0f677b505c399f97c95e13fd3d22e492 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Wed, 9 May 2018 23:25:52 +0200 Subject: [PATCH 033/109] Make sure aliens hatched from eggs are not selectable by default, closes #1054 --- src/object/old_object.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 23a303aa..3acf608a 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -684,6 +684,8 @@ void COldObject::SetType(ObjectType type) m_type = type; m_name = GetObjectName(m_type); + SetSelectable(IsSelectableByDefault(m_type)); + // TODO: Temporary hack if ( m_type == OBJECT_MOBILEfa || // WingedGrabber m_type == OBJECT_MOBILEfs || // WingedSniffer From 8095dc14f78c9d996cadbace3178f3fb2b9818df Mon Sep 17 00:00:00 2001 From: krzys-h Date: Thu, 10 May 2018 11:12:22 +0200 Subject: [PATCH 034/109] Add support for custom button= for View cameras --- src/level/robotmain.cpp | 9 +++++---- src/level/robotmain.h | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index f6679413..2cabcccf 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -3555,8 +3555,9 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) continue; } Viewpoint tmp; - tmp.eye = line->GetParam("eye")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f))*g_unit; - tmp.look = line->GetParam("lookat")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f))*g_unit; + tmp.eye = line->GetParam("eye")->AsPoint()*g_unit; + tmp.look = line->GetParam("lookat")->AsPoint()*g_unit; + tmp.button = line->GetParam("button")->AsInt(13); // 13 is the camera button m_viewpoints.push_back(tmp); continue; } @@ -5933,12 +5934,12 @@ void CRobotMain::CreateCodeBattleInterface() //viewpoint selection section ddim.x = 40.0f/640.0f; ddim.y = 50.0f/640.0f; - for(unsigned int i = 0; iCreateButton(pos,ddim, 13, EventType(EVENT_VIEWPOINT0 + i)); + pw->CreateButton(pos, ddim, m_viewpoints[i].button, EventType(EVENT_VIEWPOINT0 + i)); } //start/camera button diff --git a/src/level/robotmain.h b/src/level/robotmain.h index d067d0e0..2614f2cc 100644 --- a/src/level/robotmain.h +++ b/src/level/robotmain.h @@ -152,8 +152,9 @@ struct MinMax struct Viewpoint { - Math::Vector eye; - Math::Vector look; + Math::Vector eye{}; + Math::Vector look{}; + int button = 13; // 13 is the camera button }; const int SATCOM_HUSTON = 0; From 05bc65a90bfcbab482872703d2743b4e656b4c8e Mon Sep 17 00:00:00 2001 From: krzys-h Date: Thu, 10 May 2018 11:12:42 +0200 Subject: [PATCH 035/109] Add support for more buttonsX.png textures (for modders) --- src/ui/controls/button.cpp | 2 -- src/ui/controls/control.cpp | 23 ++++++++--------------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/ui/controls/button.cpp b/src/ui/controls/button.cpp index 4c1d3d99..706946b7 100644 --- a/src/ui/controls/button.cpp +++ b/src/ui/controls/button.cpp @@ -25,8 +25,6 @@ #include "graphics/engine/engine.h" -#include - namespace Ui { diff --git a/src/ui/controls/control.cpp b/src/ui/controls/control.cpp index 2013b612..0d1692ee 100644 --- a/src/ui/controls/control.cpp +++ b/src/ui/controls/control.cpp @@ -24,6 +24,7 @@ #include "common/restext.h" #include "common/settings.h" +#include "common/stringutils.h" #include "level/robotmain.h" @@ -449,6 +450,7 @@ void CControl::Draw() Math::Point pos; float zoomExt, zoomInt; int icon; + int buttonFile = 1; if ( (m_state & STATE_VISIBLE) == 0 ) return; @@ -517,23 +519,14 @@ void CControl::Draw() if ( m_state & STATE_DEAD ) return; - icon = m_icon; - if ( icon >= 128 ) + + icon = m_icon%64; + buttonFile = (m_icon/64) + 1; + if ( buttonFile != 1 ) { - icon -= 128; - m_engine->SetTexture("textures/interface/button3.png"); - m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE); - } - else if ( icon >= 64 ) - { - icon -= 64; - m_engine->SetTexture("textures/interface/button2.png"); - m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE); - } - else - { - m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE); + m_engine->SetTexture("textures/interface/button" + StrUtils::ToString(buttonFile) + ".png"); } + m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE); if ( icon != -1 ) { DrawPart(icon, zoomInt, 0.0f); From 12cf57409cd338c56db6e877b31b1dba18ed681b Mon Sep 17 00:00:00 2001 From: krzys-h Date: Thu, 10 May 2018 11:24:59 +0200 Subject: [PATCH 036/109] Support more buttonX.png files in other places than just buttons --- src/graphics/engine/text.cpp | 19 +++---------------- src/ui/controls/control.cpp | 16 +++++++++------- src/ui/controls/control.h | 7 +++++++ src/ui/controls/shortcut.cpp | 16 +--------------- 4 files changed, 20 insertions(+), 38 deletions(-) diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 0ecd5820..045cdc4c 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -1004,22 +1004,9 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::I // For whatever reason ch.c1 is a SIGNED char, we need to fix that unsigned char icon = static_cast(ch.c1); - unsigned int texID; - - if ( icon >= 128 ) - { - icon -= 128; - texID = m_engine->LoadTexture("textures/interface/button3.png").id; - } - else if ( icon >= 64 ) - { - icon -= 64; - texID = m_engine->LoadTexture("textures/interface/button2.png").id; - } - else - { - texID = m_engine->LoadTexture("textures/interface/button1.png").id; - } + // TODO: A bit of code duplication, see CControl::SetButtonTextureForIcon() + unsigned int texID = m_engine->LoadTexture("textures/interface/button" + StrUtils::ToString((icon/64) + 1) + ".png").id; + icon = icon%64; Math::Point uv1, uv2; uv1.x = (32.0f / 256.0f) * (icon%8); diff --git a/src/ui/controls/control.cpp b/src/ui/controls/control.cpp index 0d1692ee..9c91f51c 100644 --- a/src/ui/controls/control.cpp +++ b/src/ui/controls/control.cpp @@ -519,13 +519,7 @@ void CControl::Draw() if ( m_state & STATE_DEAD ) return; - - icon = m_icon%64; - buttonFile = (m_icon/64) + 1; - if ( buttonFile != 1 ) - { - m_engine->SetTexture("textures/interface/button" + StrUtils::ToString(buttonFile) + ".png"); - } + icon = SetButtonTextureForIcon(m_icon); m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE); if ( icon != -1 ) { @@ -844,5 +838,13 @@ std::string CControl::GetResourceName(EventType eventType) return name; } +int CControl::SetButtonTextureForIcon(int icon) +{ + int iconIdx = icon%64; + int buttonFile = (icon/64) + 1; + m_engine->SetTexture("textures/interface/button" + StrUtils::ToString(buttonFile) + ".png"); + return iconIdx; +} + } diff --git a/src/ui/controls/control.h b/src/ui/controls/control.h index d3e6d5aa..a7166df8 100644 --- a/src/ui/controls/control.h +++ b/src/ui/controls/control.h @@ -116,6 +116,13 @@ protected: std::string GetResourceName(EventType eventType); + /** + * \brief Set texture in m_engine to correct buttonX.png for given icon + * \param icon Icon to draw + * \return Index inside the selected texture of the icon to draw + */ + int SetButtonTextureForIcon(int icon); + protected: Gfx::CEngine* m_engine; Gfx::CParticle* m_particle; diff --git a/src/ui/controls/shortcut.cpp b/src/ui/controls/shortcut.cpp index d85132d1..7d3ddd6d 100644 --- a/src/ui/controls/shortcut.cpp +++ b/src/ui/controls/shortcut.cpp @@ -123,21 +123,7 @@ void CShortcut::Draw() DrawVertex(icon, 0.95f); } - icon = m_icon; - if ( icon >= 128 ) - { - icon -= 128; - m_engine->SetTexture("textures/interface/button3.png"); - } - else if ( icon >= 64 ) - { - icon -= 64; - m_engine->SetTexture("textures/interface/button2.png"); - } - else - { - m_engine->SetTexture("textures/interface/button1.png"); - } + icon = SetButtonTextureForIcon(m_icon); if (m_icon == 58) { m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE); From f538b4f47716a450502bdfa93d9837c4103b1cdf Mon Sep 17 00:00:00 2001 From: krzys-h Date: Thu, 10 May 2018 11:32:33 +0200 Subject: [PATCH 037/109] What did I say about commiting in a hurry --- src/ui/controls/control.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ui/controls/control.cpp b/src/ui/controls/control.cpp index 9c91f51c..9a110e42 100644 --- a/src/ui/controls/control.cpp +++ b/src/ui/controls/control.cpp @@ -450,7 +450,6 @@ void CControl::Draw() Math::Point pos; float zoomExt, zoomInt; int icon; - int buttonFile = 1; if ( (m_state & STATE_VISIBLE) == 0 ) return; From acc3362172b4a06f2f6962e8e3d3670db9657404 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Thu, 10 May 2018 21:06:10 +0200 Subject: [PATCH 038/109] Update data submodule --- data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data b/data index 10b07763..572cf040 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 10b07763fb68f53840d402ad36817e86603c63a6 +Subproject commit 572cf040c52270cb0fcdc5a4dde306c1f5807b07 From 7aaac449f51cc9ee96cef571973fa30ef5a917ec Mon Sep 17 00:00:00 2001 From: krzys-h Date: Thu, 10 May 2018 21:16:42 +0200 Subject: [PATCH 039/109] Fix release script version override This fixes a bug in 94a18e9648dc5deb46297c99f0460ca15e93010e --- tools/release.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tools/release.py b/tools/release.py index 03e83b6f..918b230a 100755 --- a/tools/release.py +++ b/tools/release.py @@ -77,21 +77,20 @@ for i in range(len(data)): if m: x = m.group(3) if m.group(1) == 'MAJOR': - if version_override is None: - major = x - else: - major = version_override[0] + if version_override is not None: + x = version_override[0] + major = x elif m.group(1) == 'MINOR': - if version_override is None: - minor = x - else: - minor = version_override[1] + if version_override is not None: + x = version_override[1] + minor = x elif m.group(1) == 'REVISION': - if version_override is None: + if version_override is not None: + x = version_override[2] + else: # Increase revision number revision = str(int(x) + 1) - else: - revision = version_override[2] + revision = x data[i] = 'set(COLOBOT_VERSION_'+m.group(1)+m.group(2)+x+')\n' m = re.match(r'^(#?)set\(COLOBOT_VERSION_(UNRELEASED|RELEASE_CODENAME)( +)"(.+)"\)$', data[i]) From 12c969c71c4ecbffea81f834b7cc43bc02fe6e31 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Thu, 10 May 2018 21:20:13 +0200 Subject: [PATCH 040/109] Post-release 0.1.11.1-alpha --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 234c201a..4ab7f22a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,9 +16,9 @@ set(COLOBOT_VERSION_MINOR 1) set(COLOBOT_VERSION_REVISION 11.1) # Used on official releases -set(COLOBOT_VERSION_RELEASE_CODENAME "-alpha") +#set(COLOBOT_VERSION_RELEASE_CODENAME "-alpha") # Used on unreleased, development builds -#set(COLOBOT_VERSION_UNRELEASED "+alpha") +set(COLOBOT_VERSION_UNRELEASED "+alpha") # Append git characteristics to version if(DEFINED COLOBOT_VERSION_UNRELEASED) From cdb8a4871a43ee41f3d0db03ca8a613c46d9b2b2 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Thu, 10 May 2018 21:20:13 +0200 Subject: [PATCH 041/109] Release 0.1.11.1-alpha: Bump version --- CMakeLists.txt | 6 +++--- data | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 89cf5344..234c201a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,12 +13,12 @@ project(colobot C CXX) set(COLOBOT_VERSION_CODENAME "Gold") set(COLOBOT_VERSION_MAJOR 0) set(COLOBOT_VERSION_MINOR 1) -set(COLOBOT_VERSION_REVISION 11) +set(COLOBOT_VERSION_REVISION 11.1) # Used on official releases -#set(COLOBOT_VERSION_RELEASE_CODENAME "-alpha") +set(COLOBOT_VERSION_RELEASE_CODENAME "-alpha") # Used on unreleased, development builds -set(COLOBOT_VERSION_UNRELEASED "+alpha") +#set(COLOBOT_VERSION_UNRELEASED "+alpha") # Append git characteristics to version if(DEFINED COLOBOT_VERSION_UNRELEASED) diff --git a/data b/data index 572cf040..3cbab714 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 572cf040c52270cb0fcdc5a4dde306c1f5807b07 +Subproject commit 3cbab7144e6bf940015b2c33fdd17c7c2bfa804b From 2b933264fc41b6794ad08a99813dd116294bb95f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Robson=20Mariano=20Alves?= Date: Tue, 15 May 2018 16:07:03 -0300 Subject: [PATCH 042/109] Translation to Brazilian Portuguese --- po/br.po | 2042 +++++++++++++++++++++++++++ src/app/app.cpp | 13 + src/common/language.cpp | 3 +- src/common/language.h | 3 +- src/ui/screen/screen_setup_game.cpp | 1 + 5 files changed, 2060 insertions(+), 2 deletions(-) create mode 100644 po/br.po diff --git a/po/br.po b/po/br.po new file mode 100644 index 00000000..956b6d2f --- /dev/null +++ b/po/br.po @@ -0,0 +1,2042 @@ +# José Robson Mariano Alves , 2018. +msgid "" +msgstr "" +"Project-Id-Version: Colobot Alpha\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: DATE\n" +"PO-Revision-Date: 2018-04-17 10:39-0300\n" +"Last-Translator: José Robson Mariano Alves \n" +"Language-Team: Portuguese \n" +"Language: pt_BR\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" +"X-Generator: Lokalize 2.0\n" +"X-Language: pt_BR\n" +"X-Source-Language: en_US\n" + +msgid " or " +msgstr " ou " + +msgid "\" [ \" expected" +msgstr "\" [ \" esperado" + +msgid "\" ] \" missing" +msgstr "\" ] \" faltando" + +#, c-format +msgid "%s: %d pts" +msgstr "" + +msgid "..behind" +msgstr "..atrás" + +msgid "..in front" +msgstr "..em frente" + +msgid "..power cell" +msgstr "..célula de energia" + +msgid "1) First click on the key you want to redefine." +msgstr "1) Primeiro clique na chave que você quer redefinir." + +msgid "2) Then press the key you want to use instead." +msgstr "2) Então pressione a chave que você quer usar no lugar." + +msgid "<< Back \\Back to the previous screen" +msgstr "<< Voltar \\Voltar para a tela anterior" + +msgid "<<< Sorry; mission failed >>>" +msgstr "<<< Desculpe; missão fracassada >>>" + +#, c-format +msgid "<<< Team %s finished! >>>" +msgstr "<<< Time %s terminou! >>>" + +#, c-format +msgid "<<< Team %s lost! >>>" +msgstr "<<< Time %s perdeu! >>>" + +#, c-format +msgid "<<< Team %s recieved %d points >>>" +msgstr "<<< Time %s recebeu %d pontos >>>" + +msgid "<<< Well done; mission accomplished >>>" +msgstr "<<< Bem feito; missão cumprida >>>" + +msgid "A label must be followed by \"for\"; \"while\"; \"do\" or \"switch\"" +msgstr "Um rótulo deve ser precedido por um \"for\"; \"while\"; \"do\" ou um \"switch\"" + +msgid "A variable can not be declared twice" +msgstr "Uma variável não pode ser declarada duas vezes" + +msgid "Abort\\Abort the current mission" +msgstr "Abortar\\Abortar a missão atual" + +msgid "Access beyond array limit" +msgstr "Acesso além dos limites da matriz" + +msgid "Access to solution\\Shows the solution (detailed instructions for missions)" +msgstr "Acesso a solução\\Exibe a solução (instruções detalhadas para missões)" + +msgid "Access to solutions\\Show program \"4: Solution\" in the exercises" +msgstr "Acesso as soluções\\Exibir programa \"4: Solução\" nos exercícios" + +msgid "Add new program" +msgstr "Adicionar novo programa" + +msgid "Alien Queen" +msgstr "Rainha Alienígena" + +msgid "Alien Queen killed" +msgstr "Rainha Alienígena morta" + +msgid "Already carrying something" +msgstr "Já está carregando algo" + +msgid "Alternative camera mode\\Move sideways instead of rotating (in free camera)" +msgstr "Modo de câmera alternativo\\Move de lado em vez de rotacionar (em câmera livre)" + +msgid "Ambiguous call to overloaded function" +msgstr "Chamada ambígua a uma função sobrecarregada" + +msgid "Analysis already performed" +msgstr "Análise já realizada" + +msgid "Analysis performed" +msgstr "Análise realizada" + +msgid "Analyzes only organic matter" +msgstr "Analisa apenas matéria orgânica" + +msgid "Anisotropy level\\Anisotropy level" +msgstr "Nível de anisotropia\\Nível de anisotropia" + +msgid "Ant" +msgstr "Formiga" + +msgid "Ant fatally wounded" +msgstr "Formiga gravemente ferida" + +msgid "Appearance\\Choose your appearance" +msgstr "Aparência\\Escolha sua aparência" + +msgid "Apply changes\\Activates the changed settings" +msgstr "Aplicar mudanças\\Ativa as configurações alteradas" + +msgid "Appropriate constructor missing" +msgstr "Construtor apropriado faltando" + +msgid "Assignment impossible" +msgstr "Tarefa impossível" + +msgid "Autolab" +msgstr "Laboratório de matérias orgânicas" + +msgid "Automatic indent\\When program editing" +msgstr "Indentação automática\\Enquanto editando programa" + +msgid "Autosave interval\\How often your game will autosave" +msgstr "Intervalo de salvamento automático\\Com que frequência seu jogo irá auto-salvar" + +msgid "Autosave slots\\How many autosave slots you'll have" +msgstr "Slots de salvamento automático\\Quantos slots de salvamento automático você terá" + +msgid "Autosave\\Enables autosave" +msgstr "Salvamento automático\\Ativa o salvamento automático" + +msgid "Back" +msgstr "Voltar" + +msgid "Background sound:\\Volume of audio tracks" +msgstr "Som de fundo:\\Volume das trilhas de áudio" + +msgid "Backward (\\key down;)" +msgstr "Retroceder (\\key down;)" + +msgid "Backward\\Moves backward" +msgstr "Retroceder\\Move para trás" + +msgid "Bad argument for \"new\"" +msgstr "Argumento inválido para \"new\"" + +msgid "Big indent\\Indent 2 or 4 spaces per level defined by braces" +msgstr "Grande indentação\\Indente 2 ou 4 espaços por nível definido por colchetes" + +msgid "Black box" +msgstr "Caixa preta" + +msgid "Blood\\Display blood when the astronaut is hit" +msgstr "Sangue\\Exibe sangue quando o astronauta é atingido" + +msgid "Blue" +msgstr "Azul" + +msgid "Blue flag" +msgstr "Bandeira azul" + +msgid "Bot destroyed" +msgstr "Robo destruido" + +msgid "Bot factory" +msgstr "Fábrica de robos" + +msgid "Build a bot factory" +msgstr "Construir uma fábrica de robos" + +msgid "Build a converter" +msgstr "Construir um conversor" + +msgid "Build a defense tower" +msgstr "Construir uma torre de defesa" + +msgid "Build a derrick" +msgstr "Construir um extrator" + +msgid "Build a destroyer" +msgstr "Construir um destruidor" + +msgid "Build a exchange post" +msgstr "Construir um posto de troca" + +msgid "Build a legged grabber" +msgstr "Construir um agarrador com pernas" + +msgid "Build a legged orga shooter" +msgstr "Construir um atirador orgânico com pernas" + +msgid "Build a legged shooter" +msgstr "Construir um atirador com pernas" + +msgid "Build a legged sniffer" +msgstr "Construir um farejador com pernas" + +msgid "Build a lightning conductor" +msgstr "Construir um condutor elétrico" + +msgid "Build a nuclear power plant" +msgstr "Construir uma planta de energia nuclear" + +msgid "Build a phazer shooter" +msgstr "Construir um atirador phazer" + +msgid "Build a power cell factory" +msgstr "Construir uma fábrica de células de energia" + +msgid "Build a power station" +msgstr "Construir uma estação de energia" + +msgid "Build a radar station" +msgstr "Construir uma estação de radar" + +msgid "Build a recycler" +msgstr "Construir um reciclador" + +msgid "Build a repair center" +msgstr "Construir um centro de reparação" + +msgid "Build a research center" +msgstr "Construir um centro de pesquisa" + +msgid "Build a shielder" +msgstr "Construir um defensor" + +msgid "Build a subber" +msgstr "Construir um mergulhador" + +msgid "Build a thumper" +msgstr "Construir um batedor" + +msgid "Build a tracked grabber" +msgstr "Construir um agarrador com esteiras" + +msgid "Build a tracked orga shooter" +msgstr "Construir um atirador orgânico com esteiras" + +msgid "Build a tracked shooter" +msgstr "Construir um atirador com esteiras" + +msgid "Build a tracked sniffer" +msgstr "Construir um farejador com esteiras" + +msgid "Build a wheeled grabber" +msgstr "Construir um agarrador com rodas" + +msgid "Build a wheeled orga shooter" +msgstr "Construir um atirador orgânico com rodas" + +msgid "Build a wheeled shooter" +msgstr "Construir um atirador com rodas" + +msgid "Build a wheeled sniffer" +msgstr "Construir um farejador com rodas" + +msgid "Build a winged grabber" +msgstr "Construir um agarrador alado" + +msgid "Build a winged orga shooter" +msgstr "Construir um atirador orgânico alado" + +msgid "Build a winged shooter" +msgstr "Construir um atirador alado" + +msgid "Build a winged sniffer" +msgstr "Construir um farejador alado" + +msgid "Build an autolab" +msgstr "Construir um laboratório" + +msgid "Building completed" +msgstr "Construção completada" + +msgid "Building destroyed" +msgstr "Construção destruida" + +msgid "Button %1" +msgstr "Botão %1" + +msgid "Calling an unknown function" +msgstr "Chamando uma função desconhecida" + +msgid "Camera (\\key camera;)" +msgstr "Câmera (\\key camera;)" + +msgid "Camera back\\Moves the camera backward" +msgstr "Voltar câmera\\Move a câmera para trás" + +msgid "Camera border scrolling\\Scrolling when the mouse touches right or left border" +msgstr "Rolagem de borda da câmera\\Rola quando o mouse toca a borda esquerda ou direita" + +msgid "Camera closer\\Moves the camera forward" +msgstr "Câmera mais perto\\Move a câmera para frente" + +msgid "Camera down\\Turns the camera down" +msgstr "Baixar câmera\\Vira a câmera para baixo" + +msgid "Camera left\\Turns the camera left" +msgstr "Câmera a esquerda\\Gira a câmera para a esquerda" + +msgid "Camera right\\Turns the camera right" +msgstr "Câmera a direita\\Gira a câmera para a direita" + +msgid "Camera up\\Turns the camera up" +msgstr "Subir câmera\\Gira a câmera para cima" + +msgid "Can not produce not researched object" +msgstr "Impossível produzir objetos não pesquisados" + +msgid "Can not produce this object in this mission" +msgstr "Impossível produzir este objeto nesta missão" + +msgid "Can't open file" +msgstr "Não é possível abrir o arquivo" + +msgid "Cancel" +msgstr "Cancelar" + +msgid "Cancel\\Cancel all changes" +msgstr "Cancelar\\Cancela todas as mudanças" + +msgid "Challenges" +msgstr "Desafios" + +msgid "Challenges in the chapter:" +msgstr "Desafios no capítulo:" + +msgid "Challenges\\Programming challenges" +msgstr "Desafios\\Desafios de programação" + +msgid "Change camera\\Switches between onboard camera and following camera" +msgstr "Mudar câmera\\Alterna entre câmera incorporada e câmera seguidora" + +msgid "Change player\\Change player" +msgstr "Mudar jogador\\Mudar jogador" + +msgid "Chapters:" +msgstr "Capítulos:" + +msgid "Cheat console\\Show cheat console" +msgstr "Console de cheats\\Mostrar console de cheats" + +msgid "Checkpoint" +msgstr "Ponto de verificação" + +msgid "Class name expected" +msgstr "Nome de classe experado" + +msgid "Climb\\Increases the power of the jet" +msgstr "Subir\\Aumenta o poder do jato" + +msgid "Clone program" +msgstr "Clonar programa" + +msgid "Clone selected program" +msgstr "Clonar o programa selecionado" + +msgid "Close" +msgstr "Fechar" + +msgid "Closing bracket missing" +msgstr "Colchete de fechamento ausente" + +#, fuzzy +msgid "Code battle" +msgstr "Batalha de código" + +msgid "Code battles" +msgstr "Batalhas de código" + +msgid "Code battles\\Program your robot to be the best of them all!" +msgstr "Batalhas de código\\Programe seu robô para ser o melhor de todos!" + +msgid "Colobot rules!" +msgstr "Regras Colobot!" + +msgid "Colobot: Gold Edition" +msgstr "Colobot: Edição de ouro" + +msgid "Command line" +msgstr "Linha de comando" + +msgid "Compilation ok (0 errors)" +msgstr "Compilação ok (0 erros)" + +msgid "Compile" +msgstr "Compilar" + +msgid "Continue" +msgstr "Continuar" + +msgid "Continue\\Continue the current mission" +msgstr "Continuar\\Continua a missão atual" + +msgid "Controls\\Keyboard, joystick and mouse settings" +msgstr "Controles\\Configurações de teclado, mouse e controles" + +msgid "Converts ore to titanium" +msgstr "Converter minério para titânio" + +msgid "Copy" +msgstr "Copiar" + +msgid "Copy (Ctrl+C)" +msgstr "Copiar (Ctrl+C)" + +msgid "Current mission saved" +msgstr "Missão atual salva" + +msgid "Custom levels:" +msgstr "Níveis personalizados:" + +msgid "Custom levels\\Levels from mods created by the users" +msgstr "Níveis personalizados\\Níveis criados pelos usuários" + +msgid "Customize your appearance" +msgstr "Personalize sua aparência" + +msgid "Cut (Ctrl+X)" +msgstr "Recortar (Ctrl+X)" + +msgid "Defense tower" +msgstr "Torre de defesa" + +msgid "Delete mark" +msgstr "Excluir marca" + +msgid "Delete player\\Deletes the player from the list" +msgstr "Excluir jogador\\Exclui o jogador da lista" + +msgid "Delete\\Deletes the selected file" +msgstr "Excluir\\Exclui o arquivo selecionado" + +msgid "Derrick" +msgstr "Extrator" + +msgid "Descend\\Reduces the power of the jet" +msgstr "Descer\\Diminui o poder do jato" + +msgid "Destroy" +msgstr "Destruir" + +msgid "Destroy the building" +msgstr "Destroi a construção" + +msgid "Destroyer" +msgstr "Destruidor" + +msgid "Device\\Driver and resolution settings" +msgstr "Dispositivo\\Configurações de driver e resolução" + +msgid "Dividing by zero" +msgstr "Dividindo por zero" + +msgid "Do you really want to destroy the selected building?" +msgstr "Você realmente deseja destruir o prédio selecionado?" + +#, c-format +msgid "Do you want to delete %s's saved games?" +msgstr "Você quer deletar os %'s jogos salvos?" + +msgid "Doors blocked by a robot or another object" +msgstr "Portas bloqueadas por um robô ou outro objeto" + +msgid "Down (\\key gdown;)" +msgstr "Baixo (\\key gdown;)" + +msgid "Drawer bot" +msgstr "Robô cartoonista" + +msgid "Dust\\Dust and dirt on bots and buildings" +msgstr "Poeira\\Poeira e sujeira nos robôs e prédios" + +msgid "Dynamic lighting\\Mobile light sources" +msgstr "Iluminação dinâmica\\Fontes móveis de luz" + +msgid "Dynamic shadows ++\\Dynamic shadows + self shadowing" +msgstr "Sombras dinâmicas ++\\Sombras dinâmicas + auto-sombreamento" + +msgid "Dynamic shadows\\Beautiful shadows!" +msgstr "Sombras dinâmicas\\Sombras magníficas!" + +msgid "Edit the selected program" +msgstr "Alterar o programa selecionado" + +msgid "Egg" +msgstr "Ovo" + +msgid "End of block missing" +msgstr "Fim do bloco ausente" + +msgid "Energy deposit (site for power station)" +msgstr "Depósito de energia (local para estação de energia)" + +msgid "Energy level" +msgstr "Nível de energia" + +msgid "Engineer" +msgstr "Engenheiro" + +msgid "Error in instruction move" +msgstr "Deslocamento impossível" + +msgid "Execute the selected program" +msgstr "Execute o programa selecionado" + +msgid "Execute/stop" +msgstr "Executar/Parar" + +msgid "Exercises in the chapter:" +msgstr "Lista de exercícios do capítulo:" + +msgid "Exercises\\Programming exercises" +msgstr "Exercícios\\Exercícios de programação" + +msgid "Explode (\\key action;)" +msgstr "Explodir (\\key action;)" + +msgid "Explosive" +msgstr "Explosivo" + +msgid "Expression expected after =" +msgstr "Expressão experada após =" + +msgid "Extend shield (\\key action;)" +msgstr "Estender escudo (\\key action;)" + +msgid "Eyeglasses:" +msgstr "Óculos:" + +msgid "Face type:" +msgstr "Tipo de face:" + +msgid "File not open" +msgstr "Arquivo não aberto" + +msgid "Filename:" +msgstr "Nome do arquivo:" + +msgid "Film sequences\\Films before and after the missions" +msgstr "Filmes de sequência\\Filmes antes de depois das missões" + +msgid "Finish" +msgstr "Finalizar" + +msgid "Fixed mine" +msgstr "Mina fixa" + +msgid "Flat ground not large enough" +msgstr "Terra plana não larga o suficiente" + +msgid "Fog\\Fog" +msgstr "Neblina\\Neblina" + +msgid "Folder:" +msgstr "Pasta:" + +#, c-format +msgid "Folder: %s" +msgstr "Pasta: %s" + +msgid "Font size" +msgstr "Tamanho da fonte" + +msgid "Forward" +msgstr "Avançar" + +msgid "Forward (\\key up;)" +msgstr "Avançar (\\key up;)" + +msgid "Forward\\Moves forward" +msgstr "Avançar\\Move para frente" + +msgid "Found a site for a derrick" +msgstr "Encontrou um local para o extrator" + +msgid "Found a site for power station" +msgstr "Encontrou um local para um estação de energia" + +msgid "Found key A (site for derrick)" +msgstr "Encontrou uma chave A (local para extrator)" + +msgid "Found key B (site for derrick)" +msgstr "Encontrou uma chave B (local para extrator)" + +msgid "Found key C (site for derrick)" +msgstr "Encontrou uma chave C (local para extrator)" + +msgid "Found key D (site for derrick)" +msgstr "Encontrou uma chave D (local para extrator)" + +msgid "Free game" +msgstr "Jogo livre" + +msgid "Free game on this planet:" +msgstr "Logo livre neste planeta:" + +msgid "Free game\\Free game without a specific goal" +msgstr "Jogo livre\\Jogo livre sem um objetivo específico" + +msgid "Full screen\\Full screen or window mode" +msgstr "Tela cheia\\Tela cheia ou modo janela" + +msgid "Function already exists" +msgstr "Função já existe" + +msgid "Function name missing" +msgstr "Falta o nome da função" + +msgid "Function needs return type \"void\"" +msgstr "Função precisa de um tipo de retorno \"void\"" + +msgid "Game speed" +msgstr "Velocidade do jogo" + +msgid "Game\\Game settings" +msgstr "Jogo\\Opções de jogabilidade" + +msgid "Gantry crane" +msgstr "Guindaste pórtico" + +msgid "Generating" +msgstr "Gerando" + +msgid "Gold Edition development by:" +msgstr "Versão de ouro desenvolvida por:" + +msgid "Goto: destination occupied" +msgstr "Vá para: destino ocupado" + +msgid "Goto: inaccessible destination" +msgstr "Vá para: destino inacessível" + +msgid "Grab or drop (\\key action;)" +msgstr "Pegar ou soltar (\\key action;)" + +msgid "Graphics\\Graphics settings" +msgstr "Gráficos\\Opções gráficas" + +msgid "Green" +msgstr "Verde" + +msgid "Green flag" +msgstr "Bandeira verde" + +msgid "Ground not flat enough" +msgstr "Chão não plano o suficiente" + +msgid "Hair color:" +msgstr "Cor do cabelo:" + +msgid "Head\\Face and hair" +msgstr "Cabeça\\Face e cabelo" + +msgid "Help about selected object" +msgstr "Ajuda sobre o objeto selecionado" + +msgid "Help balloons\\Explain the function of the buttons" +msgstr "Balões de ajuda\\Explica a função dos botões" + +msgid "Hex value out of range" +msgstr "Valor hexadecimal fora de alcance" + +#, fuzzy +msgid "Higher speed\\Doubles speed" +msgstr "Alta velocidade\\Dobra a velocidade" + +msgid "Highest\\Highest graphic quality (lowest frame rate)" +msgstr "Elevado\\Alta qualidade gráfica (baixa taxa de quadros)" + +msgid "Home" +msgstr "Início" + +msgid "Houston Mission Control" +msgstr "Centro de controle de missões Houston" + +msgid "Illegal object" +msgstr "Objeto inacessível" + +msgid "Impossible under water" +msgstr "Impossível debaixo d'água" + +msgid "Impossible when carrying an object" +msgstr "Impossível enquanto carregando um objeto" + +msgid "Impossible when flying" +msgstr "Impossível enquanto voando" + +msgid "Impossible when moving" +msgstr "Impossível enquanto movendo" + +msgid "Impossible when swimming" +msgstr "Impossível enquanto nadando" + +msgid "Inappropriate bot" +msgstr "Robô inapropriado" + +msgid "Inappropriate cell type" +msgstr "Tipo de célula inapropriada" + +msgid "Inappropriate object" +msgstr "Objeto inapropiado" + +msgid "Incorrect index type" +msgstr "Tipo de índice inválido" + +msgid "Infected by a virus; temporarily out of order" +msgstr "Infectado por vírus; temporariamento fora de serviço" + +msgid "Information exchange post" +msgstr "Posto de troca de informação" + +msgid "Instruction \"break\" outside a loop" +msgstr "Intrução \"break\" fora de um laço" + +msgid "Instruction \"case\" missing" +msgstr "Instrução \"case\" faltando" + +msgid "Instruction \"case\" outside a block \"switch\"" +msgstr "Instrução \"case\" fora de um bloco \"switch\"" + +msgid "Instruction \"else\" without corresponding \"if\"" +msgstr "Instrução \"else\" sem o \"if\" correspondente" + +msgid "Instructions (\\key help;)" +msgstr "Instruções (\\key help;)" + +msgid "Instructions after the final closing brace" +msgstr "Instruções depois do último colchete de fechamento" + +msgid "Instructions for the mission (\\key help;)" +msgstr "Instruções para a missão (\\key help;)" + +msgid "Instructions from Houston" +msgstr "Instruções de Houston" + +msgid "Instructions\\Shows the instructions for the current mission" +msgstr "Instruções\\Mostra as instruções para a missão atual" + +msgid "Internal error - tell the developers" +msgstr "Erro interno - contacte os desenvolvedores" + +msgid "Invalid universal character name" +msgstr "Nome de carácter universal inválido" + +msgid "Invert\\Invert values on this axis" +msgstr "Inverter\\Inverte os valores neste eixo" + +msgid "Jet temperature" +msgstr "Temperatura do jato" + +msgid "Key A" +msgstr "Tecla A" + +msgid "Key B" +msgstr "Tecla B" + +msgid "Key C" +msgstr "Tecla C" + +msgid "Key D" +msgstr "Tecla D" + +msgid "Keyword \"while\" missing" +msgstr "Palavra-chave \"while\" faltando" + +msgid "Keyword help(\\key cbot;)" +msgstr "Palavra-chave ajuda (\\key cbot;)" + +msgid "LOADING" +msgstr "CARREGANDO" + +msgid "Legged grabber" +msgstr "Agarrador com pernas" + +msgid "Legged orga shooter" +msgstr "Atirador orgânico com pernas" + +msgid "Legged shooter" +msgstr "Atirador com pernas" + +msgid "Legged sniffer" +msgstr "Farejador com pernas" + +msgid "Levels in this chapter:" +msgstr "Níveis neste capítulo:" + +msgid "Lightning conductor" +msgstr "Condutor elétrico" + +msgid "List of objects" +msgstr "Lista dos objetos" + +msgid "List of saved missions" +msgstr "Lista das missões salvas" + +msgid "Load a saved mission" +msgstr "Carregar uma missão salva" + +msgid "Load\\Load a saved mission" +msgstr "Carregar\\Carregar uma missão salva" + +msgid "Load\\Loads the selected mission" +msgstr "Carregar\\Carrega a missão selecionada" + +msgid "Loading basic level settings" +msgstr "Carregando configurações de nível básico" + +msgid "Loading finished!" +msgstr "Carregamento finalizado!" + +msgid "Loading music" +msgstr "Carregando música" + +msgid "Loading objects" +msgstr "Carregando objetos" + +msgid "Loading terrain" +msgstr "Carregando terreno" + +# msgid "Speed 0.5x\\Half speed" +# msgstr "" +# msgid "Speed 1.0x\\Normal speed" +# msgstr "" +# msgid "Speed 1.5x\\1.5 times faster" +# msgstr "" +# msgid "Speed 2.0x\\Double speed" +# msgstr "" +# msgid "Speed 3.0x\\Triple speed" +# msgstr "" +# msgid "Speed 4.0x\\Quadruple speed" +# msgstr "" +# msgid "Speed 6.0x\\Sextuple speed" +# msgstr "" +msgid "Lower speed\\Decrease speed by half" +msgstr "Velocidade baixa\\Diminuir velocidade pela metade" + +msgid "Lowest\\Minimum graphic quality (highest frame rate)" +msgstr "Mínimo\\Qualidade gráfica mínima (alta taxa de quadros)" + +msgid "Lunar Roving Vehicle" +msgstr "Veículo rotativo Lunar" + +msgid "MSAA\\Multisample anti-aliasing" +msgstr "MSAA\\Antisserrilhamento multiamostragem" + +msgid "Maximize" +msgstr "Maximizar" + +msgid "Minimize" +msgstr "Minimizar" + +msgid "Mipmap level\\Mipmap level" +msgstr "Nível do mini-mapa\\Nível do mini-mapa" + +msgid "Missing end quote" +msgstr "Aspas de fechamento ausentes" + +msgid "Missing hex digits after escape sequence" +msgstr "Digitos hexademais ausentes após sequência de escape" + +msgid "Mission name" +msgstr "Nome da missão" + +msgid "Missions" +msgstr "Missões" + +msgid "Missions on this planet:" +msgstr "Lista de missões neste planeta:" + +msgid "Missions\\Select mission" +msgstr "Missões\\Selecione uma missão" + +msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis" +msgstr "Inversão de mouse X\\Inverte a direção da rolagem no eixo X" + +msgid "Mouse inversion Y\\Inversion of the scrolling direction on the Y axis" +msgstr "Inversão de mouse Y\\Inverte a direção da rolagem no eixo Y" + +msgid "Move selected program down" +msgstr "Move o programa selecionado para baixo" + +msgid "Move selected program up" +msgstr "Move o programa selecionado para cima" + +msgid "Mute\\No sound" +msgstr "Mudo\\Sem som" + +msgid "Name:" +msgstr "Nome:" + +msgid "Negative value rejected by \"throw\"" +msgstr "Valor negativo rejeitado por \"throw\"" + +msgid "Nest" +msgstr "Ninho" + +msgid "New" +msgstr "Novo" + +msgid "New ..." +msgstr "Novo ..." + +msgid "New bot available" +msgstr "Novo robô disponível" + +msgid "Next" +msgstr "Próximo" + +msgid "Next object\\Selects the next object" +msgstr "Próximo objeto\\Selecionar o próximo objeto" + +msgid "No" +msgstr "Não" + +msgid "No energy in the subsoil" +msgstr "Nenhuma energia no subsolo" + +msgid "No flag nearby" +msgstr "Nenhuma bandeira próxima" + +msgid "No function running" +msgstr "Nenhuma função executando" + +msgid "No function with this name accepts this kind of parameter" +msgstr "Nenhuma função com este nome aceita este tipo de parâmetro" + +msgid "No function with this name accepts this number of parameters" +msgstr "Nenhuma função com este nome aceita este número de parâmetros" + +msgid "No information exchange post within range" +msgstr "Nenhum posto de troca de informação ao alcance" + +msgid "No more energy" +msgstr "Não há mais energia" + +msgid "No ore in the subsoil" +msgstr "Nenhum mineral no subsolo" + +msgid "No power cell" +msgstr "Sem célula de energia" + +msgid "No titanium" +msgstr "Sem titânio" + +msgid "No titanium around" +msgstr "Nenhum titânio ao redor" + +msgid "No titanium ore to convert" +msgstr "Sem minério de titânio para converter" + +msgid "No titanium to transform" +msgstr "Nenhum titânio para transformar" + +msgid "No uranium to transform" +msgstr "Nenhum urânio para transformar" + +msgid "No userlevels installed!" +msgstr "Nenhum nível de usuário instalado!" + +msgid "Non-void function needs \"return;\"" +msgstr "Funções não void precisam de \"return;\"" + +msgid "Normal size" +msgstr "Tamanho normal" + +msgid "Normal\\Normal graphic quality" +msgstr "Normal\\Qualidade gráfica normal" + +msgid "Normal\\Normal sound volume" +msgstr "Normal\\Volume de som normal" + +msgid "Not enough energy" +msgstr "Sem energia suficiente" + +msgid "Not enough energy yet" +msgstr "Ainda sem energia suficiente" + +msgid "Not found anything to destroy" +msgstr "Não encontrou nada para destruir" + +msgid "Nothing to analyze" +msgstr "Nada para analisar" + +msgid "Nothing to drop" +msgstr "Nada para largar" + +msgid "Nothing to grab" +msgstr "Nada para pegar" + +msgid "Nothing to recycle" +msgstr "Nada para reciclar" + +msgid "Nuclear power cell" +msgstr "Célula de energia núclear" + +msgid "Nuclear power cell available" +msgstr "Célula de energia núclear disponível" + +msgid "Nuclear power station" +msgstr "Estação de energia núclear" + +msgid "Number missing" +msgstr "Número ausente" + +msgid "Number of insects detected" +msgstr "Número de insetos detectados" + +msgid "Number of particles\\Explosions, dust, reflections, etc." +msgstr "Quantidade de particulas\\Explosões, poeira, reflexões, etc." + +msgid "OK" +msgstr "OK" + +msgid "OK\\Choose the selected player" +msgstr "OK\\Escolher o jogador selecionado" + +msgid "OK\\Close program editor and return to game" +msgstr "OK\\Fechar o editor e retornar ao jogo" + +msgid "Object too close" +msgstr "Objeto muito próximo" + +msgid "Octal value out of range" +msgstr "Valor octal fora do limite" + +msgid "One step" +msgstr "Um passo" + +msgid "Open" +msgstr "Abrir" + +msgid "Open (Ctrl+O)" +msgstr "Abrir (Ctrl+O)" + +msgid "Opening brace missing" +msgstr "Chave de abertura ausente" + +msgid "Opening bracket missing" +msgstr "Colchete de abertura ausente" + +msgid "Operation impossible with value \"nan\"" +msgstr "Operação impossível com o valor \"nan\"" + +msgid "Options" +msgstr "Opções" + +msgid "Options\\Preferences" +msgstr "Opções\\Preferências" + +msgid "Organic matter" +msgstr "Matéria orgânica" + +msgid "Origin of last message\\Shows where the last message was sent from" +msgstr "Origem da última mensagem\\Mostra de onde a última mensagem foi enviada" + +msgid "Original game developed by:" +msgstr "Jogo original desenvolvido por:" + +msgid "Parameters missing" +msgstr "Parâmetros ausentes" + +msgid "Particles in the interface\\Steam clouds and sparks in the interface" +msgstr "Partículas na interface\\Núvens de vapor e faíscas na interface" + +msgid "Paste (Ctrl+V)" +msgstr "Colar (Ctrl+V)" + +msgid "Pause blur\\Blur the background on the pause screen" +msgstr "Borrão de pausa\\Borra o fundo na tela de pausa" + +msgid "Pause in background\\Pause the game when the window is unfocused" +msgstr "Pausar quando em background\\Pausa o jogo quando a janela está sem foco" + +msgid "Pause/continue" +msgstr "Pausar/Continuar" + +msgid "Pause\\Pause the game without opening menu" +msgstr "Pausar\\Pausa o jogo sem abrir o menu" + +msgid "Phazer shooter" +msgstr "Atirador phazer" + +msgid "Photography" +msgstr "Fotografia" + +msgid "Place occupied" +msgstr "Local ocupado" + +msgid "Planets:" +msgstr "Planetas:" + +msgid "Plans for defense tower available" +msgstr "Planos para a torre de defesa disponíveis" + +msgid "Plans for nuclear power plant available" +msgstr "Planos para a planta nuclear disponíveis" + +msgid "Plans for phazer shooter available" +msgstr "Planos para o atirador phazer disponíveis" + +msgid "Plans for shielder available" +msgstr "Planos para o defensor disponíveis" + +msgid "Plans for shooter available" +msgstr "Planos para o atirador disponíveis" + +msgid "Plans for thumper available" +msgstr "Planos para o batedor disponíveis" + +msgid "Plans for tracked robots available" +msgstr "Planos para robôs com esteiras disponíveis" + +msgid "Plant a flag" +msgstr "Colocar uma bandeira" + +msgid "Play\\Start mission!" +msgstr "Jogar\\Iniciar missão!" + +msgid "Player" +msgstr "Jogador" + +msgid "Player name" +msgstr "Nome do jogador" + +msgid "Player's name" +msgstr "Nome dos jogadores" + +msgid "Power cell" +msgstr "Célula de energia" + +msgid "Power cell available" +msgstr "Célula de energia disponível" + +msgid "Power cell factory" +msgstr "Fábrica de células de energia" + +msgid "Power station" +msgstr "Estação de energia" + +msgid "Practice bot" +msgstr "Robô de prática" + +msgid "Press \\key help; to read instructions on your SatCom" +msgstr "Pressione \\key help; para ler as intruções no seu SatCom" + +msgid "Previous" +msgstr "Anterior" + +msgid "Previous object\\Selects the previous object" +msgstr "Objeto anterior\\Seleciona o objeto anterior" + +msgid "Previous selection (\\key desel;)" +msgstr "Seleção anterior (\\key desel;)" + +msgid "Private element" +msgstr "Elemento privado" + +msgid "Private\\Private folder" +msgstr "Privado\\Pasta privada" + +msgid "Processing level file" +msgstr "Processando o arquivo de nível" + +msgid "Program cloned" +msgstr "Programa clonado" + +msgid "Program editor" +msgstr "Editor" + +msgid "Program finished" +msgstr "Programa finalizado" + +msgid "Program infected by a virus" +msgstr "Programa infectado por vírus" + +msgid "Programming exercises" +msgstr "Exercícios de programação" + +msgid "Programming help" +msgstr "Ajuda de programação" + +msgid "Programming help (\\key prog;)" +msgstr "Ajuda de programação (\\key prog;)" + +msgid "Programming help\\Gives more detailed help with programming" +msgstr "Ajuda de programação\\Fornece uma ajuda mais detalhada sobre programação" + +msgid "Programs dispatched by Houston" +msgstr "Programas enviados por Houston" + +msgid "Public required" +msgstr "Necessário público" + +msgid "Public\\Common folder" +msgstr "Público\\Pasta comum" + +msgid "Quake at explosions\\The screen shakes at explosions" +msgstr "Tremer em explosões\\A tela sacode em explosões" + +msgid "Quick load\\Immediately load game" +msgstr "Carregando rápido\\Imediatamente carrega o jogo" + +msgid "Quick save\\Immediately save game" +msgstr "Salvamento rápido\\Imediatamente salva o jogo" + +#, fuzzy +msgid "Quicksave slot not found" +msgstr "Slot para salvamento rápido não encontrado" + +msgid "Quit\\Quit Colobot: Gold Edition" +msgstr "Sair\\Fecha Colobot: ediçao de ouro" + +msgid "Quit\\Quit the current mission or exercise" +msgstr "Sair\\Termina a missão atual ou exercício" + +msgid "Radar station" +msgstr "Estação de radar" + +msgid "Read error" +msgstr "Erro de leitura" + +msgid "Recorder" +msgstr "Gravador" + +msgid "Recycle (\\key action;)" +msgstr "Reciclar (\\key action;)" + +msgid "Recycler" +msgstr "Reciclador" + +msgid "Red" +msgstr "Vermelho" + +msgid "Red flag" +msgstr "Bandeira vermelha" + +msgid "Reflections on the buttons \\Shiny buttons" +msgstr "Reflexões nos botões\\Botões brilhantes" + +msgid "Remains of Apollo mission" +msgstr "Restos da missão Apollo" + +msgid "Remove a flag" +msgstr "Remover a bandeira" + +msgid "Remove selected program" +msgstr "Remover o programa selecionado" + +msgid "Render distance\\Maximum visibility" +msgstr "Distância de renderização\\Visibilidade máxima" + +msgid "Repair center" +msgstr "Centro de reparos" + +msgid "Research center" +msgstr "Centro de pesquisa" + +msgid "Research program already performed" +msgstr "Programa de pesquisa já realizado" + +msgid "Research program completed" +msgstr "Programa de pesquisa completado" + +msgid "Reserved keyword of CBOT language" +msgstr "Palavra-chave reservada para a linguagem CBOT" + +msgid "Resolution" +msgstr "Resolução" + +msgid "Resolution:" +msgstr "Resolução:" + +msgid "Resources" +msgstr "Recursos" + +msgid "Restart\\Restart the mission from the beginning" +msgstr "Reiniciar\\Reinicia a missão do começo" + +msgid "Restoring CBot execution state" +msgstr "Restaura o estado de execução do CBot" + +msgid "Restoring saved objects" +msgstr "Restaurando objetos salvos" + +msgid "Results" +msgstr "Resultados" + +msgid "Return to start" +msgstr "Retornar para o início" + +msgid "Robbie" +msgstr "Robbie" + +msgid "Ruin" +msgstr "Ruína" + +msgid "Run research program for defense tower" +msgstr "Executar programa de pesquisa para torre de defesa" + +msgid "Run research program for legged bots" +msgstr "Executar programa de pesquisa para robôs com pernas" + +msgid "Run research program for nuclear power" +msgstr "Executar programa de pesquisa para energia nuclear" + +msgid "Run research program for orga shooter" +msgstr "Executar programa de pesquisa para atirador orgânico" + +msgid "Run research program for phazer shooter" +msgstr "Executar programa de pesquisa para atirador phazer" + +msgid "Run research program for shielder" +msgstr "Executar programa de pesquisa para defensor" + +msgid "Run research program for shooter" +msgstr "Executar programa de pesquisa para atirador" + +msgid "Run research program for thumper" +msgstr "Executar programa de pesquisa para batedor" + +msgid "Run research program for tracked bots" +msgstr "Executar programa de pesquisa para robôs com esteira" + +msgid "Run research program for winged bots" +msgstr "Executar programa de pesquisa para robôs alados" + +msgid "SatCom" +msgstr "SatCom" + +msgid "Satellite report" +msgstr "Relatório do satélite" + +msgid "Save" +msgstr "Salvar" + +msgid "Save (Ctrl+S)" +msgstr "Salvar (Ctrl+S)" + +msgid "Save the current mission" +msgstr "Salve a missão atual" + +msgid "Save\\Save the current mission" +msgstr "Salvar\\Salve a missão atual" + +msgid "Save\\Saves the current mission" +msgstr "Salvar\\Salva a missão atual" + +msgid "Select the astronaut\\Selects the astronaut" +msgstr "Selecione o astronauta\\Seleciona o astronauta" + +msgid "Semicolon terminator missing" +msgstr "Falta o terminador ponto e vírgula" + +msgid "Shadow resolution\\Higher means better range and quality, but slower" +msgstr "Resolução das sombras\\Valores altos significam alcance e qualidade melhores, porém mais devagar" + +msgid "Shield level" +msgstr "Nível de escudo" + +msgid "Shield radius" +msgstr "Raio do escudo" + +msgid "Shielder" +msgstr "Defensor" + +msgid "Shoot (\\key action;)" +msgstr "Atirar (\\key action;)" + +msgid "Show if the ground is flat" +msgstr "Mostre se o solo é plano" + +msgid "Show the place" +msgstr "Mostre o local" + +msgid "Show the range" +msgstr "Mostre o alcance" + +msgid "Show the solution" +msgstr "Mostre a solução" + +msgid "Sign \" : \" missing" +msgstr "Sinal \" : \" ausente" + +msgid "Simple shadows\\Shadows spots on the ground" +msgstr "Sombras simples\\Pontos de sombra no chão" + +msgid "Size 1" +msgstr "Tamanho 1" + +msgid "Size 2" +msgstr "Tamanho 2" + +msgid "Size 3" +msgstr "Tamanho 3" + +msgid "Size 4" +msgstr "Tamanho 4" + +msgid "Size 5" +msgstr "Tamanho 5" + +msgid "Sniff (\\key action;)" +msgstr "Farejar (\\key action;)" + +msgid "Solution" +msgstr "Solução" + +msgid "Sound effects:\\Volume of engines, voice, shooting, etc." +msgstr "Efeitos sonoros:\\Volume dos motores, voz, tiros, etc." + +msgid "Sound\\Music and game sound volume" +msgstr "Som\\Volume do som das músicas e do jogo" + +msgid "Spaceship" +msgstr "Nave espacial" + +msgid "Spaceship ruin" +msgstr "Ruína de nave espacial" + +msgid "Spider" +msgstr "Aranha" + +msgid "Spider fatally wounded" +msgstr "Aranha fatalmente ferida" + +msgid "Stack overflow" +msgstr "Estouro de pilha" + +msgid "Standard action\\Standard action of the bot (take/grab, shoot, sniff, etc)" +msgstr "Ação padrão\\Ação padrão do robô (pegar/agarrar, atirar, farejar, etc)" + +msgid "Standard controls\\Standard key functions" +msgstr "Controles padrões\\Funções padrões das teclas" + +msgid "Standard speed\\Reset speed to normal" +msgstr "Velocidade padrão\\Reiniciar a velocidade para o normal" + +msgid "Standard\\Standard appearance settings" +msgstr "Padrão\\Configurações de aparência padrão" + +msgid "Start" +msgstr "Iniciar" + +msgid "Starting..." +msgstr "Iniciando..." + +msgid "Still working ..." +msgstr "Ainda trabalhando ..." + +msgid "String missing" +msgstr "Carácteres ausentes" + +msgid "Strip color:" +msgstr "Cor da tira:" + +msgid "Subber" +msgstr "Mergulhador" + +msgid "Suit color:" +msgstr "Cor do traje:" + +msgid "Suit\\Astronaut suit" +msgstr "Traje\\Traje de astronauta" + +msgid "Summary:" +msgstr "Sumário:" + +msgid "Survival kit" +msgstr "Kit de sobrevivência" + +msgid "Switch bots <-> buildings" +msgstr "Trocar robôs <-> prédios" + +msgid "Take off to finish the mission" +msgstr "Decole para finalizar a missão" + +msgid "Target" +msgstr "Alvo" + +msgid "Target bot" +msgstr "Robô alvo" + +msgid "Terrain relief" +msgstr "Relevo do terreno" + +msgid "Texture filtering\\Texture filtering" +msgstr "Filtragem de textura\\Filtragem de textura" + +msgid "Textures" +msgstr "Texturas" + +msgid "The battle has ended" +msgstr "A batalha acabou" + +msgid "The expression must return a boolean value" +msgstr "A expressão deve retornar um valor booleano" + +msgid "The function returned no value" +msgstr "A função não retornou nenhum valor" + +msgid "The mission is not accomplished yet (press \\key help; for more details)" +msgstr "A missão não foi completada ainda (pressione \\key help; para mais detalhes)" + +msgid "The types of the two operands are incompatible" +msgstr "Os tipos dos dois operandos são incompativeis" + +msgid "This class already exists" +msgstr "Esta classe já existe" + +msgid "This class does not exist" +msgstr "Esta classe não existe" + +msgid "This is example code that cannot be run directly" +msgstr "Este é um código de exemplo que não pode ser executado diretamente" + +msgid "This is not a member of this class" +msgstr "Este não é um membro desta classe" + +msgid "This label does not exist" +msgstr "Este rótulo não existe" + +msgid "This menu is for userlevels from mods, but you didn't install any" +msgstr "Este menu é para níveis de usuários, mas você não instalou nenhum." + +msgid "This object is currently busy" +msgstr "Este objeto está ocupado atualmente" + +msgid "This object is not a member of a class" +msgstr "Este objeto não é um membro de uma classe" + +msgid "This parameter needs a default value" +msgstr "Este parâmetro necessita de um valor padrão" + +msgid "This program is read-only, clone it to edit" +msgstr "Este programa é somente-leitura, clone-o para edita-lo" + +msgid "Thump (\\key action;)" +msgstr "Bater (\\key action;)" + +msgid "Thumper" +msgstr "Batedor" + +msgid "Titanium" +msgstr "Titânio" + +msgid "Titanium available" +msgstr "Titânio disponível" + +msgid "Titanium deposit (site for derrick)" +msgstr "Depósito de titânio (local para extrator)" + +msgid "Titanium ore" +msgstr "Mineral de titânio" + +msgid "Titanium too close" +msgstr "Titânio muito perto" + +msgid "Titanium too far away" +msgstr "Titânio muito longe" + +msgid "Too close to a building" +msgstr "Muito perto de um prédio" + +msgid "Too close to an existing flag" +msgstr "Muito perto de uma bandeira" + +msgid "Too close to space ship" +msgstr "Muito perto da nave espacial" + +msgid "Too many flags of this color (maximum 5)" +msgstr "Muitas bandeiras dessa cor (máximo 5)" + +msgid "Too many parameters" +msgstr "Muitos parâmetros" + +msgid "Tracked grabber" +msgstr "Pegador com esteiras" + +msgid "Tracked orga shooter" +msgstr "Atirador orgânico com esteiras" + +msgid "Tracked shooter" +msgstr "Atirador com esteiras" + +msgid "Tracked sniffer" +msgstr "Farejador com esteiras" + +msgid "Transforms only titanium" +msgstr "Transformar somente titânio" + +msgid "Transforms only uranium" +msgstr "Transformar somente urânio" + +msgid "Transmitted information" +msgstr "Informação transmitida" + +msgid "Turn left (\\key left;)" +msgstr "Vire a esquerda (\\key left;)" + +msgid "Turn left\\turns the bot to the left" +msgstr "Vire a esquerda\\vira o robô para a esquerda" + +msgid "Turn right (\\key right;)" +msgstr "Vire a direita (\\key right;)" + +msgid "Turn right\\turns the bot to the right" +msgstr "Vire a direita\\vira o robô para a direita" + +msgid "Type declaration missing" +msgstr "Declaração de tipo ausente" + +msgid "Unable to control enemy objects" +msgstr "Impossível controlar objetos inimigos" + +msgid "Undo (Ctrl+Z)" +msgstr "Desfazer (Ctrl+Z)" + +msgid "Unit" +msgstr "Unidade" + +msgid "Unknown Object" +msgstr "Objeto desconhecido" + +msgid "Unknown command" +msgstr "Comando desconhecido" + +msgid "Unknown escape sequence" +msgstr "Sequência de escape desconhecidade" + +msgid "Unknown function" +msgstr "Função desconhecida" + +msgid "Up (\\key gup;)" +msgstr "Cima (\\key gup;)" + +msgid "Uranium deposit (site for derrick)" +msgstr "Depósito de urânio (local para extrator)" + +msgid "Uranium ore" +msgstr "Mineral de urânio" + +msgid "User levels" +msgstr "Níveis de usuário" + +msgid "Variable name missing" +msgstr "Nome de variável ausente" + +msgid "Variable not declared" +msgstr "Variável não declarada" + +msgid "Variable not initialized" +msgstr "Variável não inicializada" + +msgid "Vault" +msgstr "Cofre" + +msgid "Violet flag" +msgstr "Bandeira violeta" + +msgid "Void parameter" +msgstr "Parâmetro vazio" + +msgid "Wasp" +msgstr "Vespa" + +msgid "Wasp fatally wounded" +msgstr "Vespa fatalmente ferida" + +msgid "Waste" +msgstr "Desperdício" + +msgid "Wheeled grabber" +msgstr "Agarrador com rodas" + +msgid "Wheeled orga shooter" +msgstr "Atirador orgânico com rodas" + +msgid "Wheeled shooter" +msgstr "Atirador com rodas" + +msgid "Wheeled sniffer" +msgstr "Farejador com rodas" + +msgid "Winged grabber" +msgstr "Agarrador alado" + +msgid "Winged orga shooter" +msgstr "Atirador orgânico alado" + +msgid "Winged shooter" +msgstr "Atirador alado" + +msgid "Winged sniffer" +msgstr "Farejador alado" + +msgid "Withdraw shield (\\key action;)" +msgstr "Retirar escudo (\\key action;)" + +msgid "Worm" +msgstr "Verme" + +msgid "Worm fatally wounded" +msgstr "Verme fatalmente ferido" + +msgid "Wreckage" +msgstr "Destroços" + +msgid "Write error" +msgstr "Erro de escrita" + +msgid "Wrong type for the assignment" +msgstr "Tipo errado para a tarefa" + +msgid "Yellow flag" +msgstr "Bandeira amarela" + +msgid "Yes" +msgstr "Sim" + +msgid "You can fly with the keys (\\key gup;) and (\\key gdown;)" +msgstr "Você pode voar com as teclas (\\key gup;) e (\\key gdown;)" + +msgid "You can not carry a radioactive object" +msgstr "Você não pode carregar um objeto radioativo" + +msgid "You can not carry an object under water" +msgstr "Você não pode carregar um objeto debaixo d'água" + +#, c-format +msgid "You cannot use \"%s\" in this exercise (used: %d)" +msgstr "Você não pode usar \"%s\" neste exercício (usado: %d)" + +msgid "You found a usable object" +msgstr "Você encontrou um objeto utilizável" + +#, c-format +msgid "You have to use \"%1$s\" at least once in this exercise (used: %2$d)" +msgid_plural "You have to use \"%1$s\" at least %3$d times in this exercise (used: %2$d)" +msgstr[0] "Você deve usar \"%1$s\" pelo menos uma vez neste exercício (usado: %2$d)" +msgstr[1] "Você deve usar \"%1$s\" pelo menos %3$d vezes neste exercício (usado: %2$d)" + +#, c-format +msgid "You have to use \"%1$s\" at most once in this exercise (used: %2$d)" +msgid_plural "You have to use \"%1$s\" at most %3$d times in this exercise (used: %2$d)" +msgstr[0] "Você deve usar \"%1$s\" pelo menos uma vez neste exercício (usado: %2$d)" +msgstr[1] "Você deve usar \"%1$s\" pelo menos %3$d vezes neste exercício (usado: %2$d)" + +msgid "You must get on the spaceship to take off" +msgstr "Você deve estar na nave espacial para decolar" + +msgid "Zoom mini-map" +msgstr "Zoom no mini-mapa" + +msgid "\\Blue flags" +msgstr "\\Bandeiras azuis" + +msgid "\\Eyeglasses 1" +msgstr "\\Óculos 1" + +msgid "\\Eyeglasses 2" +msgstr "\\Óculos 2" + +msgid "\\Eyeglasses 3" +msgstr "\\Óculos 3" + +msgid "\\Eyeglasses 4" +msgstr "\\Óculos 4" + +msgid "\\Eyeglasses 5" +msgstr "\\Óculos 5" + +msgid "\\Face 1" +msgstr "\\Face 1" + +msgid "\\Face 2" +msgstr "\\Face 2" + +msgid "\\Face 3" +msgstr "\\Face 3" + +msgid "\\Face 4" +msgstr "\\Face 4" + +msgid "\\Green flags" +msgstr "\\Bandeiras verdes" + +msgid "\\New player name" +msgstr "\\Nome do novo jogador" + +msgid "\\No eyeglasses" +msgstr "\\Sem óculos" + +msgid "\\Raise the pencil" +msgstr "\\Levante o lápis" + +msgid "\\Red flags" +msgstr "\\Bandeiras vermelhas" + +msgid "\\Return to Colobot: Gold Edition" +msgstr "\\Voltar a Colobot: edição de ouro" + +msgid "\\SatCom on standby" +msgstr "\\SatCom em espera" + +msgid "\\Start recording" +msgstr "\\Iniciar gravação" + +msgid "\\Stop recording" +msgstr "\\Parar gravação" + +msgid "\\Turn left" +msgstr "\\Virar a esquerda" + +msgid "\\Turn right" +msgstr "\\Virar a direita" + +msgid "\\Use the black pencil" +msgstr "\\Use o lápis preto" + +msgid "\\Use the blue pencil" +msgstr "\\Use o lápis azul" + +msgid "\\Use the brown pencil" +msgstr "\\Use o lápis marrom" + +msgid "\\Use the green pencil" +msgstr "\\Use o lápis verde" + +msgid "\\Use the orange pencil" +msgstr "\\Use o lápis laranja" + +msgid "\\Use the purple pencil" +msgstr "\\Use o lápis roxo" + +msgid "\\Use the red pencil" +msgstr "\\Use o lápis vermelho" + +msgid "\\Use the yellow pencil" +msgstr "\\Use o lápis amarelo" + +msgid "\\Violet flags" +msgstr "\\Bandeiras violetas" + +msgid "\\Yellow flags" +msgstr "\\Bandeiras amarelas" + +msgid "colobot.info" +msgstr "colobot.info" + +msgid "epsitec.com" +msgstr "epsitec.com" + +#~ msgid " " +#~ msgstr " " + +#~ msgid " Drivers:" +#~ msgstr " Pilotes :" + +#~ msgid " Missions on this level:" +#~ msgstr " Missions du niveau :" + +#~ msgid "\"%s\" missing in this exercise" +#~ msgstr "Il manque \"%s\" dans le programme" + +#~ msgid "3D sound\\3D positioning of the sound" +#~ msgstr "Bruitages 3D\\Positionnement sonore dans l'espace" + +#~ msgid "Building too close" +#~ msgstr "Bâtiment trop proche" + +#~ msgid "COLOBOT" +#~ msgstr "COLOBOT" + +#~ msgid "Camera awayest" +#~ msgstr "Caméra plus loin" + +#~ msgid "Camera down\\Decrease camera angle while visiting message origin" +#~ msgstr "Caméra plus basse\\Réduit l'angle de caméra lors de la vue de l'origine des messages" + +#~ msgid "Camera nearest" +#~ msgstr "Caméra plus proche" + +#~ msgid "Camera to left" +#~ msgstr "Caméra à gauche" + +#~ msgid "Camera to right" +#~ msgstr "Caméra à droite" + +#~ msgid "Camera up\\Increase camera angle while visiting message origin" +#~ msgstr "Caméra plus haute\\Augmente l'angle de caméra lors de la vue de l'origine des messages" + +#~ msgid "Can not create this; there are too many objects" +#~ msgstr "Création impossible; il y a trop d'objets" + +#~ msgid "Cancel\\Keep current player name" +#~ msgstr "Annuler\\Conserver le joueur actuel" + +#~ msgid "Checkpoint crossed" +#~ msgstr "Indicateur atteint" + +#~ msgid "Compass" +#~ msgstr "Boussole" + +#~ msgid "Continue\\Continue the game" +#~ msgstr "Continuer\\Continuer de jouer" + +#~ msgid "Delete" +#~ msgstr "Détruire" + +#~ msgid "Details\\Visual quality of 3D objects" +#~ msgstr "Détails des objets\\Qualité des objets en 3D" + +#~ msgid "Developed by :" +#~ msgstr "Développé par :" + +#~ msgid "Do you want to quit Colobot: Gold Edition?" +#~ msgstr "Voulez-vous quitter Colobot: Édition Gold ?" + +#~ msgid "Exit film\\Film at the exit of exercises" +#~ msgstr "Retour animé\\Retour animé dans les exercices" + +#~ msgid "Friendly fire\\Your shooting can damage your own objects " +#~ msgstr "Dégâts à soi-même\\Vos tirs infligent des dommages à vos unités" + +#~ msgid "Ground inappropriate" +#~ msgstr "Terrain inadapté" + +#~ msgid "Key word help\\More detailed help about key words" +#~ msgstr "Instructions mot-clé\\Explication sur le mot-clé" + +#~ msgid "Marks on the ground\\Marks on the ground" +#~ msgstr "Marques sur le sol\\Marques dessinées sur le sol" + +#~ msgid "Mouse shadow\\Gives the mouse a shadow" +#~ msgstr "Souris ombrée\\Jolie souris avec une ombre" + +#~ msgid "No other robot" +#~ msgstr "Pas d'autre robot" + +#~ msgid "Not yet enough energy" +#~ msgstr "Pas encore assez d'énergie" + +#~ msgid "Num of decorative objects\\Number of purely ornamental objects" +#~ msgstr "Nb d'objets décoratifs\\Qualité d'objets non indispensables" + +#~ msgid "Planets and stars\\Astronomical objects in the sky" +#~ msgstr "Planètes et étoiles\\Motifs mobiles dans le ciel" + +#~ msgid "Quit the mission?" +#~ msgstr "Quitter la mission ?" + +#~ msgid "Quit\\Quit COLOBOT" +#~ msgstr "Quitter\\Quitter COLOBOT" + +#~ msgid "Robbie\\Your assistant" +#~ msgstr "Robbie\\Votre assistant" + +#~ msgid "Sky\\Clouds and nebulae" +#~ msgstr "Ciel\\Ciel et nuages" + +#~ msgid "Speed 0.5x\\Half speed" +#~ msgstr "Vitesse 0.5x\\Demi-vitesse" + +#~ msgid "Speed 1.0x\\Normal speed" +#~ msgstr "Vitesse 1.0x\\Vitesse normale" + +#~ msgid "Speed 1.5x\\1.5 times faster" +#~ msgstr "Vitesse 1.5x\\Une fois et demi plus rapide" + +#~ msgid "Speed 3.0x\\Three times faster" +#~ msgstr "Vitesse 3.0x\\Trois fois plus rapide" + +#~ msgid "Speed 3.0x\\Triple speed" +#~ msgstr "Vitesse 3.0x\\Trois fois plus rapide " + +#~ msgid "Speed 4.0x\\Quadruple speed" +#~ msgstr "Vitesse 4.0x\\Quatre fois plus rapide" + +#~ msgid "Speed 6.0x\\Sextuple speed" +#~ msgstr "Vitesse 6.0x\\Six fois plus rapide" + +#~ msgid "Sunbeams\\Sunbeams in the sky" +#~ msgstr "Rayons du soleil\\Rayons selon l'orientation" + +#~ msgid "System mouse\\Use system mouse cursor" +#~ msgstr "Souris système\\Utiliser le curseur de la souris système" + +#~ msgid "Textures\\Quality of textures " +#~ msgstr "Qualité des textures\\Qualité des images" + +#~ msgid "The list is only available if a \\l;radar station\\u object\\radar; is working.\n" +#~ msgstr "Liste non disponible sans \\l;radar\\u object\\radar;.\n" + +#~ msgid "Use a joystick\\Joystick or keyboard" +#~ msgstr "Utilise un joystick\\Joystick ou clavier" + +#~ msgid "User\\User levels" +#~ msgstr "Suppl.\\Niveaux supplémentaires" + +#~ msgid "\\Return to COLOBOT" +#~ msgstr "\\Retourner dans COLOBOT" + +#~ msgid "\\b;Aliens\n" +#~ msgstr "\\b;Listes des ennemis\n" + +#~ msgid "\\b;Buildings\n" +#~ msgstr "\\b;Listes des bâtiments\n" + +#~ msgid "\\b;Error\n" +#~ msgstr "\\b;Erreur\n" + +#~ msgid "\\b;List of objects\n" +#~ msgstr "\\b;Listes des objets\n" + +#~ msgid "\\b;Moveable objects\n" +#~ msgstr "\\b;Listes des objets transportables\n" + +#~ msgid "\\b;Robots\n" +#~ msgstr "\\b;Listes des robots\n" + +#~ msgid "\\c; (none)\\n;\n" +#~ msgstr "\\c; (aucun)\\n;\n" diff --git a/src/app/app.cpp b/src/app/app.cpp index 3444481c..c9fbf296 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -1718,6 +1718,11 @@ char CApplication::GetLanguageChar() const case LANGUAGE_RUSSIAN: langChar = 'R'; break; + + case LANGUAGE_PORTUGUESE_BRAZILIAN: + langChar = 'B'; + break; + } return langChar; } @@ -1774,6 +1779,10 @@ void CApplication::SetLanguage(Language language) { m_language = LANGUAGE_RUSSIAN; } + else if (strncmp(envLang,"br",2) == 0) + { + m_language = LANGUAGE_PORTUGUESE_BRAZILIAN; + } else { GetLogger()->Warn("Enviromnent locale ('%s') is not supported, setting default language\n", envLang); @@ -1812,6 +1821,10 @@ void CApplication::SetLanguage(Language language) case LANGUAGE_RUSSIAN: locale = "ru_RU.utf8"; break; + + case LANGUAGE_PORTUGUESE_BRAZILIAN: + locale = "pt_BR.utf8"; + break; } std::string langStr = "LANGUAGE="; diff --git a/src/common/language.cpp b/src/common/language.cpp index a9f62419..d1990b49 100644 --- a/src/common/language.cpp +++ b/src/common/language.cpp @@ -27,7 +27,8 @@ const std::map LANGUAGE_MAP = { { LANGUAGE_GERMAN, "de" }, { LANGUAGE_FRENCH, "fr" }, { LANGUAGE_POLISH, "pl" }, - { LANGUAGE_RUSSIAN, "ru" } + { LANGUAGE_RUSSIAN, "ru" }, + { LANGUAGE_PORTUGUESE_BRAZILIAN, "br" } }; bool ParseLanguage(const std::string& str, Language& language) diff --git a/src/common/language.h b/src/common/language.h index f25f7f77..0310cb73 100644 --- a/src/common/language.h +++ b/src/common/language.h @@ -33,7 +33,8 @@ enum Language LANGUAGE_GERMAN = 2, LANGUAGE_POLISH = 3, LANGUAGE_RUSSIAN = 4, - LANGUAGE_CZECH = 5 + LANGUAGE_CZECH = 5, + LANGUAGE_PORTUGUESE_BRAZILIAN = 6 }; bool ParseLanguage(const std::string& str, Language& language); diff --git a/src/ui/screen/screen_setup_game.cpp b/src/ui/screen/screen_setup_game.cpp index cb4af8f4..a076ab59 100644 --- a/src/ui/screen/screen_setup_game.cpp +++ b/src/ui/screen/screen_setup_game.cpp @@ -149,6 +149,7 @@ void CScreenSetupGame::CreateInterface() pli->SetItemName(1+LANGUAGE_GERMAN, "German"); pli->SetItemName(1+LANGUAGE_POLISH, "Polish"); pli->SetItemName(1+LANGUAGE_RUSSIAN, "Russian"); + pli->SetItemName(1+LANGUAGE_PORTUGUESE_BRAZILIAN, "Brazilian Portuguese"); UpdateSetupButtons(); } From be1066912fadc29914b30994211b825d6b42471b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Robson=20Mariano=20Alves?= Date: Tue, 15 May 2018 16:50:42 -0300 Subject: [PATCH 043/109] Translation to Brazilian Portuguese --- po/br.po | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/po/br.po b/po/br.po index 956b6d2f..dc710c46 100644 --- a/po/br.po +++ b/po/br.po @@ -1560,6 +1560,10 @@ msgstr "Bater (\\key action;)" msgid "Thumper" msgstr "Batedor" +#, c-format +msgid "Time: %s" +msgstr "Tempo: %s" + msgid "Titanium" msgstr "Titânio" From dbd1f601da7e7468662aca9c173edf15de667da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Robson=20Mariano=20Alves?= Date: Tue, 15 May 2018 18:31:41 -0300 Subject: [PATCH 044/109] Translation to Brazilian Portuguese --- data | 2 +- po/{br.po => pt.po} | 0 src/app/app.cpp | 4 ++-- src/common/language.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename po/{br.po => pt.po} (100%) diff --git a/data b/data index 3cbab714..8597221e 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 3cbab7144e6bf940015b2c33fdd17c7c2bfa804b +Subproject commit 8597221e4ddbb9016e7aba46c508dca84f3aa1d6 diff --git a/po/br.po b/po/pt.po similarity index 100% rename from po/br.po rename to po/pt.po diff --git a/src/app/app.cpp b/src/app/app.cpp index c9fbf296..780bc5fb 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -1720,7 +1720,7 @@ char CApplication::GetLanguageChar() const break; case LANGUAGE_PORTUGUESE_BRAZILIAN: - langChar = 'B'; + langChar = 'P'; break; } @@ -1779,7 +1779,7 @@ void CApplication::SetLanguage(Language language) { m_language = LANGUAGE_RUSSIAN; } - else if (strncmp(envLang,"br",2) == 0) + else if (strncmp(envLang,"pt",2) == 0) { m_language = LANGUAGE_PORTUGUESE_BRAZILIAN; } diff --git a/src/common/language.cpp b/src/common/language.cpp index d1990b49..37a8dca1 100644 --- a/src/common/language.cpp +++ b/src/common/language.cpp @@ -28,7 +28,7 @@ const std::map LANGUAGE_MAP = { { LANGUAGE_FRENCH, "fr" }, { LANGUAGE_POLISH, "pl" }, { LANGUAGE_RUSSIAN, "ru" }, - { LANGUAGE_PORTUGUESE_BRAZILIAN, "br" } + { LANGUAGE_PORTUGUESE_BRAZILIAN, "pt" } }; bool ParseLanguage(const std::string& str, Language& language) From 17447e813b97a68861c2ad257e7cead16724c16b Mon Sep 17 00:00:00 2001 From: krzys-h Date: Wed, 16 May 2018 11:55:06 +0200 Subject: [PATCH 045/109] Fix building of colobot.rc on Windows --- desktop/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/desktop/CMakeLists.txt b/desktop/CMakeLists.txt index dcca3b77..b49ef2d3 100644 --- a/desktop/CMakeLists.txt +++ b/desktop/CMakeLists.txt @@ -145,7 +145,12 @@ if(PLATFORM_MACOSX) endif(PLATFORM_MACOSX) if(PLATFORM_WINDOWS) - set(COLOBOT_VERSION_4COMMAS "${COLOBOT_VERSION_MAJOR},${COLOBOT_VERSION_MINOR},${COLOBOT_VERSION_REVISION},0") + if(COLOBOT_VERSION_REVISION MATCHES "([0-9]+)\\.([0-9]+)") + string(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\1,\\2" COLOBOT_VERSION_REVISION_COMMA "${COLOBOT_VERSION_REVISION}") + set(COLOBOT_VERSION_4COMMAS "${COLOBOT_VERSION_MAJOR},${COLOBOT_VERSION_MINOR},${COLOBOT_VERSION_REVISION_COMMA}") + else() + set(COLOBOT_VERSION_4COMMAS "${COLOBOT_VERSION_MAJOR},${COLOBOT_VERSION_MINOR},${COLOBOT_VERSION_REVISION},0") + endif() configure_file(colobot.rc.cmake ${CMAKE_CURRENT_BINARY_DIR}/colobot.rc) endif(PLATFORM_WINDOWS) From 073191d1eaaa0a82923ebf936e7ce2b388ebdf9c Mon Sep 17 00:00:00 2001 From: krzys-h Date: Wed, 16 May 2018 13:28:06 +0200 Subject: [PATCH 046/109] Small CPathManager refactoring --- CMakeLists.txt | 31 ++++---- src/app/pathman.cpp | 90 ++++++++++++++++-------- src/app/pathman.h | 26 ++++--- src/common/config.h.cmake | 2 +- src/common/resources/resourcemanager.cpp | 10 +++ src/common/resources/resourcemanager.h | 4 ++ src/common/system/system.cpp | 2 +- src/common/system/system_linux.cpp | 7 +- src/common/system/system_macosx.cpp | 5 ++ src/common/system/system_windows.cpp | 7 +- 10 files changed, 120 insertions(+), 64 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ab7f22a..9b96d6b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,6 +201,9 @@ option(OFFICIAL_BUILD "Official build (changes crash screen text)" OFF) # Portable build - load all data from current directory option(PORTABLE "Portable build" OFF) +# Portable saves - suitable for e.g. putting the whole game on external storage and moving your saves with it +option(PORTABLE_SAVES "Portable saves" OFF) + # Building tests can be enabled/disabled option(TESTS "Build tests" OFF) @@ -350,21 +353,19 @@ endif() ## # Installation paths defined before compiling sources -if(PLATFORM_WINDOWS) - if(MXE) - # We need to use STRING because PATH doesn't accept relative paths - set(COLOBOT_INSTALL_BIN_DIR ./ CACHE STRING "Colobot binary directory") - set(COLOBOT_INSTALL_LIB_DIR ./ CACHE STRING "Colobot libraries directory") - set(COLOBOT_INSTALL_DATA_DIR ./data CACHE STRING "Colobot shared data directory") - set(COLOBOT_INSTALL_I18N_DIR ./lang CACHE STRING "Colobot translations directory") - set(COLOBOT_INSTALL_DOC_DIR ./doc CACHE STRING "Colobot documentation directory") - else() - set(COLOBOT_INSTALL_BIN_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot binary directory") - set(COLOBOT_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot libraries directory") - set(COLOBOT_INSTALL_DATA_DIR ${CMAKE_INSTALL_PREFIX}/data CACHE PATH "Colobot shared data directory") - set(COLOBOT_INSTALL_I18N_DIR ${CMAKE_INSTALL_PREFIX}/lang CACHE PATH "Colobot translations directory") - set(COLOBOT_INSTALL_DOC_DIR ${CMAKE_INSTALL_PREFIX}/doc CACHE PATH "Colobot documentation directory") - endif() +if(PORTABLE OR (PLATFORM_WINDOWS AND MXE)) + # We need to use STRING because PATH doesn't accept relative paths + set(COLOBOT_INSTALL_BIN_DIR ./ CACHE STRING "Colobot binary directory") + set(COLOBOT_INSTALL_LIB_DIR ./ CACHE STRING "Colobot libraries directory") + set(COLOBOT_INSTALL_DATA_DIR ./data CACHE STRING "Colobot shared data directory") + set(COLOBOT_INSTALL_I18N_DIR ./lang CACHE STRING "Colobot translations directory") + set(COLOBOT_INSTALL_DOC_DIR ./doc CACHE STRING "Colobot documentation directory") +elseif(PLATFORM_WINDOWS) + set(COLOBOT_INSTALL_BIN_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot binary directory") + set(COLOBOT_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/ CACHE PATH "Colobot libraries directory") + set(COLOBOT_INSTALL_DATA_DIR ${CMAKE_INSTALL_PREFIX}/data CACHE PATH "Colobot shared data directory") + set(COLOBOT_INSTALL_I18N_DIR ${CMAKE_INSTALL_PREFIX}/lang CACHE PATH "Colobot translations directory") + set(COLOBOT_INSTALL_DOC_DIR ${CMAKE_INSTALL_PREFIX}/doc CACHE PATH "Colobot documentation directory") elseif(PLATFORM_MACOSX) set(COLOBOT_INSTALL_BIN_DIR ../MacOS CACHE STRING "Colobot binary directory") set(COLOBOT_INSTALL_LIB_DIR ../MacOS CACHE STRING "Colobot libraries directory") diff --git a/src/app/pathman.cpp b/src/app/pathman.cpp index e86780e5..60715ac1 100644 --- a/src/app/pathman.cpp +++ b/src/app/pathman.cpp @@ -38,46 +38,41 @@ #include CPathManager::CPathManager(CSystemUtils* systemUtils) - : m_systemUtils(systemUtils) + : m_dataPath(systemUtils->GetDataPath()) + , m_langPath(systemUtils->GetLangPath()) + , m_savePath(systemUtils->GetSaveDir()) + , m_modAutoloadDir{ m_dataPath + "/mods", m_savePath + "/mods" } + , m_mods{} { - #ifdef PORTABLE - m_dataPath = "./data"; - m_langPath = "./lang"; - m_savePath = "./saves"; - #else - m_dataPath = m_systemUtils->GetDataPath(); - m_langPath = m_systemUtils->GetLangPath(); - #ifdef DEV_BUILD - m_savePath = "./saves"; - #else - m_savePath = m_systemUtils->GetSaveDir(); - #endif - #endif } CPathManager::~CPathManager() { } -void CPathManager::SetDataPath(std::string dataPath) +void CPathManager::SetDataPath(const std::string &dataPath) { m_dataPath = dataPath; } -void CPathManager::SetLangPath(std::string langPath) +void CPathManager::SetLangPath(const std::string &langPath) { m_langPath = langPath; } -void CPathManager::SetSavePath(std::string savePath) +void CPathManager::SetSavePath(const std::string &savePath) { m_savePath = savePath; } -void CPathManager::AddMod(std::string modPath) +void CPathManager::AddModAutoloadDir(const std::string &modAutoloadDirPath) { - GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str()); - CResourceManager::AddLocation(modPath, true); + m_modAutoloadDir.push_back(modAutoloadDirPath); +} + +void CPathManager::AddMod(const std::string &modPath) +{ + m_mods.push_back(modPath); } const std::string& CPathManager::GetDataPath() @@ -106,8 +101,8 @@ std::string CPathManager::VerifyPaths() { GetLogger()->Error("Data directory '%s' doesn't exist or is not a directory\n", m_dataPath.c_str()); return std::string("Could not read from data directory:\n") + - std::string("'") + m_dataPath + std::string("'\n") + - std::string("Please check your installation, or supply a valid data directory by -datadir option."); + std::string("'") + m_dataPath + std::string("'\n") + + std::string("Please check your installation, or supply a valid data directory by -datadir option."); } #if PLATFORM_WINDOWS @@ -133,19 +128,51 @@ std::string CPathManager::VerifyPaths() void CPathManager::InitPaths() { - LoadModsFromDir(m_dataPath+"/mods"); - LoadModsFromDir(m_savePath+"/mods"); - GetLogger()->Info("Data path: %s\n", m_dataPath.c_str()); GetLogger()->Info("Save path: %s\n", m_savePath.c_str()); - CResourceManager::AddLocation(m_dataPath, false); + if (!m_modAutoloadDir.empty()) + { + GetLogger()->Info("Mod autoload dirs:\n"); + for(const std::string& modAutoloadDir : m_modAutoloadDir) + GetLogger()->Info(" * %s\n", modAutoloadDir.c_str()); + } + if (!m_mods.empty()) + { + GetLogger()->Info("Mods:\n"); + for(const std::string& modPath : m_mods) + GetLogger()->Info(" * %s\n", modPath.c_str()); + } + + CResourceManager::AddLocation(m_dataPath); + + for (const std::string& modAutoloadDir : m_modAutoloadDir) + { + GetLogger()->Trace("Searching for mods in '%s'...\n", modAutoloadDir.c_str()); + for (const std::string& modPath : FindModsInDir(modAutoloadDir)) + { + GetLogger()->Info("Autoloading mod: '%s'\n", modPath.c_str()); + CResourceManager::AddLocation(modPath); + } + } + + for (const std::string& modPath : m_mods) + { + GetLogger()->Info("Loading mod: '%s'\n", modPath.c_str()); + CResourceManager::AddLocation(modPath); + } + CResourceManager::SetSaveLocation(m_savePath); - CResourceManager::AddLocation(m_savePath, true); + CResourceManager::AddLocation(m_savePath); + + GetLogger()->Debug("Finished initalizing data paths\n"); + GetLogger()->Debug("PHYSFS search path is:\n"); + for (const std::string& path : CResourceManager::GetLocations()) + GetLogger()->Debug(" * %s\n", path.c_str()); } -void CPathManager::LoadModsFromDir(const std::string &dir) +std::vector CPathManager::FindModsInDir(const std::string &dir) { - GetLogger()->Trace("Looking for mods in '%s' ...\n", dir.c_str()); + std::vector ret; try { #if PLATFORM_WINDOWS @@ -156,9 +183,9 @@ void CPathManager::LoadModsFromDir(const std::string &dir) for(; iterator != boost::filesystem::directory_iterator(); ++iterator) { #if PLATFORM_WINDOWS - AddMod(CSystemUtilsWindows::UTF8_Encode(iterator->path().wstring())); + ret.push_back(CSystemUtilsWindows::UTF8_Encode(iterator->path().wstring())); #else - AddMod(iterator->path().string()); + ret.push_back(iterator->path().string()); #endif } } @@ -166,4 +193,5 @@ void CPathManager::LoadModsFromDir(const std::string &dir) { GetLogger()->Warn("Unable to load mods from directory '%s': %s\n", dir.c_str(), e.what()); } + return ret; } diff --git a/src/app/pathman.h b/src/app/pathman.h index 39c780df..dd18d66e 100644 --- a/src/app/pathman.h +++ b/src/app/pathman.h @@ -17,16 +17,10 @@ * along with this program. If not, see http://gnu.org/licenses */ -/** - * \file app/pathman.h - * \brief Class for managing data/lang/save paths - */ - #pragma once -#include "common/singleton.h" - #include +#include class CSystemUtils; @@ -34,16 +28,17 @@ class CSystemUtils; * \class CPathManager * \brief Class for managing data/lang/save paths */ -class CPathManager : public CSingleton +class CPathManager { public: CPathManager(CSystemUtils* systemUtils); ~CPathManager(); - void SetDataPath(std::string dataPath); - void SetLangPath(std::string langPath); - void SetSavePath(std::string savePath); - void AddMod(std::string modPath); + void SetDataPath(const std::string &dataPath); + void SetLangPath(const std::string &langPath); + void SetSavePath(const std::string &savePath); + void AddModAutoloadDir(const std::string &modAutoloadDirPath); + void AddMod(const std::string &modPath); const std::string& GetDataPath(); const std::string& GetLangPath(); @@ -56,14 +51,17 @@ public: private: //! Loads all mods from given directory - void LoadModsFromDir(const std::string &dir); + std::vector FindModsInDir(const std::string &dir); private: - CSystemUtils* m_systemUtils; //! Data path std::string m_dataPath; //! Lang path std::string m_langPath; //! Save path std::string m_savePath; + //! Mod autoload paths + std::vector m_modAutoloadDir; + //! Mod paths + std::vector m_mods; }; diff --git a/src/common/config.h.cmake b/src/common/config.h.cmake index b4767724..f6d0bcae 100644 --- a/src/common/config.h.cmake +++ b/src/common/config.h.cmake @@ -16,7 +16,7 @@ #cmakedefine OPENAL_SOUND -#cmakedefine PORTABLE @PORTABLE@ +#cmakedefine PORTABLE_SAVES @PORTABLE_SAVES@ #define COLOBOT_DEFAULT_DATADIR "@COLOBOT_INSTALL_DATA_DIR@" #define COLOBOT_I18N_DIR "@COLOBOT_INSTALL_I18N_DIR@" diff --git a/src/common/resources/resourcemanager.cpp b/src/common/resources/resourcemanager.cpp index 820495b8..0ad82816 100644 --- a/src/common/resources/resourcemanager.cpp +++ b/src/common/resources/resourcemanager.cpp @@ -85,6 +85,16 @@ bool CResourceManager::RemoveLocation(const std::string &location) return true; } +std::vector CResourceManager::GetLocations() +{ + std::vector ret; + char **list = PHYSFS_getSearchPath(); + for (char **it = list; *it != nullptr; ++it) + ret.push_back(*it); + PHYSFS_freeList(list); + return ret; +} + bool CResourceManager::SetSaveLocation(const std::string &location) { diff --git a/src/common/resources/resourcemanager.h b/src/common/resources/resourcemanager.h index d0b4ab24..95661a4f 100644 --- a/src/common/resources/resourcemanager.h +++ b/src/common/resources/resourcemanager.h @@ -35,8 +35,12 @@ public: static std::string CleanPath(const std::string &path); + //! Add a location to the search path static bool AddLocation(const std::string &location, bool prepend = true); + //! Remove a location from the search path static bool RemoveLocation(const std::string &location); + //! List all locations in the search path + static std::vector GetLocations(); static bool SetSaveLocation(const std::string &location); static std::string GetSaveLocation(); diff --git a/src/common/system/system.cpp b/src/common/system/system.cpp index 01b633cc..44064556 100644 --- a/src/common/system/system.cpp +++ b/src/common/system/system.cpp @@ -190,5 +190,5 @@ std::string CSystemUtils::GetLangPath() std::string CSystemUtils::GetSaveDir() { - return std::string("saves"); + return "./saves"; } diff --git a/src/common/system/system_linux.cpp b/src/common/system/system_linux.cpp index 3cd25ed2..6578830d 100644 --- a/src/common/system/system_linux.cpp +++ b/src/common/system/system_linux.cpp @@ -96,6 +96,9 @@ long long CSystemUtilsLinux::TimeStampExactDiff(SystemTimeStamp *before, SystemT std::string CSystemUtilsLinux::GetSaveDir() { +#if PORTABLE_SAVES || DEV_BUILD + return CSystemUtils::GetSaveDir(); +#else std::string savegameDir; // Determine savegame dir according to XDG Base Directory Specification @@ -105,7 +108,8 @@ std::string CSystemUtilsLinux::GetSaveDir() char *envHOME = getenv("HOME"); if (envHOME == nullptr) { - savegameDir = "/tmp/colobot-save"; + GetLogger()->Warn("Unable to find directory for saves - using current directory"); + savegameDir = "./saves"; } else { @@ -119,6 +123,7 @@ std::string CSystemUtilsLinux::GetSaveDir() GetLogger()->Trace("Saved game files are going to %s\n", savegameDir.c_str()); return savegameDir; +#endif } void CSystemUtilsLinux::Usleep(int usec) diff --git a/src/common/system/system_macosx.cpp b/src/common/system/system_macosx.cpp index ede5b481..9ef7ce1d 100644 --- a/src/common/system/system_macosx.cpp +++ b/src/common/system/system_macosx.cpp @@ -102,10 +102,15 @@ std::string CSystemUtilsMacOSX::GetLangPath() std::string CSystemUtilsMacOSX::GetSaveDir() { +#if PORTABLE_SAVES || DEV_BUILD + // TODO: I have no idea if this actually works on Mac OS + return "./saves"; +#else std::string savegameDir = m_ASPath; GetLogger()->Trace("Saved game files are going to %s\n", savegameDir.c_str()); return savegameDir; +#endif } void CSystemUtilsMacOSX::Usleep(int usec) diff --git a/src/common/system/system_windows.cpp b/src/common/system/system_windows.cpp index f51959b4..e459cf00 100644 --- a/src/common/system/system_windows.cpp +++ b/src/common/system/system_windows.cpp @@ -110,12 +110,16 @@ std::wstring CSystemUtilsWindows::UTF8_Decode(const std::string& str) std::string CSystemUtilsWindows::GetSaveDir() { +#if PORTABLE_SAVES || DEV_BUILD + return "./saves"; +#else std::string savegameDir; wchar_t* envUSERPROFILE = _wgetenv(L"USERPROFILE"); if (envUSERPROFILE == nullptr) { - savegameDir = "./saves"; + GetLogger()->Warn("Unable to find directory for saves - using current directory"); + savegameDir = CSystemUtils::GetSaveDir(false); } else { @@ -124,6 +128,7 @@ std::string CSystemUtilsWindows::GetSaveDir() GetLogger()->Trace("Saved game files are going to %s\n", savegameDir.c_str()); return savegameDir; +#endif } void CSystemUtilsWindows::Usleep(int usec) From 0c16d9a2729dc2d7caa44b153c454f9e6c58e07e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Robson=20Mariano=20Alves?= Date: Wed, 16 May 2018 10:22:57 -0300 Subject: [PATCH 047/109] Translation to Brazilian Portuguese --- src/app/app.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 780bc5fb..8743e91e 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -1720,7 +1720,7 @@ char CApplication::GetLanguageChar() const break; case LANGUAGE_PORTUGUESE_BRAZILIAN: - langChar = 'P'; + langChar = 'B'; break; } From abb7d54ef5d88818030f18b9e187a1067f6c5a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Przyby=C5=82?= Date: Mon, 4 Jun 2018 09:17:51 +0200 Subject: [PATCH 048/109] Add support for VS CMake/vcpkg compilation (#1174) * Add support for VS CMake/vcpkg compilation * Fix system_windows.cpp compilation * Add optimization and hidden console to MSVC release builds --- .gitignore | 4 +++ CMakeLists.txt | 21 ++++++++++--- cmake/FindLibSndFile.cmake | 2 +- cmake/FindPhysFS.cmake | 2 +- src/CBot/CBotDebug.cpp | 1 + src/CBot/CMakeLists.txt | 5 +++ src/CMakeLists.txt | 47 ++++++++++++++++++++++++++-- src/common/system/system_windows.cpp | 4 +-- 8 files changed, 76 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index f9f69301..f3461be1 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,7 @@ CMakeLists.txt.user.* # Ignore Visual Studio Code files /.vscode + +# Ignore Visual Studio files +/CMakeSettings.json +/.vs diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b96d6b6..44a63de6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,9 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) # Include cmake directory with some additional scripts set(CMAKE_MODULE_PATH "${colobot_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) +# MSVC needs different flags if linking statically +option(MSVC_STATIC "Link statically when using MSVC" OFF) + # Compiler detection if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) @@ -160,14 +163,19 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") message(STATUS "Detected MSVC compiler") set(NORMAL_CXX_FLAGS "/wd\"4244\" /wd\"4309\" /wd\"4800\" /wd\"4996\" /wd\"4351\" /EHsc") # disable some useless warnings - set(RELEASE_CXX_FLAGS "/MD") - set(DEBUG_CXX_FLAGS "/MDd /ZI") + if(MSVC_STATIC) + set(RELEASE_CXX_FLAGS "/MT /Ox") + set(DEBUG_CXX_FLAGS "/MTd /ZI") + else(MSVC_STATIC) + set(RELEASE_CXX_FLAGS "/MD /Ox") + set(DEBUG_CXX_FLAGS "/MDd /ZI") + endif() set(TEST_CXX_FLAGS "") add_definitions(-DNOEXCEPT= -DHAS_MSVC_EXCEPTION_BUG) # Needed for Debug information (it's set to "No" by default for some reason) - set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG") - set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG") + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS} /DEBUG") + set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS} /DEBUG") else() message(FATAL_ERROR "Your C++ compiler doesn't seem to be supported.") endif() @@ -315,6 +323,11 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") set(CBOT_STATIC 1) # only this works for some reason set(WINGETOPT 1) # use wingetopt library + + # Hide console in release builds + if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CMAKE_WIN32_EXECUTABLE 1) + endif() endif() ## diff --git a/cmake/FindLibSndFile.cmake b/cmake/FindLibSndFile.cmake index 8666c66f..7a6d32b6 100644 --- a/cmake/FindLibSndFile.cmake +++ b/cmake/FindLibSndFile.cmake @@ -5,7 +5,7 @@ FIND_PATH(LIBSNDFILE_INCLUDE_DIR sndfile.h) -SET(LIBSNDFILE_NAMES ${LIBSNDFILE_NAMES} sndfile libsndfile) +SET(LIBSNDFILE_NAMES ${LIBSNDFILE_NAMES} sndfile libsndfile libsndfile-1) FIND_LIBRARY(LIBSNDFILE_LIBRARY NAMES ${LIBSNDFILE_NAMES} PATH) IF(LIBSNDFILE_INCLUDE_DIR AND LIBSNDFILE_LIBRARY) diff --git a/cmake/FindPhysFS.cmake b/cmake/FindPhysFS.cmake index fae83786..6d4c93d4 100644 --- a/cmake/FindPhysFS.cmake +++ b/cmake/FindPhysFS.cmake @@ -7,7 +7,7 @@ IF (WIN32) FIND_PATH( PHYSFS_INCLUDE_PATH physfs.h DOC "The directory where physfs.h resides") FIND_LIBRARY( PHYSFS_LIBRARY - NAMES physfs + NAMES physfs physfs-static PATHS /mingw/lib DOC "The PhysFS library") ELSE (WIN32) diff --git a/src/CBot/CBotDebug.cpp b/src/CBot/CBotDebug.cpp index 892d1d0e..bef509b0 100644 --- a/src/CBot/CBotDebug.cpp +++ b/src/CBot/CBotDebug.cpp @@ -23,6 +23,7 @@ #include "CBot/CBotInstr/CBotFunction.h" #include "CBot/CBotInstr/CBotInstrCall.h" +#include #include #include #include diff --git a/src/CBot/CMakeLists.txt b/src/CBot/CMakeLists.txt index dcb39e1a..a9a83e2e 100644 --- a/src/CBot/CMakeLists.txt +++ b/src/CBot/CMakeLists.txt @@ -151,7 +151,12 @@ set(LOCAL_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/.. ) +set(SYSTEM_INCLUDES + ${Boost_INCLUDE_DIRS} +) + include_directories(${LOCAL_INCLUDES}) +include_directories(SYSTEM ${SYSTEM_INCLUDES}) if(CBOT_STATIC) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e0857506..0a924344 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,8 +44,51 @@ if(MXE) # MXE requires special treatment elseif(PLATFORM_WINDOWS) # because it isn't included in standard linking libraries if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - find_library(LIBINTL_LIBRARY NAMES intl.lib) - set(PLATFORM_LIBS ${LIBINTL_LIBRARY}) + find_library(LIBINTL_LIBRARY NAMES intl.lib libintl) + + if(${MSVC_STATIC}) + if (${OPENAL_SOUND}) + find_library(FLAC_LIBRARY NAMES flac.lib) + find_library(VORBIS_LIBRARY NAMES vorbis.lib) + find_library(VORBISENC_LIBRARY NAMES vorbisenc.lib) + find_library(OGG_LIBRARY NAMES ogg.lib) + set(OPENAL_MSVC_LIBS + ${FLAC_LIBRARY} + ${VORBIS_LIBRARY} + ${VORBISENC_LIBRARY} + ${OGG_LIBRARY} + ) + endif() + + find_library(BZ2_LIBRARY NAMES bz2.lib) + find_library(JPEG_LIBRARY NAMES jpeg.lib) + find_library(TIFF_LIBRARY NAMES tiff.lib) + find_library(WEBP_LIBRARY NAMES webp.lib) + find_library(LZMA_LIBRARY NAMES lzma.lib) + find_library(FREETYPE_LIBRARY NAMES freetype.lib) + set(MSVC_LIBS + ${LIBINTL_LIBRARY} + ${OPENAL_MSVC_LIBS} + ${JPEG_LIBRARY} + ${TIFF_LIBRARY} + ${BZ2_LIBRARY} + ${WEBP_LIBRARY} + ${LZMA_LIBRARY} + ${FREETYPE_LIBRARY} + winmm.lib + dxguid.lib + imm32.lib + ole32.lib + oleaut32.lib + version.lib + wsock32.lib + ws2_32.lib + ) + else(${MSVC_STATIC}) + set(MSVC_LIBS ${LIBINTL_LIBRARY}) + endif() + + set(PLATFORM_LIBS ${MSVC_LIBS}) else() set(PLATFORM_LIBS "-lintl") endif() diff --git a/src/common/system/system_windows.cpp b/src/common/system/system_windows.cpp index e459cf00..a20bfcf1 100644 --- a/src/common/system/system_windows.cpp +++ b/src/common/system/system_windows.cpp @@ -111,7 +111,7 @@ std::wstring CSystemUtilsWindows::UTF8_Decode(const std::string& str) std::string CSystemUtilsWindows::GetSaveDir() { #if PORTABLE_SAVES || DEV_BUILD - return "./saves"; + return CSystemUtils::GetSaveDir(); #else std::string savegameDir; @@ -119,7 +119,7 @@ std::string CSystemUtilsWindows::GetSaveDir() if (envUSERPROFILE == nullptr) { GetLogger()->Warn("Unable to find directory for saves - using current directory"); - savegameDir = CSystemUtils::GetSaveDir(false); + savegameDir = "./saves"; } else { From 359abf9a823735ad8d22da8f60deb53b8f3adb8f Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Thu, 5 Jul 2018 19:43:56 +0200 Subject: [PATCH 049/109] Add VSync switch to Device tab --- src/app/app.cpp | 16 +++++++- src/common/event.cpp | 1 + src/common/event.h | 1 + src/common/restext.cpp | 1 + src/common/settings.cpp | 5 +++ src/graphics/engine/engine.cpp | 15 ++++++++ src/graphics/engine/engine.h | 10 +++++ src/ui/screen/screen_setup_display.cpp | 52 ++++++++++++++++++++++++++ 8 files changed, 99 insertions(+), 2 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 3444481c..9ec5f17e 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -817,9 +817,15 @@ bool CApplication::CreateVideoSurface() int vsync = 0; if (GetConfigFile().GetIntProperty("Experimental", "VSync", vsync)) { - SDL_GL_SetSwapInterval(vsync); + if (SDL_GL_SetSwapInterval(vsync) == -1) + { + GetLogger()->Warn("Adaptive sync not supported.\n"); + vsync = 1; + SDL_GL_SetSwapInterval(vsync); + GetConfigFile().SetIntProperty("Experimental", "VSync", vsync); + } - GetLogger()->Info("Using Vsync: %s\n", (vsync ? "true" : "false")); + GetLogger()->Info("Using Vsync: %s\n", (vsync == -1 ? "adaptive" : (vsync ? "true" : "false"))); } return true; @@ -832,6 +838,12 @@ bool CApplication::ChangeVideoConfig(const Gfx::DeviceConfig &newConfig) // TODO: Somehow this doesn't work for maximized windows (at least on Ubuntu) SDL_SetWindowSize(m_private->window, m_deviceConfig.size.x, m_deviceConfig.size.y); SDL_SetWindowFullscreen(m_private->window, m_deviceConfig.fullScreen ? SDL_WINDOW_FULLSCREEN : 0); + if( SDL_GL_SetSwapInterval(m_engine->GetVSync()) == -1 ) + { + GetLogger()->Warn("Adaptive sync not supported.\n"); + m_engine->SetVSync(1); + SDL_GL_SetSwapInterval(1); + } m_device->ConfigChanged(m_deviceConfig); diff --git a/src/common/event.cpp b/src/common/event.cpp index 8dded9e1..302c2702 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -232,6 +232,7 @@ void InitializeEventTypeTexts() EVENT_TYPE_TEXT[EVENT_INTERFACE_SHADOW_MAPPING_QUALITY] = "EVENT_INTERFACE_SHADOW_MAPPING_QUALITY"; EVENT_TYPE_TEXT[EVENT_INTERFACE_SHADOW_MAPPING_BUFFER] = "EVENT_INTERFACE_SHADOW_MAPPING_BUFFER"; EVENT_TYPE_TEXT[EVENT_INTERFACE_LANGUAGE] = "EVENT_INTERFACE_LANGUAGE"; + EVENT_TYPE_TEXT[EVENT_INTERFACE_VSYNC] = "EVENT_INTERFACE_VSYNC"; EVENT_TYPE_TEXT[EVENT_INTERFACE_KINFO1] = "EVENT_INTERFACE_KINFO1"; EVENT_TYPE_TEXT[EVENT_INTERFACE_KINFO2] = "EVENT_INTERFACE_KINFO2"; diff --git a/src/common/event.h b/src/common/event.h index 64c52e41..a9353e5e 100644 --- a/src/common/event.h +++ b/src/common/event.h @@ -268,6 +268,7 @@ enum EventType EVENT_INTERFACE_SHADOW_MAPPING_QUALITY = 788, EVENT_INTERFACE_SHADOW_MAPPING_BUFFER = 789, EVENT_INTERFACE_LANGUAGE = 790, + EVENT_INTERFACE_VSYNC = 791, EVENT_INTERFACE_KINFO1 = 500, EVENT_INTERFACE_KINFO2 = 501, diff --git a/src/common/restext.cpp b/src/common/restext.cpp index 9bac8434..c8602329 100644 --- a/src/common/restext.cpp +++ b/src/common/restext.cpp @@ -216,6 +216,7 @@ void InitializeRestext() stringsEvent[EVENT_INTERFACE_SHADOW_MAPPING] = TR("Dynamic shadows\\Beautiful shadows!"); stringsEvent[EVENT_INTERFACE_SHADOW_MAPPING_QUALITY]= TR("Dynamic shadows ++\\Dynamic shadows + self shadowing"); stringsEvent[EVENT_INTERFACE_SHADOW_MAPPING_BUFFER] = TR("Shadow resolution\\Higher means better range and quality, but slower"); + stringsEvent[EVENT_INTERFACE_VSYNC] = TR("Vertical Synchronization\\Limits the number of frames per second to display frequency"); stringsEvent[EVENT_INTERFACE_KDEF] = TR("Standard controls\\Standard key functions"); assert(INPUT_SLOT_MAX < EVENT_INTERFACE_KEY_END-EVENT_INTERFACE_KEY); diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 93db8102..1094d9eb 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -112,6 +112,7 @@ void CSettings::SaveSettings() // Experimental settings GetConfigFile().SetBoolProperty("Experimental", "TerrainShadows", engine->GetTerrainShadows()); + GetConfigFile().SetIntProperty("Experimental", "VSync", engine->GetVSync()); CInput::GetInstancePointer()->SaveKeyBindings(); @@ -274,6 +275,10 @@ void CSettings::LoadSettings() if (GetConfigFile().GetBoolProperty("Experimental", "TerrainShadows", bValue)) engine->SetTerrainShadows(bValue); + if (GetConfigFile().GetIntProperty("Experimental", "VSync", iValue)) + { + engine->SetVSync(iValue); + } CInput::GetInstancePointer()->LoadKeyBindings(); diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 40d4d1d1..2641992d 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -197,6 +197,7 @@ CEngine::CEngine(CApplication *app, CSystemUtils* systemUtils) m_terrainShadows = false; m_shadowRange = 0.0f; m_multisample = 2; + m_vsync = 0; m_backForce = true; m_lightMode = true; @@ -323,6 +324,7 @@ bool CEngine::Create() SetShadowMappingOffscreen(m_offscreenShadowRendering); SetShadowMappingOffscreenResolution(m_offscreenShadowRenderingResolution); SetMultiSample(m_multisample); + SetVSync(m_vsync); m_modelManager = MakeUnique(this); m_pyroManager = MakeUnique(); @@ -3023,6 +3025,19 @@ bool CEngine::GetTerrainShadows() return m_terrainShadows; } +void CEngine::SetVSync(int value) +{ + if (value < -1) value = -1; + if (value > 1) value = 1; + if(m_vsync == value) return; + m_vsync = value; +} + +int CEngine::GetVSync() +{ + return m_vsync; +} + void CEngine::SetBackForce(bool present) { m_backForce = present; diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 794bd9e8..88a35dda 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -1072,6 +1072,13 @@ public: bool GetTerrainShadows(); //@} + //@{ + //! Management of vertical synchronization + // NOTE: This is an user configuration setting + void SetVSync(int value); + int GetVSync(); + //@} + //@{ //! Management of shadow color // NOTE: This is a setting configurable only in INI file @@ -1336,6 +1343,9 @@ protected: //! Texture bias for sampling shadow maps Math::Matrix m_shadowBias; + //! Vertical synchronization controll + int m_vsync; + //! World matrix for 2D interface Math::Matrix m_matWorldInterface; //! Projection matrix for 2D interface diff --git a/src/ui/screen/screen_setup_display.cpp b/src/ui/screen/screen_setup_display.cpp index bf31baa6..15f2511f 100644 --- a/src/ui/screen/screen_setup_display.cpp +++ b/src/ui/screen/screen_setup_display.cpp @@ -101,6 +101,36 @@ void CScreenSetupDisplay::CreateInterface() pc->SetState(STATE_SHADOW); pc->SetState(STATE_CHECK, m_setupFull); + pos.x = ox+sx*10; + pos.y = oy+sy*9; + ddim.x = dim.x*6; + ddim.y = dim.y*1; + GetResource(RES_EVENT, EVENT_INTERFACE_VSYNC, name); + pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name); + pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT); + + pos.x = ox+sx*10; + pos.y = oy+sy*7.97f; + ddim.x = dim.x*6; + ddim.y = dim.y*1.8f; + pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_VSYNC); + pli->SetState(STATE_SHADOW); + pli->SetItemName(0, "Off"); + pli->SetItemName(1, "Adaptive"); + pli->SetItemName(2, "On"); + switch(m_engine->GetVSync()) + { + case -1: //Adaptive? + pli->SetSelect(1); + break; + case 0: //Off? + pli->SetSelect(0); + break; + case 1: //On? + pli->SetSelect(2); + break; + } + ddim.x = dim.x*6; ddim.y = dim.y*1; pos.x = ox+sx*10; @@ -117,6 +147,7 @@ bool CScreenSetupDisplay::EventProcess(const Event &event) CWindow* pw; CCheck* pc; CButton* pb; + CList* pl; switch( event.type ) { @@ -153,6 +184,27 @@ bool CScreenSetupDisplay::EventProcess(const Event &event) UpdateApply(); break; + case EVENT_INTERFACE_VSYNC: + pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); + if ( pw == nullptr ) break; + pl = static_cast(pw->SearchControl(EVENT_INTERFACE_VSYNC)); + if (pl == nullptr ) break; + switch(pl->GetSelect()) + { + case 0: //Off? + m_engine->SetVSync(0); + break; + case 1: //Adaptive? + m_engine->SetVSync(-1); + break; + case 2: //On? + m_engine->SetVSync(1); + break; + } + ChangeDisplay(); + UpdateApply(); + break; + default: return true; } From 608d59f07b815da29132c44c05456e5b2892f12b Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Thu, 5 Jul 2018 20:56:38 +0200 Subject: [PATCH 050/109] Moved VSync setting from Experimental to Setup --- src/app/app.cpp | 4 ++-- src/common/settings.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 9ec5f17e..f7c0b529 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -815,14 +815,14 @@ bool CApplication::CreateVideoSurface() m_private->glcontext = SDL_GL_CreateContext(m_private->window); int vsync = 0; - if (GetConfigFile().GetIntProperty("Experimental", "VSync", vsync)) + if (GetConfigFile().GetIntProperty("Setup", "VSync", vsync)) { if (SDL_GL_SetSwapInterval(vsync) == -1) { GetLogger()->Warn("Adaptive sync not supported.\n"); vsync = 1; SDL_GL_SetSwapInterval(vsync); - GetConfigFile().SetIntProperty("Experimental", "VSync", vsync); + GetConfigFile().SetIntProperty("Setup", "VSync", vsync); } GetLogger()->Info("Using Vsync: %s\n", (vsync == -1 ? "adaptive" : (vsync ? "true" : "false"))); diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 1094d9eb..488666d2 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -112,7 +112,7 @@ void CSettings::SaveSettings() // Experimental settings GetConfigFile().SetBoolProperty("Experimental", "TerrainShadows", engine->GetTerrainShadows()); - GetConfigFile().SetIntProperty("Experimental", "VSync", engine->GetVSync()); + GetConfigFile().SetIntProperty("Setup", "VSync", engine->GetVSync()); CInput::GetInstancePointer()->SaveKeyBindings(); @@ -275,7 +275,7 @@ void CSettings::LoadSettings() if (GetConfigFile().GetBoolProperty("Experimental", "TerrainShadows", bValue)) engine->SetTerrainShadows(bValue); - if (GetConfigFile().GetIntProperty("Experimental", "VSync", iValue)) + if (GetConfigFile().GetIntProperty("Setup", "VSync", iValue)) { engine->SetVSync(iValue); } From 4bfada2ad6c982047da4bdc03fe239b8a2b90f0c Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Thu, 5 Jul 2018 21:18:14 +0200 Subject: [PATCH 051/109] Better handling of VSync errors --- src/app/app.cpp | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index f7c0b529..aabae7eb 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -817,13 +817,25 @@ bool CApplication::CreateVideoSurface() int vsync = 0; if (GetConfigFile().GetIntProperty("Setup", "VSync", vsync)) { - if (SDL_GL_SetSwapInterval(vsync) == -1) + while (SDL_GL_SetSwapInterval(vsync) == -1) { - GetLogger()->Warn("Adaptive sync not supported.\n"); - vsync = 1; - SDL_GL_SetSwapInterval(vsync); - GetConfigFile().SetIntProperty("Setup", "VSync", vsync); + switch(vsync) + { + case -1: //failed with adaptive sync? + GetLogger()->Warn("Adaptive sync not supported.\n"); + vsync = 1; + break; + case 1: //failed with VSync enabled? + GetLogger()->Warn("Couldn't enable VSync.\n"); + vsync = 0; + break; + case 0: //failed with VSync disabled? + GetLogger()->Warn("Couldn't disable VSync.\n"); + vsync = 1; + break; + } } + GetConfigFile().SetIntProperty("Setup", "VSync", vsync); GetLogger()->Info("Using Vsync: %s\n", (vsync == -1 ? "adaptive" : (vsync ? "true" : "false"))); } @@ -838,12 +850,27 @@ bool CApplication::ChangeVideoConfig(const Gfx::DeviceConfig &newConfig) // TODO: Somehow this doesn't work for maximized windows (at least on Ubuntu) SDL_SetWindowSize(m_private->window, m_deviceConfig.size.x, m_deviceConfig.size.y); SDL_SetWindowFullscreen(m_private->window, m_deviceConfig.fullScreen ? SDL_WINDOW_FULLSCREEN : 0); - if( SDL_GL_SetSwapInterval(m_engine->GetVSync()) == -1 ) + + int vsync = m_engine->GetVSync(); + while (SDL_GL_SetSwapInterval(vsync) == -1) { - GetLogger()->Warn("Adaptive sync not supported.\n"); - m_engine->SetVSync(1); - SDL_GL_SetSwapInterval(1); + switch(vsync) + { + case -1: //failed with adaptive sync? + GetLogger()->Warn("Adaptive sync not supported.\n"); + vsync = 1; + break; + case 1: //failed with VSync enabled? + GetLogger()->Warn("Couldn't enable VSync.\n"); + vsync = 0; + break; + case 0: //failed with VSync disabled? + GetLogger()->Warn("Couldn't disable VSync.\n"); + vsync = 1; + break; + } } + m_engine->SetVSync(vsync); m_device->ConfigChanged(m_deviceConfig); From fb00898035e024e0cd49c778a6816dd721f9acde Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Sat, 21 Jul 2018 00:09:37 +0200 Subject: [PATCH 052/109] Fix switch case documentation shortcut Also some polishing of loops help texts --- src/script/cbottoken.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/script/cbottoken.cpp b/src/script/cbottoken.cpp index 06b6ea14..24b60a09 100644 --- a/src/script/cbottoken.cpp +++ b/src/script/cbottoken.cpp @@ -372,6 +372,9 @@ std::string GetHelpFilename(const char *token) if ( strcmp(token, "synchronized" ) == 0 ) helpfile = "cbot/synchro"; if ( strcmp(token, "new" ) == 0 ) helpfile = "cbot/new"; if ( strcmp(token, "this" ) == 0 ) helpfile = "cbot/this"; + if ( strcmp(token, "switch" ) == 0 || + strcmp(token, "case" ) == 0 || + strcmp(token, "default" ) == 0 ) helpfile = "cbot/switch"; if (helpfile.empty()) return ""; @@ -491,11 +494,14 @@ bool IsFunction(const char *token) const char* GetHelpText(const char *token) { - if ( strcmp(token, "if" ) == 0 ) return "if ( condition ) { bloc }"; - if ( strcmp(token, "else" ) == 0 ) return "else { bloc }"; + if ( strcmp(token, "if" ) == 0 ) return "if ( condition ) { code }"; + if ( strcmp(token, "else" ) == 0 ) return "else { code }"; if ( strcmp(token, "for" ) == 0 ) return "for ( before ; condition ; end )"; - if ( strcmp(token, "while" ) == 0 ) return "while ( condition ) { bloc }"; - if ( strcmp(token, "do" ) == 0 ) return "do { bloc } while ( condition );"; + if ( strcmp(token, "while" ) == 0 ) return "while ( condition ) { code }"; + if ( strcmp(token, "do" ) == 0 ) return "do { code } while ( condition );"; + if ( strcmp(token, "switch" ) == 0 ) return "switch ( value ) { code }"; + if ( strcmp(token, "case" ) == 0 ) return "case label: { code }"; + if ( strcmp(token, "default" ) == 0 ) return "default: { code } "; if ( strcmp(token, "break" ) == 0 ) return "break;"; if ( strcmp(token, "continue" ) == 0 ) return "continue;"; if ( strcmp(token, "return" ) == 0 ) return "return;"; From 14b6f7cafaeeaedbdd63ea64a25255626ca4eadd Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Mon, 23 Jul 2018 12:46:47 +0200 Subject: [PATCH 053/109] Fixed some linter warnings in font_config files --- src/common/font_config.cpp | 19 +++++++++---------- src/common/font_config.h | 18 ++++++++---------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/common/font_config.cpp b/src/common/font_config.cpp index e021ec0b..a7a306b6 100644 --- a/src/common/font_config.cpp +++ b/src/common/font_config.cpp @@ -1,6 +1,6 @@ /* * This file is part of the Colobot: Gold Edition source code - * Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam + * Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam * http://epsitec.ch; http://colobot.info; http://github.com/colobot * * This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see http://gnu.org/licenses */ - + #include "common/font_config.h" #include "common/logger.h" @@ -38,7 +38,7 @@ namespace bp = boost::property_tree; -const std::map defaultFont = +const std::map DEFAULT_FONT = { { Gfx::FONT_COMMON, "dvu_sans.ttf" }, { Gfx::FONT_COMMON_BOLD, "dvu_sans_bold.ttf" }, @@ -51,7 +51,7 @@ const std::map defaultFont = { Gfx::FONT_SATCOM_ITALIC, "dvu_sans_italic.ttf" }, }; -const std::map fontType = +const std::map FONT_TYPE = { { Gfx::FONT_COMMON, "FontCommon" }, { Gfx::FONT_COMMON_BOLD, "FontCommonBold" }, @@ -77,11 +77,10 @@ bool CFontConfig::Init() try { std::unique_ptr stream; - bool good; auto inputStream = MakeUnique("/fonts/fonts.ini"); - good = inputStream->is_open(); + bool good = inputStream->is_open(); stream = std::move(inputStream); - + if (good) { bp::ini_parser::read_ini(*stream, m_propertyTree); @@ -107,10 +106,10 @@ std::string CFontConfig::GetFont(Gfx::FontType type) std::string CFontConfig::GetDefaultFont(Gfx::FontType type) const { - return defaultFont.at(type); + return DEFAULT_FONT.at(type); } std::string CFontConfig::GetFontType(Gfx::FontType type) const { - return fontType.at(type); -} \ No newline at end of file + return FONT_TYPE.at(type); +} diff --git a/src/common/font_config.h b/src/common/font_config.h index 96d9efe3..c475ebc5 100644 --- a/src/common/font_config.h +++ b/src/common/font_config.h @@ -1,6 +1,6 @@ /* * This file is part of the Colobot: Gold Edition source code - * Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam + * Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam * http://epsitec.ch; http://colobot.info; http://github.com/colobot * * This program is free software: you can redistribute it and/or modify @@ -16,12 +16,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see http://gnu.org/licenses */ - + /** * \file common/font_config.h * \brief Class for loading fonts from /data/fonts/fonts.ini */ - + #pragma once #include "common/singleton.h" @@ -39,14 +39,12 @@ * */ - - class CFontConfig { public: CFontConfig(); virtual ~CFontConfig(); - + /** Loads fonts.ini * \return return true on success */ @@ -56,19 +54,19 @@ public: * \return return path to font file */ std::string GetFont(Gfx::FontType type); - + /** Const type method to read filenames of fonts from defaultFont map * used as a fallback if it wasn't possible to read font from fonts.ini * \return return filename of default path */ std::string GetDefaultFont(Gfx::FontType type) const; - + /** Const type method converting Gfx::FontType to string * \return return id of font used in fonts.ini file */ - + std::string GetFontType(Gfx::FontType type) const; - + private: boost::property_tree::ptree m_propertyTree; }; From df46bcfe2df91fcf998a1be63bd4f20e4133394d Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Mon, 23 Jul 2018 14:03:59 +0200 Subject: [PATCH 054/109] Fix another linter warning --- src/graphics/engine/text.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 5638c61b..35166fe7 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -127,14 +127,14 @@ bool CText::Create() m_error = std::string("TTF_Init error: ") + std::string(TTF_GetError()); return false; } - + for (auto type : {FONT_COMMON, FONT_STUDIO, FONT_SATCOM}) { m_fonts[static_cast(type)] = MakeUnique(fontConfig.GetFont(type)); m_fonts[static_cast(type|FONT_BOLD)] = MakeUnique(fontConfig.GetFont(static_cast(type|FONT_BOLD))); m_fonts[static_cast(type|FONT_ITALIC)] = MakeUnique(fontConfig.GetFont(static_cast(type|FONT_ITALIC))); } - + for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it) { FontType type = (*it).first; From d84be03a830131aeaefa50d30dbaa7974d89096f Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Mon, 23 Jul 2018 14:10:27 +0200 Subject: [PATCH 055/109] Removed non-existing font from code Forgot to check build on clean data directory --- src/common/font_config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/font_config.cpp b/src/common/font_config.cpp index a7a306b6..078cb34a 100644 --- a/src/common/font_config.cpp +++ b/src/common/font_config.cpp @@ -45,7 +45,7 @@ const std::map DEFAULT_FONT = { Gfx::FONT_COMMON_ITALIC, "dvu_sans_italic.ttf" }, { Gfx::FONT_STUDIO, "dvu_sans_mono.ttf" }, { Gfx::FONT_STUDIO_BOLD, "dvu_sans_mono_bold.ttf" }, - { Gfx::FONT_STUDIO_ITALIC, "dvu_sans_mono_italic.ttf" }, + { Gfx::FONT_STUDIO_ITALIC, "dvu_sans_mono.ttf" }, //placeholder for future use, DejaVu Sans Mono doesn't have italic variant { Gfx::FONT_SATCOM, "dvu_sans.ttf" }, { Gfx::FONT_SATCOM_BOLD, "dvu_sans_bold.ttf" }, { Gfx::FONT_SATCOM_ITALIC, "dvu_sans_italic.ttf" }, From 3383532752efb716c38ffb72a3b89712c817e388 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Wed, 25 Jul 2018 00:44:06 +0200 Subject: [PATCH 056/109] Changed font_config to font_loader Apparently linter doesn't like files with `config` in its name --- src/CMakeLists.txt | 4 ++-- src/common/{font_config.cpp => font_loader.cpp} | 14 +++++++------- src/common/{font_config.h => font_loader.h} | 10 +++++----- src/graphics/engine/text.cpp | 12 ++++++------ 4 files changed, 20 insertions(+), 20 deletions(-) rename src/common/{font_config.cpp => font_loader.cpp} (91%) rename src/common/{font_config.h => font_loader.h} (94%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 37d6cb04..60ba3232 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -106,8 +106,8 @@ set(BASE_SOURCES common/error.h common/event.cpp common/event.h - common/font_config.h - common/font_config.cpp + common/font_loader.h + common/font_loader.cpp common/global.h common/image.cpp common/image.h diff --git a/src/common/font_config.cpp b/src/common/font_loader.cpp similarity index 91% rename from src/common/font_config.cpp rename to src/common/font_loader.cpp index 078cb34a..79b9375c 100644 --- a/src/common/font_config.cpp +++ b/src/common/font_loader.cpp @@ -17,7 +17,7 @@ * along with this program. If not, see http://gnu.org/licenses */ -#include "common/font_config.h" +#include "common/font_loader.h" #include "common/logger.h" #include "common/make_unique.h" @@ -64,15 +64,15 @@ const std::map FONT_TYPE = { Gfx::FONT_SATCOM_ITALIC, "FontSatComItalic" }, }; -CFontConfig::CFontConfig() +CFontLoader::CFontLoader() { } -CFontConfig::~CFontConfig() +CFontLoader::~CFontLoader() { } -bool CFontConfig::Init() +bool CFontLoader::Init() { try { @@ -99,17 +99,17 @@ bool CFontConfig::Init() return true; } -std::string CFontConfig::GetFont(Gfx::FontType type) +std::string CFontLoader::GetFont(Gfx::FontType type) { return std::string("/fonts/") + m_propertyTree.get(GetFontType(type), GetDefaultFont(type)); } -std::string CFontConfig::GetDefaultFont(Gfx::FontType type) const +std::string CFontLoader::GetDefaultFont(Gfx::FontType type) const { return DEFAULT_FONT.at(type); } -std::string CFontConfig::GetFontType(Gfx::FontType type) const +std::string CFontLoader::GetFontType(Gfx::FontType type) const { return FONT_TYPE.at(type); } diff --git a/src/common/font_config.h b/src/common/font_loader.h similarity index 94% rename from src/common/font_config.h rename to src/common/font_loader.h index c475ebc5..a68fc0ad 100644 --- a/src/common/font_config.h +++ b/src/common/font_loader.h @@ -18,7 +18,7 @@ */ /** - * \file common/font_config.h + * \file common/font_loader.h * \brief Class for loading fonts from /data/fonts/fonts.ini */ @@ -33,17 +33,17 @@ #include /** -* \class CFontConfig +* \class CFontLoader * * \brief Class for loading config file * */ -class CFontConfig +class CFontLoader { public: - CFontConfig(); - virtual ~CFontConfig(); + CFontLoader(); + virtual ~CFontLoader(); /** Loads fonts.ini * \return return true on success diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 35166fe7..e9b60934 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -22,7 +22,7 @@ #include "app/app.h" -#include "common/font_config.h" +#include "common/font_loader.h" #include "common/image.h" #include "common/logger.h" #include "common/stringutils.h" @@ -117,8 +117,8 @@ CText::~CText() bool CText::Create() { - CFontConfig fontConfig; - if (!fontConfig.Init()) + CFontLoader fontLoader; + if (!fontLoader.Init()) { GetLogger()->Warn("Error on parsing fonts config file: failed to open file\n"); } @@ -130,9 +130,9 @@ bool CText::Create() for (auto type : {FONT_COMMON, FONT_STUDIO, FONT_SATCOM}) { - m_fonts[static_cast(type)] = MakeUnique(fontConfig.GetFont(type)); - m_fonts[static_cast(type|FONT_BOLD)] = MakeUnique(fontConfig.GetFont(static_cast(type|FONT_BOLD))); - m_fonts[static_cast(type|FONT_ITALIC)] = MakeUnique(fontConfig.GetFont(static_cast(type|FONT_ITALIC))); + m_fonts[static_cast(type)] = MakeUnique(fontLoader.GetFont(type)); + m_fonts[static_cast(type|FONT_BOLD)] = MakeUnique(fontLoader.GetFont(static_cast(type|FONT_BOLD))); + m_fonts[static_cast(type|FONT_ITALIC)] = MakeUnique(fontLoader.GetFont(static_cast(type|FONT_ITALIC))); } for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it) From f93fd61c26667c147f76ddfda87c6c2976f9f8c2 Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Wed, 25 Jul 2018 21:34:39 +0200 Subject: [PATCH 057/109] Rename OFFICIAL_BUILD to OFFICIAL_COLOBOT_BUILD In order to avoid conflict with OFFICIAL_BUILD variable inside ntverp.h. It caused compilation error "invalid integer expression" https://github.com/tpn/winsdk-10/blob/master/Include/10.0.10240.0/shared/ntverp.h#L134 --- CMakeLists.txt | 2 +- src/app/signal_handlers.cpp | 2 +- src/common/version.h.cmake | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 44a63de6..8881e0e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -204,7 +204,7 @@ option(DEV_BUILD "Enable development build (enables some debugging tools, local # Official build - changes text on the crash screen # PLEASE DO NOT USE ON UNOFFICIAL BUILDS. Thanks. -option(OFFICIAL_BUILD "Official build (changes crash screen text)" OFF) +option(OFFICIAL_COLOBOT_BUILD "Official build (changes crash screen text)" OFF) # Portable build - load all data from current directory option(PORTABLE "Portable build" OFF) diff --git a/src/app/signal_handlers.cpp b/src/app/signal_handlers.cpp index 1974ba3f..03771dab 100644 --- a/src/app/signal_handlers.cpp +++ b/src/app/signal_handlers.cpp @@ -133,7 +133,7 @@ void CSignalHandlers::ReportError(const std::string& errorMessage) msg << "including information on what you were doing before this happened and all the information below." << std::endl; msg << "==============================" << std::endl; #if BUILD_NUMBER == 0 - #ifdef OFFICIAL_BUILD + #ifdef OFFICIAL_COLOBOT_BUILD msg << "You are running official " << COLOBOT_VERSION_DISPLAY << " build." << std::endl; #else // COLOBOT_VERSION_DISPLAY doesn't update if you don't run CMake after "git pull" diff --git a/src/common/version.h.cmake b/src/common/version.h.cmake index ad3714b3..ca377e4f 100644 --- a/src/common/version.h.cmake +++ b/src/common/version.h.cmake @@ -4,4 +4,4 @@ #define COLOBOT_VERSION_DISPLAY "@COLOBOT_VERSION_DISPLAY@" #define BUILD_NUMBER @BUILD_NUMBER@ -#cmakedefine OFFICIAL_BUILD +#cmakedefine OFFICIAL_COLOBOT_BUILD From 32d3d1eb924cc89b3cfdd1a729a04e0be96af296 Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Wed, 25 Jul 2018 21:38:47 +0200 Subject: [PATCH 058/109] Change key for debug menu to F10 and for stats to F11 F12 is used by Visual Studio debugger to trigger a breakpoint and apparently it cannot be changed: "The F12 key is reserved for use by the debugger at all times, so it should not be registered as a hot key. Even when you are not debugging an application, F12 is reserved in case a kernel-mode debugger or a just-in-time debugger is resident." Source: https://msdn.microsoft.com/en-us/library/windows/desktop/ms646309.aspx?f=255&MSPPError=-2147217396 --- src/graphics/engine/engine.cpp | 2 +- src/level/robotmain.cpp | 2 +- src/ui/debug_menu.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 4dfec9ca..8cb595eb 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -431,7 +431,7 @@ bool CEngine::ProcessEvent(const Event &event) { auto data = event.GetData(); - if (data->key == KEY(F12)) + if (data->key == KEY(F11)) { m_showStats = !m_showStats; return false; diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 2cabcccf..e2608007 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -779,7 +779,7 @@ bool CRobotMain::ProcessEvent(Event &event) if (IsPhaseWithWorld(m_phase)) { - if (data->key == KEY(F11)) + if (data->key == KEY(F10)) { m_debugMenu->ToggleInterface(); return false; diff --git a/src/ui/debug_menu.h b/src/ui/debug_menu.h index e3ee0933..ecc6f81e 100644 --- a/src/ui/debug_menu.h +++ b/src/ui/debug_menu.h @@ -39,7 +39,7 @@ class CInterface; /** * \class CDebugMenu - * \brief Handles debug menu (F11) + * \brief Handles debug menu (F10) * * There should always be only one instance of this class for each associated CRobotMain class. */ From cb701cacb8f1cf0f0d52c0e778474588e7e88703 Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Wed, 25 Jul 2018 21:44:31 +0200 Subject: [PATCH 059/109] Add a workaround for failed assertion in VS debugger Assertion failed: ploc->_Mbcurmax == 1 || ploc->_Mbcurmax == 2 Apparently MS C/C++ library doesn't support UTF-8 locales, which causes the assertion to fail. My solution is to ignore the system locale and try to set the classic one. LibreOffice seems to have this problem fixed in less simple way: https://gerrit.libreoffice.org/#/c/54110/ --- src/app/app.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/app/app.cpp b/src/app/app.cpp index 3444481c..58a58da4 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -1832,7 +1832,12 @@ void CApplication::SetLanguage(Language language) // Update C++ locale try { +#if defined(_MSC_VER) && defined(_DEBUG) + // Avoids failed assertion in VS debugger + throw -1; +#else std::locale::global(std::locale(systemLocale.c_str())); +#endif } catch (...) { From 7e19622b85dbad63bc5b0ceb53a2b22db65a574b Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Wed, 25 Jul 2018 23:45:15 +0200 Subject: [PATCH 060/109] Allow both F11 and F12 for stats --- src/graphics/engine/engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 8cb595eb..bc17087e 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -431,7 +431,7 @@ bool CEngine::ProcessEvent(const Event &event) { auto data = event.GetData(); - if (data->key == KEY(F11)) + if (data->key == KEY(F11) || data->key == KEY(F12)) { m_showStats = !m_showStats; return false; From f3b30625eec3dcef259ba69b557f3878b012c5e7 Mon Sep 17 00:00:00 2001 From: Jerzy B Date: Sun, 12 Aug 2018 06:49:45 +0100 Subject: [PATCH 061/109] Fix GCC 8 warning about sprintf overflow (#1192) --- src/ui/screen/screen_io.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ui/screen/screen_io.cpp b/src/ui/screen/screen_io.cpp index 06db0339..d3df8fdb 100644 --- a/src/ui/screen/screen_io.cpp +++ b/src/ui/screen/screen_io.cpp @@ -58,7 +58,7 @@ void CScreenIO::IOReadName() CEdit* pe; std::string resume; char line[100]; - char name[100]; + std::string name; time_t now; pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); @@ -81,10 +81,10 @@ void CScreenIO::IOReadName() time(&now); strftime(line, 99, "%y.%m.%d %H:%M", localtime(&now)); - sprintf(name, "%s - %s %d", line, resume.c_str(), m_main->GetLevelRank()); + name = StrUtils::Format("%s - %s %d", line, resume.c_str(), m_main->GetLevelRank()); pe->SetText(name); - pe->SetCursor(strlen(name), 0); + pe->SetCursor(name.length(), 0); m_interface->SetFocus(pe); } From 6f0a294048b017cf92011a6c4933d9418174f216 Mon Sep 17 00:00:00 2001 From: Jerzy B Date: Sat, 18 Aug 2018 09:11:46 +0100 Subject: [PATCH 062/109] Give space for a null character in texture name --- src/graphics/model/model_io_structs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/graphics/model/model_io_structs.h b/src/graphics/model/model_io_structs.h index 36f4f7f1..5646bafd 100644 --- a/src/graphics/model/model_io_structs.h +++ b/src/graphics/model/model_io_structs.h @@ -188,7 +188,7 @@ struct OldModelTriangleV1 Vertex p2; Vertex p3; Material material; - char texName[20] = {}; + char texName[21] = {'\0'}; float min = 0; float max = 0; }; @@ -207,7 +207,7 @@ struct OldModelTriangleV2 Vertex p2; Vertex p3; Material material; - char texName[20] = {}; + char texName[21] = {'\0'}; float min = 0.0f; float max = 0.0f; long state = 0; @@ -231,7 +231,7 @@ struct OldModelTriangleV3 VertexTex2 p2; VertexTex2 p3; Material material; - char texName[20] = {}; + char texName[21] = {'\0'}; float min = 0.0f; float max = 0.0f; long state = 0; From 47ff15502293e76e698b70884e977eb11d062d47 Mon Sep 17 00:00:00 2001 From: Martin Doucha Date: Mon, 20 Aug 2018 23:05:19 +0200 Subject: [PATCH 063/109] Minor improvements in Czech translation --- po/cs.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/po/cs.po b/po/cs.po index 555df720..9f0f49c4 100644 --- a/po/cs.po +++ b/po/cs.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: 0.1.11\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: DATE\n" -"PO-Revision-Date: 2018-02-24 20:39+01\n" +"PO-Revision-Date: 2018-08-20 22:48+02\n" "Last-Translator: next_ghost \n" "Language-Team: Czech \n" "Language: Czech\n" @@ -1193,7 +1193,7 @@ msgid "Programming help\\Gives more detailed help with programming" msgstr "Nápověda\\Zobrazí nápovědu pro psaní programů" msgid "Programs dispatched by Houston" -msgstr "Program poslaný z Houstonu" +msgstr "Programy poslané z Houstonu" msgid "Public required" msgstr "Tato definice musí být veřejná (public)" @@ -1548,7 +1548,7 @@ msgstr "Buchar" #, c-format msgid "Time: %s" -msgstr "" +msgstr "Čas: %s" msgid "Titanium" msgstr "Titan" @@ -1741,7 +1741,7 @@ msgid "You cannot use \"%s\" in this exercise (used: %d)" msgstr "V tomto cvičení nesmíte použít \"%s\" (použito: %dx)" msgid "You found a usable object" -msgstr "Našli jste fungující objekt" +msgstr "Našli jste použitelný objekt" #, c-format msgid "You have to use \"%1$s\" at least once in this exercise (used: %2$d)" From ee0b46a2784020cc34116c888015717f50038747 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Tue, 21 Aug 2018 21:28:45 +0200 Subject: [PATCH 064/109] Add a note mentioned in issue #1197 --- src/common/restext.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/restext.cpp b/src/common/restext.cpp index c8602329..4aa21564 100644 --- a/src/common/restext.cpp +++ b/src/common/restext.cpp @@ -48,6 +48,9 @@ const char* stringsCbot[CBot::CBotErrMAX] = { nullptr }; */ #define TR(x) x +/* Please run `make update-pot` after changing this file + * in order to update translation files. Thank you. + */ void InitializeRestext() { From b37cf36a52de5a3c0fde0b3902eafe6f5fbf6f90 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Tue, 21 Aug 2018 21:35:37 +0200 Subject: [PATCH 065/109] Updated pot files Just figured out I didn't updated them before --- po/colobot.pot | 3 +++ po/cs.po | 3 +++ po/de.po | 3 +++ po/fr.po | 3 +++ po/pl.po | 3 +++ po/ru.po | 3 +++ 6 files changed, 18 insertions(+) diff --git a/po/colobot.pot b/po/colobot.pot index 5d71af8c..b91aba04 100644 --- a/po/colobot.pot +++ b/po/colobot.pot @@ -451,6 +451,9 @@ msgstr "" msgid "Shadow resolution\\Higher means better range and quality, but slower" msgstr "" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + msgid "Standard controls\\Standard key functions" msgstr "" diff --git a/po/cs.po b/po/cs.po index 555df720..133e0b95 100644 --- a/po/cs.po +++ b/po/cs.po @@ -1664,6 +1664,9 @@ msgstr "Proměnná nebyla nastavena" msgid "Vault" msgstr "Trezor" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + msgid "Violet flag" msgstr "Fialová vlajka" diff --git a/po/de.po b/po/de.po index 553ead83..66d9918a 100644 --- a/po/de.po +++ b/po/de.po @@ -1681,6 +1681,9 @@ msgstr "Der Wert dieser Variable wurde nicht definiert" msgid "Vault" msgstr "Bunker" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + msgid "Violet flag" msgstr "Violette Fahne" diff --git a/po/fr.po b/po/fr.po index ce3f5fdf..8e2880b0 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1684,6 +1684,9 @@ msgstr "Variable non initialisée" msgid "Vault" msgstr "Coffre-fort" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + msgid "Violet flag" msgstr "Drapeau violet" diff --git a/po/pl.po b/po/pl.po index f9f76de8..073c7b58 100644 --- a/po/pl.po +++ b/po/pl.po @@ -1663,6 +1663,9 @@ msgstr "Zmienna nie została zainicjalizowana" msgid "Vault" msgstr "Skrytka" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "Synchronizacja pionowa\\Ogranicza ilość klatek na sekundę do wartości odświeżania ekranu" + msgid "Violet flag" msgstr "Fioletowa flaga" diff --git a/po/ru.po b/po/ru.po index 0763e742..ca44c0c5 100644 --- a/po/ru.po +++ b/po/ru.po @@ -1694,6 +1694,9 @@ msgstr "Переменная не инициализирована" msgid "Vault" msgstr "Хранилище" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + msgid "Violet flag" msgstr "Фиолетовый флаг" From 2871bac0ceb3aec549ae3d2839f5b1b3db2af61c Mon Sep 17 00:00:00 2001 From: Alexander Olofsson Date: Thu, 4 Oct 2018 00:43:09 +0200 Subject: [PATCH 066/109] Add an appdata XML for Linux packaging Fixes #1204 --- desktop/CMakeLists.txt | 6 ++++ desktop/info.colobot.Colobot.appdata.xml | 37 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 desktop/info.colobot.Colobot.appdata.xml diff --git a/desktop/CMakeLists.txt b/desktop/CMakeLists.txt index b49ef2d3..5a4b04cc 100644 --- a/desktop/CMakeLists.txt +++ b/desktop/CMakeLists.txt @@ -70,6 +70,12 @@ if(PLATFORM_GNU) DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications/ ) + # Install appdata + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/info.colobot.Colobot.appdata.xml + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo/ + ) + # Install Icon install( FILES ${COLOBOT_ICON_FILE} diff --git a/desktop/info.colobot.Colobot.appdata.xml b/desktop/info.colobot.Colobot.appdata.xml new file mode 100644 index 00000000..9510e512 --- /dev/null +++ b/desktop/info.colobot.Colobot.appdata.xml @@ -0,0 +1,37 @@ + + + info.colobot.Colobot + CC0-1.0 + GPL-3.0 + TerranovaTeam + contact@colobot.info + Colobot + Colonize with bots + + +

Colobot (Colonize with Bots) is an educational game aiming to teach programming through entertainment. You are playing as an astronaut on a journey with robot helpers to find a planet for colonization. It features 3D real-time graphics and a C++ and Java-like, object-oriented language, CBOT, which can be used to program the robots available in the game.

+
+ + colobot.desktop + + + + Alpha 0.1.5 + https://colobot.info/wordpress/wp-content/uploads/alpha-0.1.5.png + + + + https://colobot.info/ + http://colobot.info/forum/ + https://github.com/colobot/colobot/issues + + + moderate + moderate + mild + + + + + +
From 0dbf82ca4e9a847b63594070d5cfa278372767ae Mon Sep 17 00:00:00 2001 From: Alexander Olofsson Date: Thu, 4 Oct 2018 01:07:20 +0200 Subject: [PATCH 067/109] Add the donation link to the appdata XML as well --- desktop/info.colobot.Colobot.appdata.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/desktop/info.colobot.Colobot.appdata.xml b/desktop/info.colobot.Colobot.appdata.xml index 9510e512..8a2a75d6 100644 --- a/desktop/info.colobot.Colobot.appdata.xml +++ b/desktop/info.colobot.Colobot.appdata.xml @@ -22,8 +22,9 @@ https://colobot.info/ - http://colobot.info/forum/ https://github.com/colobot/colobot/issues + http://colobot.info/forum/ + https://colobot.info/donate/ moderate From abf1a60a86d2ff931837372167764d030236b830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Cie=C5=9Bla?= Date: Wed, 10 Oct 2018 19:14:23 +0200 Subject: [PATCH 068/109] Fix for #1203 --- src/object/old_object.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 3acf608a..3ecbb0e8 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -284,13 +284,19 @@ void COldObject::DeleteObject(bool bAll) if (m_power != nullptr) { if (m_power->Implements(ObjectInterfaceType::Old)) + { + dynamic_cast(m_power)->SetTransporter(nullptr); dynamic_cast(m_power)->DeleteObject(bAll); + } m_power = nullptr; } if (m_cargo != nullptr) { if (m_cargo->Implements(ObjectInterfaceType::Old)) + { + dynamic_cast(m_cargo)->SetTransporter(nullptr); dynamic_cast(m_cargo)->DeleteObject(bAll); + } m_cargo = nullptr; } } From 7c88a6e66758cd3d7b1682853c4696935f5877cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Cie=C5=9Bla?= Date: Sat, 13 Oct 2018 10:12:41 +0200 Subject: [PATCH 069/109] Fix for #1194 --- src/graphics/engine/engine.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 5a056b7d..24c68098 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -4048,7 +4048,9 @@ void CEngine::UseMSAA(bool enable) } } - framebuffer->Bind(); + if (framebuffer != nullptr) { + framebuffer->Bind(); + } m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, true); m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, true); From 634d087d5e4c4c22662bf9c65e414c66439e0ab2 Mon Sep 17 00:00:00 2001 From: "Alexander \"Ananace\" Olofsson" Date: Mon, 29 Oct 2018 18:32:34 +0100 Subject: [PATCH 070/109] Don't grab the AppData XML from binary dir Only supposed to grab from there when generating the file from CMake variables. --- desktop/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/CMakeLists.txt b/desktop/CMakeLists.txt index 5a4b04cc..af704932 100644 --- a/desktop/CMakeLists.txt +++ b/desktop/CMakeLists.txt @@ -72,7 +72,7 @@ if(PLATFORM_GNU) # Install appdata install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/info.colobot.Colobot.appdata.xml + FILES info.colobot.Colobot.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo/ ) From 4305f8de03f2cd9564c8ab658e7d1fdb67326c82 Mon Sep 17 00:00:00 2001 From: suve Date: Sun, 18 Nov 2018 21:09:11 +0100 Subject: [PATCH 071/109] Add a minimum & maximum game speed limit --- src/level/robotmain.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 2cabcccf..40b74a95 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -119,6 +119,10 @@ const float UNIT = 4.0f; // default for g_unit float g_unit; // conversion factor +// Min/max values for the game speed. +const float MIN_SPEED = 1/8.0f; +const float MAX_SPEED = 256.0f; + // Reference colors used when recoloring textures, see ChangeColor() const Gfx::Color COLOR_REF_BOT = Gfx::Color( 10.0f/256.0f, 166.0f/256.0f, 254.0f/256.0f); // blue const Gfx::Color COLOR_REF_ALIEN = Gfx::Color(135.0f/256.0f, 170.0f/256.0f, 13.0f/256.0f); // green @@ -5362,6 +5366,15 @@ void CRobotMain::UpdateChapterPassed() //! Changes game speed void CRobotMain::SetSpeed(float speed) { + if(speed < MIN_SPEED) + { + speed = MIN_SPEED; + } + else if(speed > MAX_SPEED) + { + speed = MAX_SPEED; + } + m_app->SetSimulationSpeed(speed); UpdateSpeedLabel(); } From d11404a6e9ddf5017f18b2ab0565c19e066f33ee Mon Sep 17 00:00:00 2001 From: Alexander Olofsson Date: Sun, 25 Nov 2018 14:49:01 +0100 Subject: [PATCH 072/109] Fix Linux savegame path issue, closes #1212 --- src/common/system/system_linux.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/system/system_linux.cpp b/src/common/system/system_linux.cpp index 3cd25ed2..840fca65 100644 --- a/src/common/system/system_linux.cpp +++ b/src/common/system/system_linux.cpp @@ -99,7 +99,7 @@ std::string CSystemUtilsLinux::GetSaveDir() std::string savegameDir; // Determine savegame dir according to XDG Base Directory Specification - char *envXDG_DATA_HOME = getenv("XDG_CONFIG_DATA"); + char *envXDG_DATA_HOME = getenv("XDG_DATA_HOME"); if (envXDG_DATA_HOME == nullptr) { char *envHOME = getenv("HOME"); From 508e7529d2b7cc7ab56175cd8d8b5595e19700fe Mon Sep 17 00:00:00 2001 From: suve Date: Tue, 27 Nov 2018 19:25:56 +0100 Subject: [PATCH 073/109] Use Math::Clamp() when limiting game speed --- src/level/robotmain.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 40b74a95..2e456fc6 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -60,6 +60,7 @@ #include "level/parser/parser.h" #include "math/const.h" +#include "math/func.h" #include "math/geometry.h" #include "object/object.h" @@ -5362,18 +5363,10 @@ void CRobotMain::UpdateChapterPassed() return m_ui->UpdateChapterPassed(); } - //! Changes game speed void CRobotMain::SetSpeed(float speed) { - if(speed < MIN_SPEED) - { - speed = MIN_SPEED; - } - else if(speed > MAX_SPEED) - { - speed = MAX_SPEED; - } + speed = Math::Clamp(speed, MIN_SPEED, MAX_SPEED); m_app->SetSimulationSpeed(speed); UpdateSpeedLabel(); From 92d2de532555cc1a5f076e6847262dd7c42db96c Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Wed, 2 Jan 2019 00:34:34 +0100 Subject: [PATCH 074/109] Fixed VSync options list Now VSync list is aligned for same height as resolution list from the bottom, as it's very hard to align them from top on different screen resolutions. --- src/ui/screen/screen_setup_display.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ui/screen/screen_setup_display.cpp b/src/ui/screen/screen_setup_display.cpp index 15f2511f..d015a58c 100644 --- a/src/ui/screen/screen_setup_display.cpp +++ b/src/ui/screen/screen_setup_display.cpp @@ -102,7 +102,7 @@ void CScreenSetupDisplay::CreateInterface() pc->SetState(STATE_CHECK, m_setupFull); pos.x = ox+sx*10; - pos.y = oy+sy*9; + pos.y = oy+sy*6.75f; ddim.x = dim.x*6; ddim.y = dim.y*1; GetResource(RES_EVENT, EVENT_INTERFACE_VSYNC, name); @@ -110,9 +110,9 @@ void CScreenSetupDisplay::CreateInterface() pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT); pos.x = ox+sx*10; - pos.y = oy+sy*7.97f; + pos.y = oy+sy*5.2f; ddim.x = dim.x*6; - ddim.y = dim.y*1.8f; + ddim.y = dim.y*2; pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_VSYNC); pli->SetState(STATE_SHADOW); pli->SetItemName(0, "Off"); From be97167994838763457967d22f441efd7ff6f568 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Wed, 2 Jan 2019 01:18:45 +0100 Subject: [PATCH 075/109] Potential fix for issue #1128 --- src/graphics/engine/text.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index a16439f4..df284160 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -33,6 +33,7 @@ #include "math/func.h" +#include #include #include @@ -1252,13 +1253,13 @@ FontTexture CText::CreateFontTexture(Math::IntPoint tileSize) Math::IntPoint CText::GetNextTilePos(const FontTexture& fontTexture) { - int horizontalTiles = FONT_TEXTURE_SIZE.x / fontTexture.tileSize.x; - int verticalTiles = FONT_TEXTURE_SIZE.y / fontTexture.tileSize.y; + int horizontalTiles = FONT_TEXTURE_SIZE.x / std::max(1, fontTexture.tileSize.x); //this should prevent crashes in some combinations of resolution and font size, see issue #1128 + int verticalTiles = FONT_TEXTURE_SIZE.y / std::max(1, fontTexture.tileSize.y); int totalTiles = horizontalTiles * verticalTiles; int tileNumber = totalTiles - fontTexture.freeSlots; - int verticalTileIndex = tileNumber / horizontalTiles; + int verticalTileIndex = tileNumber / std::max(1, horizontalTiles); int horizontalTileIndex = tileNumber % horizontalTiles; return Math::IntPoint(horizontalTileIndex * fontTexture.tileSize.x, From e3f53dc20370f394b206af6913e91649a5300949 Mon Sep 17 00:00:00 2001 From: Vladislav Kuzkokov Date: Sun, 6 Jan 2019 07:09:57 +0100 Subject: [PATCH 076/109] Put pitch and roll in [-180,180) range. Reasonable values lie close to either side of 0. --- src/script/scriptfunc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp index 20a85bb2..0816cce8 100644 --- a/src/script/scriptfunc.cpp +++ b/src/script/scriptfunc.cpp @@ -3412,9 +3412,9 @@ void CScriptFunctions::uObject(CBotVar* botThis, void* user) pVar = pVar->GetNext(); // "orientation" pVar->SetValFloat(Math::NormAngle(2*Math::PI - pos.y)*180.0f/Math::PI); pVar = pVar->GetNext(); // "pitch" - pVar->SetValFloat(Math::NormAngle(pos.z)*180.0f/Math::PI); + pVar->SetValFloat((Math::NormAngle(pos.z + Math::PI) - Math::PI)*180.0f/Math::PI); pVar = pVar->GetNext(); // "roll" - pVar->SetValFloat(Math::NormAngle(pos.x)*180.0f/Math::PI); + pVar->SetValFloat((Math::NormAngle(pos.x + Math::PI) - Math::PI)*180.0f/Math::PI); // Updates the energy level of the object. pVar = pVar->GetNext(); // "energyLevel" From 63bf8e07da8e06fcfefc90d0429ff218f425b522 Mon Sep 17 00:00:00 2001 From: maf-ia Date: Sat, 12 Jan 2019 21:28:49 +0100 Subject: [PATCH 077/109] Complete last 5 french sentences not fully translated --- po/fr.po | 2273 ++++++------------------------------------------------ 1 file changed, 233 insertions(+), 2040 deletions(-) diff --git a/po/fr.po b/po/fr.po index ce3f5fdf..a216620b 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1,2052 +1,245 @@ -# Didier Raboud , 2012, 2015, 2016. -# Martin Quinson , 2016 -# B-CE, 2018 +# SOME DESCRIPTIVE TITLE +# Copyright (C) YEAR Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. msgid "" msgstr "" -"Project-Id-Version: Colobot 0.1.11\n" +"Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: DATE\n" -"PO-Revision-Date: 2018-02-28 20:00+0100\n" -"Last-Translator: B-CE\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" "Language: fr\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" -"X-Generator: Lokalize 2.0\n" -"X-Language: fr_FR\n" -"X-Source-Language: en_US\n" - -msgid " or " -msgstr " ou " - -msgid "\" [ \" expected" -msgstr "\" [ \" attendu" - -msgid "\" ] \" missing" -msgstr "\" ] \" manquant" - -#, c-format -msgid "%s: %d pts" -msgstr "%s: %d points" - -msgid "..behind" -msgstr "..derrière" - -msgid "..in front" -msgstr "..devant" - -msgid "..power cell" -msgstr "..pile" - -msgid "1) First click on the key you want to redefine." -msgstr "1) Cliquez d'abord sur la touche à redéfinir." - -msgid "2) Then press the key you want to use instead." -msgstr "2) Appuyez ensuite sur la nouvelle touche souhaitée." - -msgid "<< Back \\Back to the previous screen" -msgstr "<< Retour \\Retour au niveau précédent" - -msgid "<<< Sorry; mission failed >>>" -msgstr "<<< Désolé; mission échouée >>>" - -#, c-format -msgid "<<< Team %s finished! >>>" -msgstr "<<< L'équipe %s a terminé! >>>" - -#, c-format -msgid "<<< Team %s lost! >>>" -msgstr "<<< L'équipe %s a perdu! >>>" - -#, c-format -msgid "<<< Team %s recieved %d points >>>" -msgstr "<<< L'équipe %s a reçu %d points >>>" - -msgid "<<< Well done; mission accomplished >>>" -msgstr "<<< Bravo; mission terminée >>>" - -msgid "A label must be followed by \"for\"; \"while\"; \"do\" or \"switch\"" -msgstr "Un label ne peut se placer que devant un \"for\"; un \"while\"; un \"do\" ou un \"switch\"" - -msgid "A variable can not be declared twice" -msgstr "Redéfinition d'une variable" - -msgid "Abort\\Abort the current mission" -msgstr "Abandonner\\Abandonner la mission en cours" - -msgid "Access beyond array limit" -msgstr "Accès hors du tableau" - -msgid "Access to solution\\Shows the solution (detailed instructions for missions)" -msgstr "Accès à la solution\\Donne la solution (instructions détaillées pour la mission)" - -msgid "Access to solutions\\Show program \"4: Solution\" in the exercises" -msgstr "Accès aux solutions\\Programme \"4: Solution\" dans les exercices" - -msgid "Add new program" -msgstr "Ajouter un nouveau programme" - -msgid "Alien Queen" -msgstr "Pondeuse" - -msgid "Alien Queen killed" -msgstr "Pondeuse mortellement touchée" - -msgid "Already carrying something" -msgstr "Porte déjà quelque chose" - -msgid "Alternative camera mode\\Move sideways instead of rotating (in free camera)" -msgstr "Mode caméra alternatif\\Déplacements latéraux au lieu des rotations (pour une caméra libre)" - -msgid "Ambiguous call to overloaded function" -msgstr "Appel ambigu à une fonction surchargée" - -msgid "Analysis already performed" -msgstr "Analyse déjà effectuée" - -msgid "Analysis performed" -msgstr "Analyse terminée" - -msgid "Analyzes only organic matter" -msgstr "N'analyse que la matière organique" - -msgid "Anisotropy level\\Anisotropy level" -msgstr "Niveau d'anisotropie\\Niveau d'anisotropie" - -msgid "Ant" -msgstr "Fourmi" - -msgid "Ant fatally wounded" -msgstr "Fourmi mortellement touchée" - -msgid "Appearance\\Choose your appearance" -msgstr "Aspect\\Choisir votre aspect" - -msgid "Apply changes\\Activates the changed settings" -msgstr "Appliquer les changements\\Active les changements effectués" - -msgid "Appropriate constructor missing" -msgstr "Constructeur approprié manquant" - -msgid "Assignment impossible" -msgstr "Assignation impossible" - -msgid "Autolab" -msgstr "Laboratoire d'analyse de matières organiques" - -msgid "Automatic indent\\When program editing" -msgstr "Indentation automatique\\Pendant l'édition d'un programme" - -msgid "Autosave interval\\How often your game will autosave" -msgstr "Interval d'auto-sauvegarde\\À quels intervals les parties vont-t-elles êtres sauvegardées automatiquement" - -msgid "Autosave slots\\How many autosave slots you'll have" -msgstr "Nombre d'auto-sauvegardes\\Combien d'auto-sauvegarde seront conservées" - -msgid "Autosave\\Enables autosave" -msgstr "Auto-sauvegarde\\Activer l'auto-sauvegarde" - -msgid "Back" -msgstr "Page précédente" - -msgid "Background sound:\\Volume of audio tracks" -msgstr "Fond sonore :\\Volume des pistes audio" - -msgid "Backward (\\key down;)" -msgstr "Recule (\\key down;)" - -msgid "Backward\\Moves backward" -msgstr "Reculer\\Se déplacer en arrière" - -msgid "Bad argument for \"new\"" -msgstr "Mauvais argument pour \"new\"" - -msgid "Big indent\\Indent 2 or 4 spaces per level defined by braces" -msgstr "Grande indentation\\Indente avec 2 ou 4 espaces par niveau" - -msgid "Black box" -msgstr "Boîte noire" - -msgid "Blood\\Display blood when the astronaut is hit" -msgstr "Sang\\Afficher du sang quand le cosmonaute est touché" - -msgid "Blue" -msgstr "Bleue" - -# tocheck : for team (fem): bleue -# tocheck : for flag/pen/bot (masc): bleu -# + capital also to check -msgid "Blue flag" -msgstr "Drapeau bleu" - -msgid "Bot destroyed" -msgstr "Robot détruit" - -msgid "Bot factory" -msgstr "Fabrique de robots" - -msgid "Build a bot factory" -msgstr "Construire une fabrique de robots" - -msgid "Build a converter" -msgstr "Construire un convertisseur" - -msgid "Build a defense tower" -msgstr "Construire une tour" - -msgid "Build a derrick" -msgstr "Construire un derrick" - -msgid "Build a destroyer" -msgstr "Construire un destructeur" - -msgid "Build a exchange post" -msgstr "Construire une borne d'information" - -msgid "Build a legged grabber" -msgstr "Fabriquer un déménageur à pattes" - -msgid "Build a legged orga shooter" -msgstr "Fabriquer un tireur organique à pattes" - -msgid "Build a legged shooter" -msgstr "Fabriquer un tireur à pattes" - -msgid "Build a legged sniffer" -msgstr "Fabriquer un renifleur à pattes" - -msgid "Build a lightning conductor" -msgstr "Construire un paratonnerre" - -msgid "Build a nuclear power plant" -msgstr "Construire une centrale nucléaire" - -msgid "Build a phazer shooter" -msgstr "Fabriquer un robot canon à phases" - -msgid "Build a power cell factory" -msgstr "Construire une fabrique de piles" - -msgid "Build a power station" -msgstr "Construire une station de recharge" - -msgid "Build a radar station" -msgstr "Construire un radar" - -msgid "Build a recycler" -msgstr "Fabriquer un robot recycleur" - -msgid "Build a repair center" -msgstr "Construire un centre de réparation" - -msgid "Build a research center" -msgstr "Construire un centre de recherches" - -msgid "Build a shielder" -msgstr "Fabriquer un robot bouclier" - -msgid "Build a subber" -msgstr "Fabriquer un robot sous-marin" - -msgid "Build a thumper" -msgstr "Fabriquer un robot secoueur" - -msgid "Build a tracked grabber" -msgstr "Fabriquer un déménageur à chenilles" - -msgid "Build a tracked orga shooter" -msgstr "Fabriquer un tireur organique à chenilles" - -msgid "Build a tracked shooter" -msgstr "Fabriquer un tireur à chenilles" - -msgid "Build a tracked sniffer" -msgstr "Fabriquer un renifleur à chenilles" - -msgid "Build a wheeled grabber" -msgstr "Fabriquer un déménageur à roues" - -msgid "Build a wheeled orga shooter" -msgstr "Fabriquer un tireur organique à roues" - -msgid "Build a wheeled shooter" -msgstr "Fabriquer un tireur à roues" - -msgid "Build a wheeled sniffer" -msgstr "Fabriquer un renifleur à roues" - -msgid "Build a winged grabber" -msgstr "Fabriquer un déménageur volant" - -msgid "Build a winged orga shooter" -msgstr "Fabriquer un tireur organique volant" - -msgid "Build a winged shooter" -msgstr "Fabriquer un tireur volant" - -msgid "Build a winged sniffer" -msgstr "Fabriquer un renifleur volant" - -msgid "Build an autolab" -msgstr "Construire un laboratoire d'analyse de matières organiques" - -msgid "Building completed" -msgstr "Bâtiment terminé" - -msgid "Building destroyed" -msgstr "Bâtiment détruit" - -msgid "Button %1" -msgstr "Bouton %1" - -msgid "Calling an unknown function" -msgstr "Appel d'une fonction inexistante" - -msgid "Camera (\\key camera;)" -msgstr "Caméra (\\key camera;)" - -msgid "Camera back\\Moves the camera backward" -msgstr "Caméra plus loin\\Recule la caméra" - -msgid "Camera border scrolling\\Scrolling when the mouse touches right or left border" -msgstr "Défilement dans les bords\\Défilement lorsque la souris touche les bords gauche ou droite" - -msgid "Camera closer\\Moves the camera forward" -msgstr "Caméra plus proche\\Avance la caméra" - -msgid "Camera down\\Turns the camera down" -msgstr "Baisser caméra\\Baisse la caméra" - -msgid "Camera left\\Turns the camera left" -msgstr "Caméra à gauche\\Tourne la caméra vers la gauche" - -msgid "Camera right\\Turns the camera right" -msgstr "Caméra à droite\\Tourne la caméra vers la droite" - -msgid "Camera up\\Turns the camera up" -msgstr "Lever caméra\\Monte la caméra" - -msgid "Can not produce not researched object" -msgstr "Impossible de créer un objet n'ayant pas été recherché" - -msgid "Can not produce this object in this mission" -msgstr "Impossible de créer cet objet dans cette mission" - -msgid "Can't open file" -msgstr "Ouverture du fichier impossible" - -msgid "Cancel" -msgstr "Annuler" - -msgid "Cancel\\Cancel all changes" -msgstr "Annuler\\Annuler toutes les modifications" - -msgid "Challenges" -msgstr "Défis" - -msgid "Challenges in the chapter:" -msgstr "Liste des défis du chapitre :" - -msgid "Challenges\\Programming challenges" -msgstr "Défis\\Défis de programmation" - -msgid "Change camera\\Switches between onboard camera and following camera" -msgstr "Changement de caméra\\Autre de point de vue" - -msgid "Change player\\Change player" -msgstr "Autre joueur\\Choix du nom du joueur" - -msgid "Chapters:" -msgstr "Liste des chapitres :" - -msgid "Cheat console\\Show cheat console" -msgstr "Console de triche\\Montre la console de triche" - -msgid "Checkpoint" -msgstr "Indicateur" - -msgid "Class name expected" -msgstr "Nom de classe attendu" - -msgid "Climb\\Increases the power of the jet" -msgstr "Monter\\Augmenter la puissance du réacteur" - -msgid "Clone program" -msgstr "Dupliquer le programme" - -msgid "Clone selected program" -msgstr "Dupliquer le programme sélectionné" - -msgid "Close" -msgstr "Fermer" - -msgid "Closing bracket missing" -msgstr "Il manque une parenthèse fermante" - -#, fuzzy -msgid "Code battle" -msgstr "Batailles de code" - -msgid "Code battles" -msgstr "Batailles de code" - -msgid "Code battles\\Program your robot to be the best of them all!" -msgstr "Batailles de code\\Programmez votre robot pour être le meilleur entre tous!" - -msgid "Colobot rules!" -msgstr "Colobot est super!" - -msgid "Colobot: Gold Edition" -msgstr "Colobot: Édition Gold" - -msgid "Command line" -msgstr "Console de commande" - -msgid "Compilation ok (0 errors)" -msgstr "Compilation ok (0 erreur)" - -msgid "Compile" -msgstr "Compiler" - -msgid "Continue" -msgstr "Continuer" - -msgid "Continue\\Continue the current mission" -msgstr "Continuer\\Continuer la mission en cours" - -msgid "Controls\\Keyboard, joystick and mouse settings" -msgstr "Commandes\\Touches du clavier" - -msgid "Converts ore to titanium" -msgstr "Conversion de minerai en titane" - -msgid "Copy" -msgstr "Copier" - -msgid "Copy (Ctrl+C)" -msgstr "Copier (Ctrl+C)" - -msgid "Current mission saved" -msgstr "Enregistrement effectué" - -msgid "Custom levels:" -msgstr "Niveaux spéciaux :" - -msgid "Custom levels\\Levels from mods created by the users" -msgstr "Niveaux spéciaux\\Niveaux importés ou personnalisés" - -msgid "Customize your appearance" -msgstr "Personnalisation de votre apparence" - -msgid "Cut (Ctrl+X)" -msgstr "Couper (Ctrl+X)" - -msgid "Defense tower" -msgstr "Tour de défense" - -msgid "Delete mark" -msgstr "Supprimer la marque" - -msgid "Delete player\\Deletes the player from the list" -msgstr "Supprimer le joueur\\Supprimer le joueur de la liste" - -msgid "Delete\\Deletes the selected file" -msgstr "Supprimer\\Supprime l'enregistrement sélectionné" - -msgid "Derrick" -msgstr "Derrick" - -msgid "Descend\\Reduces the power of the jet" -msgstr "Descendre\\Diminuer la puissance du réacteur" - -msgid "Destroy" -msgstr "Détruire" - -msgid "Destroy the building" -msgstr "Démolit le bâtiment" - -msgid "Destroyer" -msgstr "Destructeur" - -msgid "Device\\Driver and resolution settings" -msgstr "Affichage\\Pilote et résolution d'affichage" - -msgid "Dividing by zero" -msgstr "Division par zéro" - -msgid "Do you really want to destroy the selected building?" -msgstr "Voulez-vous vraiment détruire le bâtiment sélectionné ?" - -#, c-format -msgid "Do you want to delete %s's saved games?" -msgstr "Voulez-vous détruire les sauvegardes de %s ?" - -msgid "Doors blocked by a robot or another object" -msgstr "Portes bloquées par un robot ou un objet" - -msgid "Down (\\key gdown;)" -msgstr "Descend (\\key gdown;)" - -msgid "Drawer bot" -msgstr "Robot dessinateur" - -msgid "Dust\\Dust and dirt on bots and buildings" -msgstr "Salissures\\Salissures des robots et bâtiments" - -msgid "Dynamic lighting\\Mobile light sources" -msgstr "Lumières dynamiques\\Éclairages mobiles" - -msgid "Dynamic shadows ++\\Dynamic shadows + self shadowing" -msgstr "Ombres dynamiques ++\\Active les ombres dynamiques et l'auto-ombrage" - -msgid "Dynamic shadows\\Beautiful shadows!" -msgstr "Ombres dynamiques\\Magnifiques ombres !" - -msgid "Edit the selected program" -msgstr "Éditer le programme sélectionné" - -msgid "Egg" -msgstr "Oeuf" - -msgid "End of block missing" -msgstr "Il manque la fin du bloc" - -msgid "Energy deposit (site for power station)" -msgstr "Emplacement pour une station de recharge ou une fabrique de pile" - -msgid "Energy level" -msgstr "Niveau d'énergie" - -msgid "Engineer" -msgstr "Technicien" - -msgid "Error in instruction move" -msgstr "Déplacement impossible" - -msgid "Execute the selected program" -msgstr "Exécute le programme sélectionné" - -msgid "Execute/stop" -msgstr "Démarrer/stopper" - -msgid "Exercises in the chapter:" -msgstr "Liste des exercices du chapitre :" - -msgid "Exercises\\Programming exercises" -msgstr "Programmation\\Exercices de programmation" - -msgid "Explode (\\key action;)" -msgstr "Détruire (\\key action;)" - -msgid "Explosive" -msgstr "Explosif" - -msgid "Expression expected after =" -msgstr "Expression attendue après =" - -msgid "Extend shield (\\key action;)" -msgstr "Déploie le bouclier (\\key action;)" - -msgid "Eyeglasses:" -msgstr "Lunettes :" - -msgid "Face type:" -msgstr "Type de visage :" - -msgid "File not open" -msgstr "Le fichier n'est pas ouvert" - -msgid "Filename:" -msgstr "Nom du fichier :" - -msgid "Film sequences\\Films before and after the missions" -msgstr "Séquences cinématiques\\Films avant ou après une mission" - -msgid "Finish" -msgstr "But/Objectif" - -# OBJECT_END : GoalArea -msgid "Fixed mine" -msgstr "Mine fixe" - -msgid "Flat ground not large enough" -msgstr "Sol plat pas assez grand" - -msgid "Fog\\Fog" -msgstr "Brouillard\\Nappes de brouillard" - -msgid "Folder:" -msgstr "Dossier:" - -#, c-format -msgid "Folder: %s" -msgstr "Dossier: %s" - -msgid "Font size" -msgstr "Taille des caractères" - -msgid "Forward" -msgstr "Page suivante" - -msgid "Forward (\\key up;)" -msgstr "Avance (\\key up;)" - -msgid "Forward\\Moves forward" -msgstr "Avancer\\Se déplacer en avant" - -msgid "Found a site for a derrick" -msgstr "Emplacement pour un derrick trouvé" - -msgid "Found a site for power station" -msgstr "Emplacement pour station de recharge ou fabrique de pile trouvé" - -msgid "Found key A (site for derrick)" -msgstr "Emplacement pour un derrick (clé A)" - -msgid "Found key B (site for derrick)" -msgstr "Emplacement pour un derrick (clé B)" - -msgid "Found key C (site for derrick)" -msgstr "Emplacement pour un derrick (clé C)" - -msgid "Found key D (site for derrick)" -msgstr "Emplacement pour un derrick (clé D)" - -msgid "Free game" -msgstr "Jeu libre" - -msgid "Free game on this planet:" -msgstr "Liste des jeux libres du chapitre :" - -msgid "Free game\\Free game without a specific goal" -msgstr "Jeu libre\\Jeu libre sans but précis" - -msgid "Full screen\\Full screen or window mode" -msgstr "Plein écran\\Plein écran ou fenêtré" - -msgid "Function already exists" -msgstr "Cette fonction existe déjà" - -msgid "Function name missing" -msgstr "Nom de la fonction attendu" - -msgid "Function needs return type \"void\"" -msgstr "La fonction a besoin de \"void\" en type de retour" - -msgid "Game speed" -msgstr "Vitesse du jeu" - -msgid "Game\\Game settings" -msgstr "Jeu\\Options de jouabilité" - -msgid "Gantry crane" -msgstr "Portique" - -msgid "Generating" -msgstr "Génération" - -msgid "Gold Edition development by:" -msgstr "Édition Gold développée par :" - -msgid "Goto: destination occupied" -msgstr "Goto: destination occupée" - -msgid "Goto: inaccessible destination" -msgstr "Goto: chemin introuvable" - -msgid "Grab or drop (\\key action;)" -msgstr "Prend ou dépose (\\key action;)" - -msgid "Graphics\\Graphics settings" -msgstr "Graphique\\Options graphiques" - -msgid "Green" -msgstr "Vert" - -msgid "Green flag" -msgstr "Drapeau vert" - -msgid "Ground not flat enough" -msgstr "Sol pas assez plat" - -msgid "Hair color:" -msgstr "Couleur des cheveux :" - -msgid "Head\\Face and hair" -msgstr "Tête\\Visage et cheveux" - -msgid "Help about selected object" -msgstr "Instructions sur la sélection" - -msgid "Help balloons\\Explain the function of the buttons" -msgstr "Bulles d'aide\\Bulles explicatives" - -msgid "Hex value out of range" -msgstr "Valeur hexadécimale impossible" - -#, fuzzy -msgid "Higher speed\\Doubles speed" -msgstr "Vitesse 2.0x\\Deux fois plus rapide" - -msgid "Highest\\Highest graphic quality (lowest frame rate)" -msgstr "Maxi\\Haute qualité (+ lent)" - -msgid "Home" -msgstr "Page initiale" - -msgid "Houston Mission Control" -msgstr "Centre de contrôle de Houston" - -msgid "Illegal object" -msgstr "Objet inaccessible" - -msgid "Impossible under water" -msgstr "Impossible sous l'eau" - -msgid "Impossible when carrying an object" -msgstr "Impossible en portant un objet" - -msgid "Impossible when flying" -msgstr "Impossible en vol" - -msgid "Impossible when moving" -msgstr "Impossible en mouvement" - -msgid "Impossible when swimming" -msgstr "Impossible en nageant" - -msgid "Inappropriate bot" -msgstr "Robot inadapté" - -msgid "Inappropriate cell type" -msgstr "Pas le bon type de pile" - -msgid "Inappropriate object" -msgstr "Pas le bon objet" - -msgid "Incorrect index type" -msgstr "Mauvais type d'index" - -msgid "Infected by a virus; temporarily out of order" -msgstr "Infecté par un virus; ne fonctionne plus temporairement" - -msgid "Information exchange post" -msgstr "Borne d'information" - -msgid "Instruction \"break\" outside a loop" -msgstr "Instruction \"break\" en dehors d'une boucle" - -msgid "Instruction \"case\" missing" -msgstr "Il manque l'instruction \"case\"" - -msgid "Instruction \"case\" outside a block \"switch\"" -msgstr "Instruction \"case\" en dehors d'un bloc \"switch\"" - -msgid "Instruction \"else\" without corresponding \"if\"" -msgstr "Instruction \"else\" sans \"if\" correspondant" - -msgid "Instructions (\\key help;)" -msgstr "Instructions (\\key help;)" - -msgid "Instructions after the final closing brace" -msgstr "Instructions après la dernière accolade fermante" - -msgid "Instructions for the mission (\\key help;)" -msgstr "Instructions sur la mission (\\key help;)" - -msgid "Instructions from Houston" -msgstr "Instructions de Houston" - -msgid "Instructions\\Shows the instructions for the current mission" -msgstr "Instructions mission\\Marche à suivre" - -msgid "Internal error - tell the developers" -msgstr "Erreur interne - contacter les développeurs" - -msgid "Invalid universal character name" -msgstr "Conversion invalide d'un caractère unicode en caractère UTF8" - -msgid "Invert\\Invert values on this axis" -msgstr "Inversion\\Inverse les valeurs sur cet axe" - -msgid "Jet temperature" -msgstr "Température du réacteur" - -msgid "Key A" -msgstr "Clé A" - -msgid "Key B" -msgstr "Clé B" - -msgid "Key C" -msgstr "Clé C" - -msgid "Key D" -msgstr "Clé D" - -msgid "Keyword \"while\" missing" -msgstr "Le mot-clé \"while\" est attendu" - -msgid "Keyword help(\\key cbot;)" -msgstr "Aide sur le mot-clé (\\key cbot;)" - -msgid "LOADING" -msgstr "CHARGEMENT" - -msgid "Legged grabber" -msgstr "Robot déménageur à pattes" - -msgid "Legged orga shooter" -msgstr "Robot tireur organique à pattes" - -msgid "Legged shooter" -msgstr "Robot tireur à pattes" - -msgid "Legged sniffer" -msgstr "Robot renifleur à pattes" - -msgid "Levels in this chapter:" -msgstr "Liste des niveaux du chapitre :" - -msgid "Lightning conductor" -msgstr "Paratonnerre" - -msgid "List of objects" -msgstr "Liste des objets" - -msgid "List of saved missions" -msgstr "Liste des missions enregistrées" - -msgid "Load a saved mission" -msgstr "Chargement d'une mission enregistrée" - -msgid "Load\\Load a saved mission" -msgstr "Charger\\Charger une mission enregistrée" - -msgid "Load\\Loads the selected mission" -msgstr "Charger\\Charger la mission sélectionnée" - -msgid "Loading basic level settings" -msgstr "Chargement des configurations de base du niveau" - -msgid "Loading finished!" -msgstr "Chargement terminé !" - -msgid "Loading music" -msgstr "Chargement de la musique" - -msgid "Loading objects" -msgstr "Chargement des objets" - -msgid "Loading terrain" -msgstr "Chargement du terrain" - -# msgid "Speed 0.5x\\Half speed" -# msgstr "" -# msgid "Speed 1.0x\\Normal speed" -# msgstr "" -# msgid "Speed 1.5x\\1.5 times faster" -# msgstr "" -# msgid "Speed 2.0x\\Double speed" -# msgstr "" -# msgid "Speed 3.0x\\Triple speed" -# msgstr "" -# msgid "Speed 4.0x\\Quadruple speed" -# msgstr "" -# msgid "Speed 6.0x\\Sextuple speed" -# msgstr "" -msgid "Lower speed\\Decrease speed by half" -msgstr "Moins rapide\\Diminuer la vitesse de moitié" - -msgid "Lowest\\Minimum graphic quality (highest frame rate)" -msgstr "Mini\\Qualité minimale (+ rapide)" - -msgid "Lunar Roving Vehicle" -msgstr "Véhicule d'exploration lunaire" - -msgid "MSAA\\Multisample anti-aliasing" -msgstr "ACME\\Anticrénelage multiéchantillon" - -msgid "Maximize" -msgstr "Taille maximale" - -msgid "Minimize" -msgstr "Taille réduite" - -msgid "Mipmap level\\Mipmap level" -msgstr "Niveau de MIP mapping\\Niveau de MIP mapping" - -msgid "Missing end quote" -msgstr "La quote de fin est manquante" - -msgid "Missing hex digits after escape sequence" -msgstr "Valeur hexadécimale manquante après la séquence d'échappement" - -msgid "Mission name" -msgstr "Nom de la mission" - -msgid "Missions" -msgstr "Missions" - -msgid "Missions on this planet:" -msgstr "Liste des missions du chapitre :" - -msgid "Missions\\Select mission" -msgstr "Missions\\La grande aventure" - -msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis" -msgstr "Inversion souris X\\Inversion de la rotation lorsque la souris touche un bord" - -msgid "Mouse inversion Y\\Inversion of the scrolling direction on the Y axis" -msgstr "Inversion souris Y\\Inversion de la rotation lorsque la souris touche un bord" - -msgid "Move selected program down" -msgstr "Déplace le programme sélectionné vers le bas" - -msgid "Move selected program up" -msgstr "Déplace le programme sélectionné vers le haut" - -msgid "Mute\\No sound" -msgstr "Silencieux\\Totalement silencieux" - -msgid "Name:" -msgstr "Nom:" - -msgid "Negative value rejected by \"throw\"" -msgstr "Valeur négative refusée pour \"throw\"" - -msgid "Nest" -msgstr "Nid" - -msgid "New" -msgstr "Nouveau" - -msgid "New ..." -msgstr "Nouveau ..." - -msgid "New bot available" -msgstr "Nouveau robot disponible" - -msgid "Next" -msgstr "Suivant" - -msgid "Next object\\Selects the next object" -msgstr "Sélectionner l'objet suivant\\Sélectionner l'objet suivant" - -msgid "No" -msgstr "Non" - -msgid "No energy in the subsoil" -msgstr "Pas d'énergie en sous-sol" - -msgid "No flag nearby" -msgstr "Aucun drapeau à proximité" - -msgid "No function running" -msgstr "Pas de fonction en exécution" - -msgid "No function with this name accepts this kind of parameter" -msgstr "Aucune fonction de ce nom n'accepte ce(s) type(s) de paramètre(s)" - -msgid "No function with this name accepts this number of parameters" -msgstr "Aucune fonction de ce nom n'accepte ce nombre de paramètres" - -msgid "No information exchange post within range" -msgstr "Pas de borne d'information accessible" - -msgid "No more energy" -msgstr "Plus d'énergie" - -msgid "No ore in the subsoil" -msgstr "Pas de minerai en sous-sol" - -msgid "No power cell" -msgstr "Pas de pile" - -msgid "No titanium" -msgstr "Pas de titane" - -msgid "No titanium around" -msgstr "Pas de titane accessible" - -msgid "No titanium ore to convert" -msgstr "Pas de minerai de titane à convertir" - -msgid "No titanium to transform" -msgstr "Pas de titane à transformer" - -msgid "No uranium to transform" -msgstr "Pas de minerai d'uranium à transformer" - -msgid "No userlevels installed!" -msgstr "Pas de niveaux spéciaux installés !" - -msgid "Non-void function needs \"return;\"" -msgstr "Les fonctions avec retour autre que void doivent comporter l'instruction \"return;\"" - -msgid "Normal size" -msgstr "Taille normale" - -msgid "Normal\\Normal graphic quality" -msgstr "Normal\\Qualité standard" - -msgid "Normal\\Normal sound volume" -msgstr "Normal\\Niveaux normaux" - -msgid "Not enough energy" -msgstr "Pas assez d'énergie" - -msgid "Not enough energy yet" -msgstr "Pas encore assez d'énergie" - -msgid "Not found anything to destroy" -msgstr "Rien trouvé à détruire" - -msgid "Nothing to analyze" -msgstr "Rien à analyser" - -msgid "Nothing to drop" -msgstr "Rien à déposer" - -msgid "Nothing to grab" -msgstr "Rien à prendre" - -msgid "Nothing to recycle" -msgstr "Rien à recycler" - -msgid "Nuclear power cell" -msgstr "Pile nucléaire" - -msgid "Nuclear power cell available" -msgstr "Pile nucléaire disponible" - -msgid "Nuclear power station" -msgstr "Centrale nucléaire" - -msgid "Number missing" -msgstr "Un nombre est attendu" - -msgid "Number of insects detected" -msgstr "Nombre d'insectes détectés" - -msgid "Number of particles\\Explosions, dust, reflections, etc." -msgstr "Quantité de particules\\Explosions, poussières, reflets, etc." - -msgid "OK" -msgstr "D'accord" - -msgid "OK\\Choose the selected player" -msgstr "D'accord\\Choisir le joueur" - -msgid "OK\\Close program editor and return to game" -msgstr "D'accord\\Compiler le programme" - -msgid "Object too close" -msgstr "Objet trop proche" - -msgid "Octal value out of range" -msgstr "Valeur octale impossible" - -msgid "One step" -msgstr "Un pas" - -msgid "Open" -msgstr "Ouvrir" - -msgid "Open (Ctrl+O)" -msgstr "Ouvrir (Ctrl+O)" - -msgid "Opening brace missing" -msgstr "Début d'un bloc attendu" - -msgid "Opening bracket missing" -msgstr "Une parenthèse ouvrante est attendue" - -msgid "Operation impossible with value \"nan\"" -msgstr "Opération sur un \"nan\"" - -msgid "Options" -msgstr "Options" - -msgid "Options\\Preferences" -msgstr "Options\\Réglages" - -msgid "Organic matter" -msgstr "Matière organique" - -msgid "Origin of last message\\Shows where the last message was sent from" -msgstr "Montrer le lieu d'un message\\Montrer le lieu du dernier message" - -msgid "Original game developed by:" -msgstr "Jeu original développé par :" - -msgid "Parameters missing" -msgstr "Pas assez de paramètres" - -msgid "Particles in the interface\\Steam clouds and sparks in the interface" -msgstr "Particules dans l'interface\\Pluie de particules" - -msgid "Paste (Ctrl+V)" -msgstr "Coller (Ctrl+V)" - -msgid "Pause blur\\Blur the background on the pause screen" -msgstr "Flouter les pauses\\Floute le fond de l'écran de pause" - -msgid "Pause in background\\Pause the game when the window is unfocused" -msgstr "Pause en arrière-plan\\Met le jeu en pause quand la fenêtre n'a plus le focus" - -msgid "Pause/continue" -msgstr "Pause/continuer" - -msgid "Pause\\Pause the game without opening menu" -msgstr "Pause\\Mettre le jeu en pause sans ouvrir le menu" - -msgid "Phazer shooter" -msgstr "Robot canon à phases" - -msgid "Photography" -msgstr "Vue de la mission" - -msgid "Place occupied" -msgstr "Emplacement occupé" - -msgid "Planets:" -msgstr "Liste des planètes :" - -msgid "Plans for defense tower available" -msgstr "Construction d'une tour de défense possible" - -msgid "Plans for nuclear power plant available" -msgstr "Construction d'une centrale nucléaire possible" - -msgid "Plans for phazer shooter available" -msgstr "Fabrication des robots canon à phases possible" - -msgid "Plans for shielder available" -msgstr "Fabrication d'un robot bouclier possible" - -msgid "Plans for shooter available" -msgstr "Fabrication des robots tireurs possible" - -msgid "Plans for thumper available" -msgstr "Fabrication d'un robot secoueur possible" - -msgid "Plans for tracked robots available" -msgstr "Fabrication des robots à chenilles possible" - -msgid "Plant a flag" -msgstr "Pose un drapeau de couleur" - -msgid "Play\\Start mission!" -msgstr "Jouer ...\\Démarrer l'action!" - -msgid "Player" -msgstr "Joueur" - -msgid "Player name" -msgstr "Nom du joueur" - -msgid "Player's name" -msgstr "Nom du joueur" - -msgid "Power cell" -msgstr "Pile normale" - -msgid "Power cell available" -msgstr "Pile disponible" - -msgid "Power cell factory" -msgstr "Fabrique de piles" - -msgid "Power station" -msgstr "Station de recharge" - -msgid "Practice bot" -msgstr "Robot d'entraînement" - -msgid "Press \\key help; to read instructions on your SatCom" -msgstr "Consultez votre SatCom en appuyant sur \\key help;" - -msgid "Previous" -msgstr "Précédent" - -msgid "Previous object\\Selects the previous object" -msgstr "Sélection précédente\\Sélectionne l'objet précédent" - -msgid "Previous selection (\\key desel;)" -msgstr "Sélection précédente (\\key desel;)" - -msgid "Private element" -msgstr "Elément protégé (privé)" - -msgid "Private\\Private folder" -msgstr "Privé\\Dossier privé" - -msgid "Processing level file" -msgstr "Analyse du fichier de niveau" - -msgid "Program cloned" -msgstr "Programme dupliqué" - -msgid "Program editor" -msgstr "Édition du programme" - -msgid "Program finished" -msgstr "Programme terminé" - -msgid "Program infected by a virus" -msgstr "Un programme est infecté par un virus" - -msgid "Programming exercises" -msgstr "Programmation" - -msgid "Programming help" -msgstr "Aide à la programmation" - -msgid "Programming help (\\key prog;)" -msgstr "Aide à la programmation (\\key prog;)" - -msgid "Programming help\\Gives more detailed help with programming" -msgstr "Instructions programmation\\Explication sur la programmation" - -msgid "Programs dispatched by Houston" -msgstr "Programmes envoyés par Houston" - -msgid "Public required" -msgstr "Public requis" - -msgid "Public\\Common folder" -msgstr "Public\\Dossier commun à tous les joueurs" - -msgid "Quake at explosions\\The screen shakes at explosions" -msgstr "Secousses lors d'explosions\\L'écran vibre lors d'une explosion" - -msgid "Quick load\\Immediately load game" -msgstr "Chargement rapide\\Chargement direct d'une sauvegarde" - -msgid "Quick save\\Immediately save game" -msgstr "Sauvegarde rapide\\Sauvegarde direct" - -#, fuzzy -msgid "Quicksave slot not found" -msgstr "Objet n'existe pas" - -msgid "Quit\\Quit Colobot: Gold Edition" -msgstr "Quitter\\Quitter Colobot : Édition Gold" - -msgid "Quit\\Quit the current mission or exercise" -msgstr "Quitter la mission en cours\\Terminer un exercice ou une mssion" - -msgid "Radar station" -msgstr "Radar" - -msgid "Read error" -msgstr "Erreur à la lecture" - -msgid "Recorder" -msgstr "Enregistreur" - -msgid "Recycle (\\key action;)" -msgstr "Recycle (\\key action;)" - -msgid "Recycler" -msgstr "Robot recycleur" - -msgid "Red" -msgstr "Rouge" - -# toCheck : capital (for team?) -msgid "Red flag" -msgstr "Drapeau rouge" - -msgid "Reflections on the buttons \\Shiny buttons" -msgstr "Reflets sur les boutons\\Boutons brillants" - -msgid "Remains of Apollo mission" -msgstr "Vestige d'une mission Apollo" - -msgid "Remove a flag" -msgstr "Enlève un drapeau" - -msgid "Remove selected program" -msgstr "Supprimer le programme sélectionné" - -msgid "Render distance\\Maximum visibility" -msgstr "Profondeur de champ\\Distance de vue maximale " - -msgid "Repair center" -msgstr "Centre de réparation" - -msgid "Research center" -msgstr "Centre de recherches" - -msgid "Research program already performed" -msgstr "Recherche déjà effectuée" - -msgid "Research program completed" -msgstr "Recherche terminée" - -msgid "Reserved keyword of CBOT language" -msgstr "Ce mot-clé est réservé au langage CBOT" - -msgid "Resolution" -msgstr "Résolution" - -msgid "Resolution:" -msgstr "Résolutions :" - -msgid "Resources" -msgstr "Ressources" - -msgid "Restart\\Restart the mission from the beginning" -msgstr "Recommencer\\Recommencer la mission au début" - -msgid "Restoring CBot execution state" -msgstr "Restaurer l'état d'exécution CBOT" - -msgid "Restoring saved objects" -msgstr "Restaurer des objets sauvés" - -msgid "Results" -msgstr "Résultats" - -msgid "Return to start" -msgstr "Remet au départ" - -msgid "Robbie" -msgstr "Robbie" - -msgid "Ruin" -msgstr "Bâtiment en ruine" - -msgid "Run research program for defense tower" -msgstr "Recherche la tour de défense" - -msgid "Run research program for legged bots" -msgstr "Recherche du fonctionnement des pattes" - -msgid "Run research program for nuclear power" -msgstr "Recherche du programme nucléaire" - -msgid "Run research program for orga shooter" -msgstr "Recherche le canon organique" - -msgid "Run research program for phazer shooter" -msgstr "Recherche le canon à phases" - -msgid "Run research program for shielder" -msgstr "Recherche le bouclier" - -msgid "Run research program for shooter" -msgstr "Recherche le canon de tir" - -msgid "Run research program for thumper" -msgstr "Recherche le secoueur" - -msgid "Run research program for tracked bots" -msgstr "Recherche du fonctionnement des chenilles" - -msgid "Run research program for winged bots" -msgstr "Recherche du fonctionnement du jet" - -msgid "SatCom" -msgstr "SatCom" - -msgid "Satellite report" -msgstr "Rapport du satellite" - -msgid "Save" -msgstr "Enregistrer" - -msgid "Save (Ctrl+S)" -msgstr "Enregistrer (Ctrl+S)" - -msgid "Save the current mission" -msgstr "Enregistrement de la mission en cours" - -msgid "Save\\Save the current mission" -msgstr "Enregistrer\\Enregistrer la mission en cours" - -msgid "Save\\Saves the current mission" -msgstr "Enregistrer\\Enregistrer la mission en cours" - -msgid "Select the astronaut\\Selects the astronaut" -msgstr "Sélectionner le cosmonaute\\Sélectionner le cosmonaute" - -msgid "Semicolon terminator missing" -msgstr "Terminateur point-virgule non trouvé" - -msgid "Shadow resolution\\Higher means better range and quality, but slower" -msgstr "Résolution des ombres\\Plus grand implique une meilleure qualité et amplitude, mais plus lent" - -msgid "Shield level" -msgstr "Niveau du bouclier" - -msgid "Shield radius" -msgstr "Rayon du bouclier" - -msgid "Shielder" -msgstr "Robot bouclier" - -msgid "Shoot (\\key action;)" -msgstr "Tir (\\key action;)" - -msgid "Show if the ground is flat" -msgstr "Montre si le sol est plat" - -msgid "Show the place" -msgstr "Montre l'endroit" - -msgid "Show the range" -msgstr "Montre le rayon d'action" - -msgid "Show the solution" -msgstr "Donne la solution" - -msgid "Sign \" : \" missing" -msgstr "Séparateur \" : \" attendu" - -msgid "Simple shadows\\Shadows spots on the ground" -msgstr "Ombres simples\\Ombres projetées au sol" - -msgid "Size 1" -msgstr "Taille 1" - -msgid "Size 2" -msgstr "Taille 2" - -msgid "Size 3" -msgstr "Taille 3" - -msgid "Size 4" -msgstr "Taille 4" - -msgid "Size 5" -msgstr "Taille 5" - -msgid "Sniff (\\key action;)" -msgstr "Cherche (\\key action;)" - -msgid "Solution" -msgstr "Solution" - -msgid "Sound effects:\\Volume of engines, voice, shooting, etc." -msgstr "Sons :\\Volume des moteurs, voix, etc." - -msgid "Sound\\Music and game sound volume" -msgstr "Son\\Volumes des sons & musiques" - -msgid "Spaceship" -msgstr "Vaisseau spatial" - -msgid "Spaceship ruin" -msgstr "Epave de vaisseau spatial" - -msgid "Spider" -msgstr "Araignée" - -msgid "Spider fatally wounded" -msgstr "Araignée mortellement touchée" - -msgid "Stack overflow" -msgstr "Débordement de la pile" - -msgid "Standard action\\Standard action of the bot (take/grab, shoot, sniff, etc)" -msgstr "Action standard\\Action du bouton avec le cadre rouge" - -msgid "Standard controls\\Standard key functions" -msgstr "Tout réinitialiser\\Remet toutes les touches standards" - -msgid "Standard speed\\Reset speed to normal" -msgstr "Vitesse standard\\Réinitialiser la vitesse à la normale" - -msgid "Standard\\Standard appearance settings" -msgstr "Standard\\Remet les couleurs standards" - -msgid "Start" -msgstr "Départ" - -msgid "Starting..." -msgstr "Lancement..." - -msgid "Still working ..." -msgstr "Travail en cours ..." - -msgid "String missing" -msgstr "Une chaîne de caractère est attendue" - -msgid "Strip color:" -msgstr "Couleur des bandes :" - -msgid "Subber" -msgstr "Robot sous-marin" - -msgid "Suit color:" -msgstr "Couleur de la combinaison :" - -msgid "Suit\\Astronaut suit" -msgstr "Corps\\Combinaison" - -msgid "Summary:" -msgstr "Résumé :" - -msgid "Survival kit" -msgstr "Sac de survie" - -msgid "Switch bots <-> buildings" -msgstr "Permute robots <-> bâtiments" - -msgid "Take off to finish the mission" -msgstr "Décolle pour terminer la mission" - -msgid "Target" -msgstr "Cible" - -msgid "Target bot" -msgstr "Cible d'entraînement" - -msgid "Terrain relief" -msgstr "Relief du terrain" - -msgid "Texture filtering\\Texture filtering" -msgstr "Filtrage de textures\\Filtrage de textures" - -msgid "Textures" -msgstr "Textures" - -msgid "The battle has ended" -msgstr "La bataille est terminée" - -msgid "The expression must return a boolean value" -msgstr "L'expression doit être un boolean" - -msgid "The function returned no value" -msgstr "La fonction n'a pas retourné de résultat" - -msgid "The mission is not accomplished yet (press \\key help; for more details)" -msgstr "La mission n'est pas terminée (appuyez sur \\key help; pour plus de détails)" - -msgid "The types of the two operands are incompatible" -msgstr "Les deux opérandes ne sont pas de types compatibles" - -msgid "This class already exists" -msgstr "Cette classe existe déjà" - -msgid "This class does not exist" -msgstr "Cette classe n'existe pas" - -msgid "This is example code that cannot be run directly" -msgstr "Ce code d'exemple ne peut pas être lancé directement" - -msgid "This is not a member of this class" -msgstr "Cet élément n'existe pas dans cette classe" - -msgid "This label does not exist" -msgstr "Cette étiquette n'existe pas" - -msgid "This menu is for userlevels from mods, but you didn't install any" -msgstr "Ce menu donne accès aux niveaux spéciaux (importés ou personnalisés), mais aucun n'est installé." - -msgid "This object is currently busy" -msgstr "Cet élément est actuellement occupé" - -msgid "This object is not a member of a class" -msgstr "L'objet n'est pas une instance d'une classe" - -msgid "This parameter needs a default value" -msgstr "Ce paramètre nécessite une valeur par défaut" - -msgid "This program is read-only, clone it to edit" -msgstr "Ce programme est en lecture-seule, le dupliquer pour pouvoir le modifier" - -msgid "Thump (\\key action;)" -msgstr "Secoue (\\key action;)" - -msgid "Thumper" -msgstr "Robot secoueur" - -#, c-format -msgid "Time: %s" +"X-Generator: Translate Toolkit 1.11.0\n" + +#. type: Title-text +#: ../scene.txt:1 +#, no-wrap +msgid "Massacre" +msgstr "Massacre" + +#. type: Resume-text +#: ../scene.txt:2 +#, no-wrap +msgid "Use a loop in order to destroy six targets." +msgstr "Détruire six cibles à l'aide d'une boucle." + +#. type: ScriptName-text +#: ../scene.txt:3 +#, no-wrap +msgid "Go" +msgstr "Go" + +#. type: \b; header +#: ../help/help.E.txt:1 +#, no-wrap +msgid "Exercise" msgstr "" -msgid "Titanium" -msgstr "Titane" - -msgid "Titanium available" -msgstr "Titane disponible" - -msgid "Titanium deposit (site for derrick)" -msgstr "Emplacement pour un derrick (minerai de titane)" - -msgid "Titanium ore" -msgstr "Minerai de titane" - -msgid "Titanium too close" -msgstr "Titane trop proche" - -msgid "Titanium too far away" -msgstr "Titane trop loin" - -msgid "Too close to a building" -msgstr "Trop proche d'un bâtiment" - -msgid "Too close to an existing flag" -msgstr "Trop proche d'un drapeau existant" - -msgid "Too close to space ship" -msgstr "Trop proche du vaisseau spatial" - -msgid "Too many flags of this color (maximum 5)" -msgstr "Trop de drapeaux de cette couleur (maximum 5)" - -msgid "Too many parameters" -msgstr "Trop de paramètres" - -msgid "Tracked grabber" -msgstr "Robot déménageur à chenilles" - -msgid "Tracked orga shooter" -msgstr "Robot tireur organique à chenilles" - -msgid "Tracked shooter" -msgstr "Robot tireur à chenilles" - -msgid "Tracked sniffer" -msgstr "Robot renifleur à chenilles" - -msgid "Transforms only titanium" -msgstr "Ne transforme que le titane" - -msgid "Transforms only uranium" -msgstr "Ne transforme que le minerai d'uranium" - -msgid "Transmitted information" -msgstr "Informations diffusées" - -msgid "Turn left (\\key left;)" -msgstr "Tourne à gauche (\\key left;)" - -msgid "Turn left\\turns the bot to the left" -msgstr "Tourner à gauche\\Moteur à gauche" - -msgid "Turn right (\\key right;)" -msgstr "Tourne à droite (\\key right;)" - -msgid "Turn right\\turns the bot to the right" -msgstr "Tourner à droite\\Moteur à droite" - -msgid "Type declaration missing" -msgstr "Déclaration de type attendu" - -msgid "Unable to control enemy objects" -msgstr "Impossible de contrôler les objets ennemis" - -msgid "Undo (Ctrl+Z)" -msgstr "Annuler (Ctrl+Z)" - -msgid "Unit" -msgstr "Unité" - -msgid "Unknown Object" -msgstr "Objet inconnu" - -msgid "Unknown command" -msgstr "Commande inconnue" - -msgid "Unknown escape sequence" +#. type: Plain text +#: ../help/help.E.txt:2 +#, no-wrap +msgid "Destroy the six targets with a program using a loop. The bot must move 5m forward to get from one target to the next." msgstr "" -msgid "Unknown function" -msgstr "Routine inconnue" - -msgid "Up (\\key gup;)" -msgstr "Monte (\\key gup;)" - -msgid "Uranium deposit (site for derrick)" -msgstr "Emplacement pour un derrick (minerai d'uranium)" - -msgid "Uranium ore" -msgstr "Minerai d'uranium" - -msgid "User levels" -msgstr "Niveaux supplémentaires" - -msgid "Variable name missing" -msgstr "Nom d'une variable attendu" - -msgid "Variable not declared" -msgstr "Variable non déclarée" - -msgid "Variable not initialized" -msgstr "Variable non initialisée" - -msgid "Vault" -msgstr "Coffre-fort" - -msgid "Violet flag" -msgstr "Drapeau violet" - -msgid "Void parameter" -msgstr "Paramètre void" - -msgid "Wasp" -msgstr "Guêpe" - -msgid "Wasp fatally wounded" -msgstr "Guêpe mortellement touchée" - -msgid "Waste" -msgstr "Déchet" - -msgid "Wheeled grabber" -msgstr "Robot déménageur à roues" - -msgid "Wheeled orga shooter" -msgstr "Robot tireur organique à roues" - -msgid "Wheeled shooter" -msgstr "Robot tireur à roues" - -msgid "Wheeled sniffer" -msgstr "Robot renifleur à roues" - -msgid "Winged grabber" -msgstr "Robot déménageur volant" - -msgid "Winged orga shooter" -msgstr "Robot tireur organique volant" - -msgid "Winged shooter" -msgstr "Robot tireur volant" - -msgid "Winged sniffer" -msgstr "Robot renifleur volant" - -msgid "Withdraw shield (\\key action;)" -msgstr "Refermer le bouclier (\\key action;)" - -msgid "Worm" -msgstr "Ver" - -msgid "Worm fatally wounded" -msgstr "Ver mortellement touché" - -msgid "Wreckage" -msgstr "Epave de robot" - -msgid "Write error" -msgstr "Erreur lors de l'écriture" - -msgid "Wrong type for the assignment" -msgstr "Mauvais type de résultat pour l'assignation" - -msgid "Yellow flag" -msgstr "Drapeau jaune" - -msgid "Yes" -msgstr "Oui" - -msgid "You can fly with the keys (\\key gup;) and (\\key gdown;)" -msgstr "Il est possible de voler avec les touches (\\key gup;) et (\\key gdown;)" - -msgid "You can not carry a radioactive object" -msgstr "Vous ne pouvez pas transporter un objet radioactif" - -msgid "You can not carry an object under water" -msgstr "Vous ne pouvez pas transporter un objet sous l'eau" - -#, c-format -msgid "You cannot use \"%s\" in this exercise (used: %d)" -msgstr "Vous ne pouvez pas utiliser «%s» dans cet exercice (utilisé : %d)" - -msgid "You found a usable object" -msgstr "Vous avez trouvé un objet utilisable" - -#, c-format -msgid "You have to use \"%1$s\" at least once in this exercise (used: %2$d)" -msgid_plural "You have to use \"%1$s\" at least %3$d times in this exercise (used: %2$d)" -msgstr[0] "Vous devez utiliser «%1$s» au moins une fois dans cet exercice (utilisé %2$d fois)" -msgstr[1] "Vous devez utiliser «%1$s» au moins %3$d fois dans cet exercice (utilisé %2$d fois)" - -#, c-format -msgid "You have to use \"%1$s\" at most once in this exercise (used: %2$d)" -msgid_plural "You have to use \"%1$s\" at most %3$d times in this exercise (used: %2$d)" -msgstr[0] "Vous devez utiliser «%1$s» au plus une fois dans cet exercice (utilisé %2$d fois)" -msgstr[1] "Vous devez utiliser «%1$s» au plus %3$d fois dans cet exercice (utilisé %2$d fois)" - -msgid "You must get on the spaceship to take off" -msgstr "Vous devez embarquer pour pouvoir décoller" - -msgid "Zoom mini-map" -msgstr "Zoom mini-carte" - -msgid "\\Blue flags" -msgstr "\\Drapeaux bleus" - -msgid "\\Eyeglasses 1" -msgstr "\\Lunettes 1" - -msgid "\\Eyeglasses 2" -msgstr "\\Lunettes 2" - -msgid "\\Eyeglasses 3" -msgstr "\\Lunettes 3" - -msgid "\\Eyeglasses 4" -msgstr "\\Lunettes 4" - -msgid "\\Eyeglasses 5" -msgstr "\\Lunettes 5" - -msgid "\\Face 1" -msgstr "\\Visage 1" - -msgid "\\Face 2" -msgstr "\\Visage 2" - -msgid "\\Face 3" -msgstr "\\Visage 3" - -msgid "\\Face 4" -msgstr "\\Visage 4" - -msgid "\\Green flags" -msgstr "\\Drapeaux verts" - -msgid "\\New player name" -msgstr "\\Nom du joueur à créer" - -msgid "\\No eyeglasses" -msgstr "\\Pas de lunettes" - -msgid "\\Raise the pencil" -msgstr "\\Relève le crayon" - -msgid "\\Red flags" -msgstr "\\Drapeaux rouges" - -msgid "\\Return to Colobot: Gold Edition" -msgstr "\\Revenir à Colobot : Édition Gold" - -msgid "\\SatCom on standby" -msgstr "\\Mettre le SatCom en veille" - -msgid "\\Start recording" -msgstr "\\Démarre l'enregistrement" - -msgid "\\Stop recording" -msgstr "\\Stoppe l'enregistrement" - -msgid "\\Turn left" -msgstr "\\Rotation à gauche" - -msgid "\\Turn right" -msgstr "\\Rotation à droite" - -msgid "\\Use the black pencil" -msgstr "\\Abaisse le crayon noir" - -msgid "\\Use the blue pencil" -msgstr "\\Abaisse le crayon bleu" - -msgid "\\Use the brown pencil" -msgstr "\\Abaisse le crayon brun" - -msgid "\\Use the green pencil" -msgstr "\\Abaisse le crayon vert" - -msgid "\\Use the orange pencil" -msgstr "\\Abaisse le crayon orange" - -msgid "\\Use the purple pencil" -msgstr "\\Abaisse le crayon violet" - -msgid "\\Use the red pencil" -msgstr "\\Abaisse le crayon rouge" - -msgid "\\Use the yellow pencil" -msgstr "\\Abaisse le crayon jaune" - -msgid "\\Violet flags" -msgstr "\\Drapeaux violets" - -msgid "\\Yellow flags" -msgstr "\\Drapeaux jaunes" - -msgid "colobot.info" -msgstr "colobot.info" - -msgid "epsitec.com" -msgstr "epsitec.com" - -#~ msgid " " -#~ msgstr " " - -#~ msgid " Drivers:" -#~ msgstr " Pilotes :" - -#~ msgid " Missions on this level:" -#~ msgstr " Missions du niveau :" - -#~ msgid "\"%s\" missing in this exercise" -#~ msgstr "Il manque \"%s\" dans le programme" - -#~ msgid "3D sound\\3D positioning of the sound" -#~ msgstr "Bruitages 3D\\Positionnement sonore dans l'espace" - -#~ msgid "Building too close" -#~ msgstr "Bâtiment trop proche" - -#~ msgid "COLOBOT" -#~ msgstr "COLOBOT" - -#~ msgid "Camera awayest" -#~ msgstr "Caméra plus loin" - -#~ msgid "Camera down\\Decrease camera angle while visiting message origin" -#~ msgstr "Caméra plus basse\\Réduit l'angle de caméra lors de la vue de l'origine des messages" - -#~ msgid "Camera nearest" -#~ msgstr "Caméra plus proche" - -#~ msgid "Camera to left" -#~ msgstr "Caméra à gauche" - -#~ msgid "Camera to right" -#~ msgstr "Caméra à droite" - -#~ msgid "Camera up\\Increase camera angle while visiting message origin" -#~ msgstr "Caméra plus haute\\Augmente l'angle de caméra lors de la vue de l'origine des messages" - -#~ msgid "Can not create this; there are too many objects" -#~ msgstr "Création impossible; il y a trop d'objets" - -#~ msgid "Cancel\\Keep current player name" -#~ msgstr "Annuler\\Conserver le joueur actuel" - -#~ msgid "Checkpoint crossed" -#~ msgstr "Indicateur atteint" - -#~ msgid "Compass" -#~ msgstr "Boussole" - -#~ msgid "Continue\\Continue the game" -#~ msgstr "Continuer\\Continuer de jouer" - -#~ msgid "Delete" -#~ msgstr "Détruire" - -#~ msgid "Details\\Visual quality of 3D objects" -#~ msgstr "Détails des objets\\Qualité des objets en 3D" - -#~ msgid "Developed by :" -#~ msgstr "Développé par :" - -#~ msgid "Do you want to quit Colobot: Gold Edition?" -#~ msgstr "Voulez-vous quitter Colobot: Édition Gold ?" - -#~ msgid "Exit film\\Film at the exit of exercises" -#~ msgstr "Retour animé\\Retour animé dans les exercices" - -#~ msgid "Friendly fire\\Your shooting can damage your own objects " -#~ msgstr "Dégâts à soi-même\\Vos tirs infligent des dommages à vos unités" - -#~ msgid "Ground inappropriate" -#~ msgstr "Terrain inadapté" - -#~ msgid "Key word help\\More detailed help about key words" -#~ msgstr "Instructions mot-clé\\Explication sur le mot-clé" - -#~ msgid "Marks on the ground\\Marks on the ground" -#~ msgstr "Marques sur le sol\\Marques dessinées sur le sol" - -#~ msgid "Mouse shadow\\Gives the mouse a shadow" -#~ msgstr "Souris ombrée\\Jolie souris avec une ombre" - -#~ msgid "No other robot" -#~ msgstr "Pas d'autre robot" - -#~ msgid "Not yet enough energy" -#~ msgstr "Pas encore assez d'énergie" - -#~ msgid "Num of decorative objects\\Number of purely ornamental objects" -#~ msgstr "Nb d'objets décoratifs\\Qualité d'objets non indispensables" - -#~ msgid "Planets and stars\\Astronomical objects in the sky" -#~ msgstr "Planètes et étoiles\\Motifs mobiles dans le ciel" - -#~ msgid "Quit the mission?" -#~ msgstr "Quitter la mission ?" - -#~ msgid "Quit\\Quit COLOBOT" -#~ msgstr "Quitter\\Quitter COLOBOT" - -#~ msgid "Robbie\\Your assistant" -#~ msgstr "Robbie\\Votre assistant" - -#~ msgid "Sky\\Clouds and nebulae" -#~ msgstr "Ciel\\Ciel et nuages" - -#~ msgid "Speed 0.5x\\Half speed" -#~ msgstr "Vitesse 0.5x\\Demi-vitesse" - -#~ msgid "Speed 1.0x\\Normal speed" -#~ msgstr "Vitesse 1.0x\\Vitesse normale" - -#~ msgid "Speed 1.5x\\1.5 times faster" -#~ msgstr "Vitesse 1.5x\\Une fois et demi plus rapide" - -#~ msgid "Speed 3.0x\\Three times faster" -#~ msgstr "Vitesse 3.0x\\Trois fois plus rapide" - -#~ msgid "Speed 3.0x\\Triple speed" -#~ msgstr "Vitesse 3.0x\\Trois fois plus rapide " - -#~ msgid "Speed 4.0x\\Quadruple speed" -#~ msgstr "Vitesse 4.0x\\Quatre fois plus rapide" - -#~ msgid "Speed 6.0x\\Sextuple speed" -#~ msgstr "Vitesse 6.0x\\Six fois plus rapide" - -#~ msgid "Sunbeams\\Sunbeams in the sky" -#~ msgstr "Rayons du soleil\\Rayons selon l'orientation" - -#~ msgid "System mouse\\Use system mouse cursor" -#~ msgstr "Souris système\\Utiliser le curseur de la souris système" - -#~ msgid "Textures\\Quality of textures " -#~ msgstr "Qualité des textures\\Qualité des images" - -#~ msgid "The list is only available if a \\l;radar station\\u object\\radar; is working.\n" -#~ msgstr "Liste non disponible sans \\l;radar\\u object\\radar;.\n" - -#~ msgid "Use a joystick\\Joystick or keyboard" -#~ msgstr "Utilise un joystick\\Joystick ou clavier" - -#~ msgid "User\\User levels" -#~ msgstr "Suppl.\\Niveaux supplémentaires" - -#~ msgid "\\Return to COLOBOT" -#~ msgstr "\\Retourner dans COLOBOT" - -#~ msgid "\\b;Aliens\n" -#~ msgstr "\\b;Listes des ennemis\n" - -#~ msgid "\\b;Buildings\n" -#~ msgstr "\\b;Listes des bâtiments\n" - -#~ msgid "\\b;Error\n" -#~ msgstr "\\b;Erreur\n" - -#~ msgid "\\b;List of objects\n" -#~ msgstr "\\b;Listes des objets\n" - -#~ msgid "\\b;Moveable objects\n" -#~ msgstr "\\b;Listes des objets transportables\n" - -#~ msgid "\\b;Robots\n" -#~ msgstr "\\b;Listes des robots\n" - -#~ msgid "\\c; (none)\\n;\n" -#~ msgstr "\\c; (aucun)\\n;\n" +#. type: \b; header +#: ../help/help.E.txt:4 +#, no-wrap +msgid "General principle" +msgstr "" + +#. type: Plain text +#: ../help/help.E.txt:5 +#, no-wrap +msgid "" +"The program must execute the following scheme:\n" +"Repeat 6 times :" +msgstr "" + +#. type: Bullet: 'o' +#: ../help/help.E.txt:7 +#, no-wrap +msgid "move 5m forward" +msgstr "" + +#. type: Bullet: 'o' +#: ../help/help.E.txt:8 +#, no-wrap +msgid "turn 90 degrees left" +msgstr "" + +#. type: Bullet: 'o' +#: ../help/help.E.txt:9 +#, no-wrap +msgid "shoot" +msgstr "" + +#. type: Bullet: 'o' +#: ../help/help.E.txt:10 +#, no-wrap +msgid "turn 90 degrees right" +msgstr "" + +#. type: Image filename +#: ../help/help.E.txt:12 +#, no-wrap +msgid "tfor1" +msgstr "" + +#. type: \b; header +#: ../help/help.E.txt:13 +#, no-wrap +msgid "Instruction for ( )" +msgstr "" + +#. type: Plain text +#: ../help/help.E.txt:14 +#, no-wrap +msgid "The instruction for asks for 3 expressions:" +msgstr "" + +#. type: Bullet: '1)' +#: ../help/help.E.txt:15 +#, no-wrap +msgid "Initialize the counting variable." +msgstr "" + +#. type: Bullet: '2)' +#: ../help/help.E.txt:16 +#, no-wrap +msgid "The end condition." +msgstr "" + +#. type: Bullet: '3)' +#: ../help/help.E.txt:17 +#, no-wrap +msgid "The counting expression." +msgstr "" + +#. type: Plain text +#: ../help/help.E.txt:19 +#, no-wrap +msgid "Here is the loop once it is integrated into the program frame:" +msgstr "" + +#. type: Source code +#: ../help/help.E.txt:20 +#, no-wrap +msgid "" +"extern void object::Massacre( )\n" +"{\n" +"\tfor ( int i=0 ; i<6 ; i=i+1 )\n" +"\t{\n" +"\t\tinstructions repeated 6 times ...\n" +"\t}\n" +"}" +msgstr "" + +#. type: Plain text +#: ../help/help.E.txt:28 +#, no-wrap +msgid "ATTENTION: The line for ( ) must not be followed by a semicolon !" +msgstr "" + +#. type: \b; header +#: ../help/help.E.txt:30 +#, no-wrap +msgid "Explanation of the instruction for ( )" +msgstr "" + +#. type: Bullet: '1)' +#: ../help/help.E.txt:31 +#, no-wrap +msgid "int i=0" +msgstr "" + +#. type: Plain text +#: ../help/help.E.txt:32 +#, no-wrap +msgid " The variable i is set to zero before the beginning of the loop." +msgstr "" + +#. type: Bullet: '2)' +#: ../help/help.E.txt:34 +#, no-wrap +msgid "i<6" +msgstr "" + +#. type: Plain text +#: ../help/help.E.txt:35 +#, no-wrap +msgid " The loop will be executed as long as i is smaller than 6." +msgstr "" + +#. type: Bullet: '3)' +#: ../help/help.E.txt:37 +#, no-wrap +msgid "i=i+1" +msgstr "" + +#. type: Plain text +#: ../help/help.E.txt:38 +#, no-wrap +msgid " At the end of every loop, add 1 to the variable i." +msgstr "" + +#. type: \b; header +#: ../help/help.E.txt:40 +#, no-wrap +msgid "Blocks" +msgstr "" + +#. type: Plain text +#: ../help/help.E.txt:41 +#, no-wrap +msgid "Use braces { } in order to create a block. All the instructions that must be executed in the for loop are held together by a block. The whole program itself is made up of a block:" +msgstr "" + +#. type: Source code +#: ../help/help.E.txt:43 +#, no-wrap +msgid "" +"extern void object::massacre( )\n" +"{\n" +"\tfill in here ...\n" +"}" +msgstr "" + +#. type: Plain text +#: ../help/help.E.txt:48 +#, no-wrap +msgid "" +"Never change these characters. Just add the instructions of the program between the braces.\n" +"You can fit several blocks one into the other. For example the for block is fitted into the block of the whole program. In order to improve readability, the editor lines up the braces belonging to the different blocks." +msgstr "" + +#. type: \b; header +#: ../help/help.E.txt:51 +#, no-wrap +msgid "Remember" +msgstr "" + +#. type: Plain text +#: ../help/help.E.txt:52 +#, no-wrap +msgid "" +"The instruction used to move forward is move();.\n" +"The instruction used to turn the bot is turn();. A positive angle turns left.\n" +"The instruction used to fire the cannon is fire(1);. A one-second burst allows to destroy all six targets." +msgstr "" + +#. type: \t; header +#: ../help/help.E.txt:56 +#, no-wrap +msgid "See also" +msgstr "" + +#. type: Plain text +#: ../help/help.E.txt:57 +#, no-wrap +msgid "Programming, types and categories." +msgstr "" From 634248885fecd2ec2d3c6cefcec3fb8a010c1541 Mon Sep 17 00:00:00 2001 From: maf-ia Date: Sat, 12 Jan 2019 21:35:51 +0100 Subject: [PATCH 078/109] Complete last 5 french sentences not fully translated --- po/fr.po | 2210 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 2008 insertions(+), 202 deletions(-) diff --git a/po/fr.po b/po/fr.po index a216620b..36fc2a26 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1,245 +1,2051 @@ -# SOME DESCRIPTIVE TITLE -# Copyright (C) YEAR Free Software Foundation, Inc. -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. +# Didier Raboud , 2012, 2015, 2016. +# Martin Quinson , 2016 +# B-CE, 2018 +# Pascal Audoux , 2018 msgid "" msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" +"Project-Id-Version: Colobot 0.1.11\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: DATE\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" +"PO-Revision-Date: 2019-01-09 23:07+0100\n" +"Last-Translator: B-CE\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Translate Toolkit 1.11.0\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 2.0.6\n" +"X-Language: fr_FR\n" +"X-Source-Language: en_US\n" +"Language-Team: \n" -#. type: Title-text -#: ../scene.txt:1 -#, no-wrap -msgid "Massacre" -msgstr "Massacre" +msgid " or " +msgstr " ou " -#. type: Resume-text -#: ../scene.txt:2 -#, no-wrap -msgid "Use a loop in order to destroy six targets." -msgstr "Détruire six cibles à l'aide d'une boucle." +msgid "\" [ \" expected" +msgstr "\" [ \" attendu" -#. type: ScriptName-text -#: ../scene.txt:3 -#, no-wrap -msgid "Go" -msgstr "Go" +msgid "\" ] \" missing" +msgstr "\" ] \" manquant" -#. type: \b; header -#: ../help/help.E.txt:1 -#, no-wrap -msgid "Exercise" -msgstr "" +#, c-format +msgid "%s: %d pts" +msgstr "%s: %d points" -#. type: Plain text -#: ../help/help.E.txt:2 -#, no-wrap -msgid "Destroy the six targets with a program using a loop. The bot must move 5m forward to get from one target to the next." -msgstr "" +msgid "..behind" +msgstr "..derrière" -#. type: \b; header -#: ../help/help.E.txt:4 -#, no-wrap -msgid "General principle" -msgstr "" +msgid "..in front" +msgstr "..devant" -#. type: Plain text -#: ../help/help.E.txt:5 -#, no-wrap -msgid "" -"The program must execute the following scheme:\n" -"Repeat 6 times :" -msgstr "" +msgid "..power cell" +msgstr "..pile" -#. type: Bullet: 'o' -#: ../help/help.E.txt:7 -#, no-wrap -msgid "move 5m forward" -msgstr "" +msgid "1) First click on the key you want to redefine." +msgstr "1) Cliquez d'abord sur la touche à redéfinir." -#. type: Bullet: 'o' -#: ../help/help.E.txt:8 -#, no-wrap -msgid "turn 90 degrees left" -msgstr "" +msgid "2) Then press the key you want to use instead." +msgstr "2) Appuyez ensuite sur la nouvelle touche souhaitée." -#. type: Bullet: 'o' -#: ../help/help.E.txt:9 -#, no-wrap -msgid "shoot" -msgstr "" +msgid "<< Back \\Back to the previous screen" +msgstr "<< Retour \\Retour au niveau précédent" -#. type: Bullet: 'o' -#: ../help/help.E.txt:10 -#, no-wrap -msgid "turn 90 degrees right" -msgstr "" +msgid "<<< Sorry; mission failed >>>" +msgstr "<<< Désolé; mission échouée >>>" -#. type: Image filename -#: ../help/help.E.txt:12 -#, no-wrap -msgid "tfor1" -msgstr "" +#, c-format +msgid "<<< Team %s finished! >>>" +msgstr "<<< L'équipe %s a terminé! >>>" -#. type: \b; header -#: ../help/help.E.txt:13 -#, no-wrap -msgid "Instruction for ( )" -msgstr "" +#, c-format +msgid "<<< Team %s lost! >>>" +msgstr "<<< L'équipe %s a perdu! >>>" -#. type: Plain text -#: ../help/help.E.txt:14 -#, no-wrap -msgid "The instruction for asks for 3 expressions:" -msgstr "" +#, c-format +msgid "<<< Team %s recieved %d points >>>" +msgstr "<<< L'équipe %s a reçu %d points >>>" -#. type: Bullet: '1)' -#: ../help/help.E.txt:15 -#, no-wrap -msgid "Initialize the counting variable." -msgstr "" +msgid "<<< Well done; mission accomplished >>>" +msgstr "<<< Bravo; mission terminée >>>" -#. type: Bullet: '2)' -#: ../help/help.E.txt:16 -#, no-wrap -msgid "The end condition." -msgstr "" +msgid "A label must be followed by \"for\"; \"while\"; \"do\" or \"switch\"" +msgstr "Un label ne peut se placer que devant un \"for\"; un \"while\"; un \"do\" ou un \"switch\"" -#. type: Bullet: '3)' -#: ../help/help.E.txt:17 -#, no-wrap -msgid "The counting expression." -msgstr "" +msgid "A variable can not be declared twice" +msgstr "Redéfinition d'une variable" -#. type: Plain text -#: ../help/help.E.txt:19 -#, no-wrap -msgid "Here is the loop once it is integrated into the program frame:" -msgstr "" +msgid "Abort\\Abort the current mission" +msgstr "Abandonner\\Abandonner la mission en cours" -#. type: Source code -#: ../help/help.E.txt:20 -#, no-wrap -msgid "" -"extern void object::Massacre( )\n" -"{\n" -"\tfor ( int i=0 ; i<6 ; i=i+1 )\n" -"\t{\n" -"\t\tinstructions repeated 6 times ...\n" -"\t}\n" -"}" -msgstr "" +msgid "Access beyond array limit" +msgstr "Accès hors du tableau" -#. type: Plain text -#: ../help/help.E.txt:28 -#, no-wrap -msgid "ATTENTION: The line for ( ) must not be followed by a semicolon !" -msgstr "" +msgid "Access to solution\\Shows the solution (detailed instructions for missions)" +msgstr "Accès à la solution\\Donne la solution (instructions détaillées pour la mission)" -#. type: \b; header -#: ../help/help.E.txt:30 -#, no-wrap -msgid "Explanation of the instruction for ( )" -msgstr "" +msgid "Access to solutions\\Show program \"4: Solution\" in the exercises" +msgstr "Accès aux solutions\\Programme \"4: Solution\" dans les exercices" -#. type: Bullet: '1)' -#: ../help/help.E.txt:31 -#, no-wrap -msgid "int i=0" -msgstr "" +msgid "Add new program" +msgstr "Ajouter un nouveau programme" -#. type: Plain text -#: ../help/help.E.txt:32 -#, no-wrap -msgid " The variable i is set to zero before the beginning of the loop." -msgstr "" +msgid "Alien Queen" +msgstr "Pondeuse" -#. type: Bullet: '2)' -#: ../help/help.E.txt:34 -#, no-wrap -msgid "i<6" -msgstr "" +msgid "Alien Queen killed" +msgstr "Pondeuse mortellement touchée" -#. type: Plain text -#: ../help/help.E.txt:35 -#, no-wrap -msgid " The loop will be executed as long as i is smaller than 6." -msgstr "" +msgid "Already carrying something" +msgstr "Porte déjà quelque chose" -#. type: Bullet: '3)' -#: ../help/help.E.txt:37 -#, no-wrap -msgid "i=i+1" -msgstr "" +msgid "Alternative camera mode\\Move sideways instead of rotating (in free camera)" +msgstr "Mode caméra alternatif\\Déplacements latéraux au lieu des rotations (pour une caméra libre)" -#. type: Plain text -#: ../help/help.E.txt:38 -#, no-wrap -msgid " At the end of every loop, add 1 to the variable i." -msgstr "" +msgid "Ambiguous call to overloaded function" +msgstr "Appel ambigu à une fonction surchargée" -#. type: \b; header -#: ../help/help.E.txt:40 -#, no-wrap -msgid "Blocks" -msgstr "" +msgid "Analysis already performed" +msgstr "Analyse déjà effectuée" -#. type: Plain text -#: ../help/help.E.txt:41 -#, no-wrap -msgid "Use braces { } in order to create a block. All the instructions that must be executed in the for loop are held together by a block. The whole program itself is made up of a block:" -msgstr "" +msgid "Analysis performed" +msgstr "Analyse terminée" -#. type: Source code -#: ../help/help.E.txt:43 -#, no-wrap -msgid "" -"extern void object::massacre( )\n" -"{\n" -"\tfill in here ...\n" -"}" -msgstr "" +msgid "Analyzes only organic matter" +msgstr "N'analyse que la matière organique" -#. type: Plain text -#: ../help/help.E.txt:48 -#, no-wrap -msgid "" -"Never change these characters. Just add the instructions of the program between the braces.\n" -"You can fit several blocks one into the other. For example the for block is fitted into the block of the whole program. In order to improve readability, the editor lines up the braces belonging to the different blocks." -msgstr "" +msgid "Anisotropy level\\Anisotropy level" +msgstr "Niveau d'anisotropie\\Niveau d'anisotropie" -#. type: \b; header -#: ../help/help.E.txt:51 -#, no-wrap -msgid "Remember" -msgstr "" +msgid "Ant" +msgstr "Fourmi" -#. type: Plain text -#: ../help/help.E.txt:52 -#, no-wrap -msgid "" -"The instruction used to move forward is move();.\n" -"The instruction used to turn the bot is turn();. A positive angle turns left.\n" -"The instruction used to fire the cannon is fire(1);. A one-second burst allows to destroy all six targets." -msgstr "" +msgid "Ant fatally wounded" +msgstr "Fourmi mortellement touchée" -#. type: \t; header -#: ../help/help.E.txt:56 -#, no-wrap -msgid "See also" -msgstr "" +msgid "Appearance\\Choose your appearance" +msgstr "Aspect\\Choisir votre aspect" -#. type: Plain text -#: ../help/help.E.txt:57 -#, no-wrap -msgid "Programming, types and categories." -msgstr "" +msgid "Apply changes\\Activates the changed settings" +msgstr "Appliquer les changements\\Active les changements effectués" + +msgid "Appropriate constructor missing" +msgstr "Constructeur approprié manquant" + +msgid "Assignment impossible" +msgstr "Assignation impossible" + +msgid "Autolab" +msgstr "Laboratoire d'analyse de matières organiques" + +msgid "Automatic indent\\When program editing" +msgstr "Indentation automatique\\Pendant l'édition d'un programme" + +msgid "Autosave interval\\How often your game will autosave" +msgstr "Interval d'auto-sauvegarde\\À quels intervals les parties vont-t-elles êtres sauvegardées automatiquement" + +msgid "Autosave slots\\How many autosave slots you'll have" +msgstr "Nombre d'auto-sauvegardes\\Combien d'auto-sauvegarde seront conservées" + +msgid "Autosave\\Enables autosave" +msgstr "Auto-sauvegarde\\Activer l'auto-sauvegarde" + +msgid "Back" +msgstr "Page précédente" + +msgid "Background sound:\\Volume of audio tracks" +msgstr "Fond sonore :\\Volume des pistes audio" + +msgid "Backward (\\key down;)" +msgstr "Recule (\\key down;)" + +msgid "Backward\\Moves backward" +msgstr "Reculer\\Se déplacer en arrière" + +msgid "Bad argument for \"new\"" +msgstr "Mauvais argument pour \"new\"" + +msgid "Big indent\\Indent 2 or 4 spaces per level defined by braces" +msgstr "Grande indentation\\Indente avec 2 ou 4 espaces par niveau" + +msgid "Black box" +msgstr "Boîte noire" + +msgid "Blood\\Display blood when the astronaut is hit" +msgstr "Sang\\Afficher du sang quand le cosmonaute est touché" + +msgid "Blue" +msgstr "Bleue" + +# tocheck : for team (fem): bleue +# tocheck : for flag/pen/bot (masc): bleu +# + capital also to check +msgid "Blue flag" +msgstr "Drapeau bleu" + +msgid "Bot destroyed" +msgstr "Robot détruit" + +msgid "Bot factory" +msgstr "Fabrique de robots" + +msgid "Build a bot factory" +msgstr "Construire une fabrique de robots" + +msgid "Build a converter" +msgstr "Construire un convertisseur" + +msgid "Build a defense tower" +msgstr "Construire une tour" + +msgid "Build a derrick" +msgstr "Construire un derrick" + +msgid "Build a destroyer" +msgstr "Construire un destructeur" + +msgid "Build a exchange post" +msgstr "Construire une borne d'information" + +msgid "Build a legged grabber" +msgstr "Fabriquer un déménageur à pattes" + +msgid "Build a legged orga shooter" +msgstr "Fabriquer un tireur organique à pattes" + +msgid "Build a legged shooter" +msgstr "Fabriquer un tireur à pattes" + +msgid "Build a legged sniffer" +msgstr "Fabriquer un renifleur à pattes" + +msgid "Build a lightning conductor" +msgstr "Construire un paratonnerre" + +msgid "Build a nuclear power plant" +msgstr "Construire une centrale nucléaire" + +msgid "Build a phazer shooter" +msgstr "Fabriquer un robot canon à phases" + +msgid "Build a power cell factory" +msgstr "Construire une fabrique de piles" + +msgid "Build a power station" +msgstr "Construire une station de recharge" + +msgid "Build a radar station" +msgstr "Construire un radar" + +msgid "Build a recycler" +msgstr "Fabriquer un robot recycleur" + +msgid "Build a repair center" +msgstr "Construire un centre de réparation" + +msgid "Build a research center" +msgstr "Construire un centre de recherches" + +msgid "Build a shielder" +msgstr "Fabriquer un robot bouclier" + +msgid "Build a subber" +msgstr "Fabriquer un robot sous-marin" + +msgid "Build a thumper" +msgstr "Fabriquer un robot secoueur" + +msgid "Build a tracked grabber" +msgstr "Fabriquer un déménageur à chenilles" + +msgid "Build a tracked orga shooter" +msgstr "Fabriquer un tireur organique à chenilles" + +msgid "Build a tracked shooter" +msgstr "Fabriquer un tireur à chenilles" + +msgid "Build a tracked sniffer" +msgstr "Fabriquer un renifleur à chenilles" + +msgid "Build a wheeled grabber" +msgstr "Fabriquer un déménageur à roues" + +msgid "Build a wheeled orga shooter" +msgstr "Fabriquer un tireur organique à roues" + +msgid "Build a wheeled shooter" +msgstr "Fabriquer un tireur à roues" + +msgid "Build a wheeled sniffer" +msgstr "Fabriquer un renifleur à roues" + +msgid "Build a winged grabber" +msgstr "Fabriquer un déménageur volant" + +msgid "Build a winged orga shooter" +msgstr "Fabriquer un tireur organique volant" + +msgid "Build a winged shooter" +msgstr "Fabriquer un tireur volant" + +msgid "Build a winged sniffer" +msgstr "Fabriquer un renifleur volant" + +msgid "Build an autolab" +msgstr "Construire un laboratoire d'analyse de matières organiques" + +msgid "Building completed" +msgstr "Bâtiment terminé" + +msgid "Building destroyed" +msgstr "Bâtiment détruit" + +msgid "Button %1" +msgstr "Bouton %1" + +msgid "Calling an unknown function" +msgstr "Appel d'une fonction inexistante" + +msgid "Camera (\\key camera;)" +msgstr "Caméra (\\key camera;)" + +msgid "Camera back\\Moves the camera backward" +msgstr "Caméra plus loin\\Recule la caméra" + +msgid "Camera border scrolling\\Scrolling when the mouse touches right or left border" +msgstr "Défilement dans les bords\\Défilement lorsque la souris touche les bords gauche ou droite" + +msgid "Camera closer\\Moves the camera forward" +msgstr "Caméra plus proche\\Avance la caméra" + +msgid "Camera down\\Turns the camera down" +msgstr "Baisser caméra\\Baisse la caméra" + +msgid "Camera left\\Turns the camera left" +msgstr "Caméra à gauche\\Tourne la caméra vers la gauche" + +msgid "Camera right\\Turns the camera right" +msgstr "Caméra à droite\\Tourne la caméra vers la droite" + +msgid "Camera up\\Turns the camera up" +msgstr "Lever caméra\\Monte la caméra" + +msgid "Can not produce not researched object" +msgstr "Impossible de créer un objet n'ayant pas été recherché" + +msgid "Can not produce this object in this mission" +msgstr "Impossible de créer cet objet dans cette mission" + +msgid "Can't open file" +msgstr "Ouverture du fichier impossible" + +msgid "Cancel" +msgstr "Annuler" + +msgid "Cancel\\Cancel all changes" +msgstr "Annuler\\Annuler toutes les modifications" + +msgid "Challenges" +msgstr "Défis" + +msgid "Challenges in the chapter:" +msgstr "Liste des défis du chapitre :" + +msgid "Challenges\\Programming challenges" +msgstr "Défis\\Défis de programmation" + +msgid "Change camera\\Switches between onboard camera and following camera" +msgstr "Changement de caméra\\Autre de point de vue" + +msgid "Change player\\Change player" +msgstr "Autre joueur\\Choix du nom du joueur" + +msgid "Chapters:" +msgstr "Liste des chapitres :" + +msgid "Cheat console\\Show cheat console" +msgstr "Console de triche\\Montre la console de triche" + +msgid "Checkpoint" +msgstr "Indicateur" + +msgid "Class name expected" +msgstr "Nom de classe attendu" + +msgid "Climb\\Increases the power of the jet" +msgstr "Monter\\Augmenter la puissance du réacteur" + +msgid "Clone program" +msgstr "Dupliquer le programme" + +msgid "Clone selected program" +msgstr "Dupliquer le programme sélectionné" + +msgid "Close" +msgstr "Fermer" + +msgid "Closing bracket missing" +msgstr "Il manque une parenthèse fermante" + +msgid "Code battle" +msgstr "Bataille de code" + +msgid "Code battles" +msgstr "Batailles de code" + +msgid "Code battles\\Program your robot to be the best of them all!" +msgstr "Batailles de code\\Programmez votre robot pour être le meilleur entre tous!" + +msgid "Colobot rules!" +msgstr "Colobot est super!" + +msgid "Colobot: Gold Edition" +msgstr "Colobot: Édition Gold" + +msgid "Command line" +msgstr "Console de commande" + +msgid "Compilation ok (0 errors)" +msgstr "Compilation ok (0 erreur)" + +msgid "Compile" +msgstr "Compiler" + +msgid "Continue" +msgstr "Continuer" + +msgid "Continue\\Continue the current mission" +msgstr "Continuer\\Continuer la mission en cours" + +msgid "Controls\\Keyboard, joystick and mouse settings" +msgstr "Commandes\\Touches du clavier" + +msgid "Converts ore to titanium" +msgstr "Conversion de minerai en titane" + +msgid "Copy" +msgstr "Copier" + +msgid "Copy (Ctrl+C)" +msgstr "Copier (Ctrl+C)" + +msgid "Current mission saved" +msgstr "Enregistrement effectué" + +msgid "Custom levels:" +msgstr "Niveaux spéciaux :" + +msgid "Custom levels\\Levels from mods created by the users" +msgstr "Niveaux spéciaux\\Niveaux importés ou personnalisés" + +msgid "Customize your appearance" +msgstr "Personnalisation de votre apparence" + +msgid "Cut (Ctrl+X)" +msgstr "Couper (Ctrl+X)" + +msgid "Defense tower" +msgstr "Tour de défense" + +msgid "Delete mark" +msgstr "Supprimer la marque" + +msgid "Delete player\\Deletes the player from the list" +msgstr "Supprimer le joueur\\Supprimer le joueur de la liste" + +msgid "Delete\\Deletes the selected file" +msgstr "Supprimer\\Supprime l'enregistrement sélectionné" + +msgid "Derrick" +msgstr "Derrick" + +msgid "Descend\\Reduces the power of the jet" +msgstr "Descendre\\Diminuer la puissance du réacteur" + +msgid "Destroy" +msgstr "Détruire" + +msgid "Destroy the building" +msgstr "Démolit le bâtiment" + +msgid "Destroyer" +msgstr "Destructeur" + +msgid "Device\\Driver and resolution settings" +msgstr "Affichage\\Pilote et résolution d'affichage" + +msgid "Dividing by zero" +msgstr "Division par zéro" + +msgid "Do you really want to destroy the selected building?" +msgstr "Voulez-vous vraiment détruire le bâtiment sélectionné ?" + +#, c-format +msgid "Do you want to delete %s's saved games?" +msgstr "Voulez-vous détruire les sauvegardes de %s ?" + +msgid "Doors blocked by a robot or another object" +msgstr "Portes bloquées par un robot ou un objet" + +msgid "Down (\\key gdown;)" +msgstr "Descend (\\key gdown;)" + +msgid "Drawer bot" +msgstr "Robot dessinateur" + +msgid "Dust\\Dust and dirt on bots and buildings" +msgstr "Salissures\\Salissures des robots et bâtiments" + +msgid "Dynamic lighting\\Mobile light sources" +msgstr "Lumières dynamiques\\Éclairages mobiles" + +msgid "Dynamic shadows ++\\Dynamic shadows + self shadowing" +msgstr "Ombres dynamiques ++\\Active les ombres dynamiques et l'auto-ombrage" + +msgid "Dynamic shadows\\Beautiful shadows!" +msgstr "Ombres dynamiques\\Magnifiques ombres !" + +msgid "Edit the selected program" +msgstr "Éditer le programme sélectionné" + +msgid "Egg" +msgstr "Oeuf" + +msgid "End of block missing" +msgstr "Il manque la fin du bloc" + +msgid "Energy deposit (site for power station)" +msgstr "Emplacement pour une station de recharge ou une fabrique de pile" + +msgid "Energy level" +msgstr "Niveau d'énergie" + +msgid "Engineer" +msgstr "Technicien" + +msgid "Error in instruction move" +msgstr "Déplacement impossible" + +msgid "Execute the selected program" +msgstr "Exécute le programme sélectionné" + +msgid "Execute/stop" +msgstr "Démarrer/stopper" + +msgid "Exercises in the chapter:" +msgstr "Liste des exercices du chapitre :" + +msgid "Exercises\\Programming exercises" +msgstr "Programmation\\Exercices de programmation" + +msgid "Explode (\\key action;)" +msgstr "Détruire (\\key action;)" + +msgid "Explosive" +msgstr "Explosif" + +msgid "Expression expected after =" +msgstr "Expression attendue après =" + +msgid "Extend shield (\\key action;)" +msgstr "Déploie le bouclier (\\key action;)" + +msgid "Eyeglasses:" +msgstr "Lunettes :" + +msgid "Face type:" +msgstr "Type de visage :" + +msgid "File not open" +msgstr "Le fichier n'est pas ouvert" + +msgid "Filename:" +msgstr "Nom du fichier :" + +msgid "Film sequences\\Films before and after the missions" +msgstr "Séquences cinématiques\\Films avant ou après une mission" + +msgid "Finish" +msgstr "But/Objectif" + +# OBJECT_END : GoalArea +msgid "Fixed mine" +msgstr "Mine fixe" + +msgid "Flat ground not large enough" +msgstr "Sol plat pas assez grand" + +msgid "Fog\\Fog" +msgstr "Brouillard\\Nappes de brouillard" + +msgid "Folder:" +msgstr "Dossier:" + +#, c-format +msgid "Folder: %s" +msgstr "Dossier: %s" + +msgid "Font size" +msgstr "Taille des caractères" + +msgid "Forward" +msgstr "Page suivante" + +msgid "Forward (\\key up;)" +msgstr "Avance (\\key up;)" + +msgid "Forward\\Moves forward" +msgstr "Avancer\\Se déplacer en avant" + +msgid "Found a site for a derrick" +msgstr "Emplacement pour un derrick trouvé" + +msgid "Found a site for power station" +msgstr "Emplacement pour station de recharge ou fabrique de pile trouvé" + +msgid "Found key A (site for derrick)" +msgstr "Emplacement pour un derrick (clé A)" + +msgid "Found key B (site for derrick)" +msgstr "Emplacement pour un derrick (clé B)" + +msgid "Found key C (site for derrick)" +msgstr "Emplacement pour un derrick (clé C)" + +msgid "Found key D (site for derrick)" +msgstr "Emplacement pour un derrick (clé D)" + +msgid "Free game" +msgstr "Jeu libre" + +msgid "Free game on this planet:" +msgstr "Liste des jeux libres du chapitre :" + +msgid "Free game\\Free game without a specific goal" +msgstr "Jeu libre\\Jeu libre sans but précis" + +msgid "Full screen\\Full screen or window mode" +msgstr "Plein écran\\Plein écran ou fenêtré" + +msgid "Function already exists" +msgstr "Cette fonction existe déjà" + +msgid "Function name missing" +msgstr "Nom de la fonction attendu" + +msgid "Function needs return type \"void\"" +msgstr "La fonction a besoin de \"void\" en type de retour" + +msgid "Game speed" +msgstr "Vitesse du jeu" + +msgid "Game\\Game settings" +msgstr "Jeu\\Options de jouabilité" + +msgid "Gantry crane" +msgstr "Portique" + +msgid "Generating" +msgstr "Génération" + +msgid "Gold Edition development by:" +msgstr "Édition Gold développée par :" + +msgid "Goto: destination occupied" +msgstr "Goto: destination occupée" + +msgid "Goto: inaccessible destination" +msgstr "Goto: chemin introuvable" + +msgid "Grab or drop (\\key action;)" +msgstr "Prend ou dépose (\\key action;)" + +msgid "Graphics\\Graphics settings" +msgstr "Graphique\\Options graphiques" + +msgid "Green" +msgstr "Vert" + +msgid "Green flag" +msgstr "Drapeau vert" + +msgid "Ground not flat enough" +msgstr "Sol pas assez plat" + +msgid "Hair color:" +msgstr "Couleur des cheveux :" + +msgid "Head\\Face and hair" +msgstr "Tête\\Visage et cheveux" + +msgid "Help about selected object" +msgstr "Instructions sur la sélection" + +msgid "Help balloons\\Explain the function of the buttons" +msgstr "Bulles d'aide\\Bulles explicatives" + +msgid "Hex value out of range" +msgstr "Valeur hexadécimale impossible" + +msgid "Higher speed\\Doubles speed" +msgstr "Vitesse augmentée\\Deux fois plus rapide" + +msgid "Highest\\Highest graphic quality (lowest frame rate)" +msgstr "Maxi\\Haute qualité (+ lent)" + +msgid "Home" +msgstr "Page initiale" + +msgid "Houston Mission Control" +msgstr "Centre de contrôle de Houston" + +msgid "Illegal object" +msgstr "Objet inaccessible" + +msgid "Impossible under water" +msgstr "Impossible sous l'eau" + +msgid "Impossible when carrying an object" +msgstr "Impossible en portant un objet" + +msgid "Impossible when flying" +msgstr "Impossible en vol" + +msgid "Impossible when moving" +msgstr "Impossible en mouvement" + +msgid "Impossible when swimming" +msgstr "Impossible en nageant" + +msgid "Inappropriate bot" +msgstr "Robot inadapté" + +msgid "Inappropriate cell type" +msgstr "Pas le bon type de pile" + +msgid "Inappropriate object" +msgstr "Pas le bon objet" + +msgid "Incorrect index type" +msgstr "Mauvais type d'index" + +msgid "Infected by a virus; temporarily out of order" +msgstr "Infecté par un virus; ne fonctionne plus temporairement" + +msgid "Information exchange post" +msgstr "Borne d'information" + +msgid "Instruction \"break\" outside a loop" +msgstr "Instruction \"break\" en dehors d'une boucle" + +msgid "Instruction \"case\" missing" +msgstr "Il manque l'instruction \"case\"" + +msgid "Instruction \"case\" outside a block \"switch\"" +msgstr "Instruction \"case\" en dehors d'un bloc \"switch\"" + +msgid "Instruction \"else\" without corresponding \"if\"" +msgstr "Instruction \"else\" sans \"if\" correspondant" + +msgid "Instructions (\\key help;)" +msgstr "Instructions (\\key help;)" + +msgid "Instructions after the final closing brace" +msgstr "Instructions après la dernière accolade fermante" + +msgid "Instructions for the mission (\\key help;)" +msgstr "Instructions sur la mission (\\key help;)" + +msgid "Instructions from Houston" +msgstr "Instructions de Houston" + +msgid "Instructions\\Shows the instructions for the current mission" +msgstr "Instructions mission\\Marche à suivre" + +msgid "Internal error - tell the developers" +msgstr "Erreur interne - contacter les développeurs" + +msgid "Invalid universal character name" +msgstr "Conversion invalide d'un caractère unicode en caractère UTF8" + +msgid "Invert\\Invert values on this axis" +msgstr "Inversion\\Inverse les valeurs sur cet axe" + +msgid "Jet temperature" +msgstr "Température du réacteur" + +msgid "Key A" +msgstr "Clé A" + +msgid "Key B" +msgstr "Clé B" + +msgid "Key C" +msgstr "Clé C" + +msgid "Key D" +msgstr "Clé D" + +msgid "Keyword \"while\" missing" +msgstr "Le mot-clé \"while\" est attendu" + +msgid "Keyword help(\\key cbot;)" +msgstr "Aide sur le mot-clé (\\key cbot;)" + +msgid "LOADING" +msgstr "CHARGEMENT" + +msgid "Legged grabber" +msgstr "Robot déménageur à pattes" + +msgid "Legged orga shooter" +msgstr "Robot tireur organique à pattes" + +msgid "Legged shooter" +msgstr "Robot tireur à pattes" + +msgid "Legged sniffer" +msgstr "Robot renifleur à pattes" + +msgid "Levels in this chapter:" +msgstr "Liste des niveaux du chapitre :" + +msgid "Lightning conductor" +msgstr "Paratonnerre" + +msgid "List of objects" +msgstr "Liste des objets" + +msgid "List of saved missions" +msgstr "Liste des missions enregistrées" + +msgid "Load a saved mission" +msgstr "Chargement d'une mission enregistrée" + +msgid "Load\\Load a saved mission" +msgstr "Charger\\Charger une mission enregistrée" + +msgid "Load\\Loads the selected mission" +msgstr "Charger\\Charger la mission sélectionnée" + +msgid "Loading basic level settings" +msgstr "Chargement des configurations de base du niveau" + +msgid "Loading finished!" +msgstr "Chargement terminé !" + +msgid "Loading music" +msgstr "Chargement de la musique" + +msgid "Loading objects" +msgstr "Chargement des objets" + +msgid "Loading terrain" +msgstr "Chargement du terrain" + +# msgid "Speed 0.5x\\Half speed" +# msgstr "" +# msgid "Speed 1.0x\\Normal speed" +# msgstr "" +# msgid "Speed 1.5x\\1.5 times faster" +# msgstr "" +# msgid "Speed 2.0x\\Double speed" +# msgstr "" +# msgid "Speed 3.0x\\Triple speed" +# msgstr "" +# msgid "Speed 4.0x\\Quadruple speed" +# msgstr "" +# msgid "Speed 6.0x\\Sextuple speed" +# msgstr "" +msgid "Lower speed\\Decrease speed by half" +msgstr "Moins rapide\\Diminuer la vitesse de moitié" + +msgid "Lowest\\Minimum graphic quality (highest frame rate)" +msgstr "Mini\\Qualité minimale (+ rapide)" + +msgid "Lunar Roving Vehicle" +msgstr "Véhicule d'exploration lunaire" + +msgid "MSAA\\Multisample anti-aliasing" +msgstr "ACME\\Anticrénelage multiéchantillon" + +msgid "Maximize" +msgstr "Taille maximale" + +msgid "Minimize" +msgstr "Taille réduite" + +msgid "Mipmap level\\Mipmap level" +msgstr "Niveau de MIP mapping\\Niveau de MIP mapping" + +msgid "Missing end quote" +msgstr "La quote de fin est manquante" + +msgid "Missing hex digits after escape sequence" +msgstr "Valeur hexadécimale manquante après la séquence d'échappement" + +msgid "Mission name" +msgstr "Nom de la mission" + +msgid "Missions" +msgstr "Missions" + +msgid "Missions on this planet:" +msgstr "Liste des missions du chapitre :" + +msgid "Missions\\Select mission" +msgstr "Missions\\La grande aventure" + +msgid "Mouse inversion X\\Inversion of the scrolling direction on the X axis" +msgstr "Inversion souris X\\Inversion de la rotation lorsque la souris touche un bord" + +msgid "Mouse inversion Y\\Inversion of the scrolling direction on the Y axis" +msgstr "Inversion souris Y\\Inversion de la rotation lorsque la souris touche un bord" + +msgid "Move selected program down" +msgstr "Déplace le programme sélectionné vers le bas" + +msgid "Move selected program up" +msgstr "Déplace le programme sélectionné vers le haut" + +msgid "Mute\\No sound" +msgstr "Silencieux\\Totalement silencieux" + +msgid "Name:" +msgstr "Nom:" + +msgid "Negative value rejected by \"throw\"" +msgstr "Valeur négative refusée pour \"throw\"" + +msgid "Nest" +msgstr "Nid" + +msgid "New" +msgstr "Nouveau" + +msgid "New ..." +msgstr "Nouveau ..." + +msgid "New bot available" +msgstr "Nouveau robot disponible" + +msgid "Next" +msgstr "Suivant" + +msgid "Next object\\Selects the next object" +msgstr "Sélectionner l'objet suivant\\Sélectionner l'objet suivant" + +msgid "No" +msgstr "Non" + +msgid "No energy in the subsoil" +msgstr "Pas d'énergie en sous-sol" + +msgid "No flag nearby" +msgstr "Aucun drapeau à proximité" + +msgid "No function running" +msgstr "Pas de fonction en exécution" + +msgid "No function with this name accepts this kind of parameter" +msgstr "Aucune fonction de ce nom n'accepte ce(s) type(s) de paramètre(s)" + +msgid "No function with this name accepts this number of parameters" +msgstr "Aucune fonction de ce nom n'accepte ce nombre de paramètres" + +msgid "No information exchange post within range" +msgstr "Pas de borne d'information accessible" + +msgid "No more energy" +msgstr "Plus d'énergie" + +msgid "No ore in the subsoil" +msgstr "Pas de minerai en sous-sol" + +msgid "No power cell" +msgstr "Pas de pile" + +msgid "No titanium" +msgstr "Pas de titane" + +msgid "No titanium around" +msgstr "Pas de titane accessible" + +msgid "No titanium ore to convert" +msgstr "Pas de minerai de titane à convertir" + +msgid "No titanium to transform" +msgstr "Pas de titane à transformer" + +msgid "No uranium to transform" +msgstr "Pas de minerai d'uranium à transformer" + +msgid "No userlevels installed!" +msgstr "Pas de niveaux spéciaux installés !" + +msgid "Non-void function needs \"return;\"" +msgstr "Les fonctions avec retour autre que void doivent comporter l'instruction \"return;\"" + +msgid "Normal size" +msgstr "Taille normale" + +msgid "Normal\\Normal graphic quality" +msgstr "Normal\\Qualité standard" + +msgid "Normal\\Normal sound volume" +msgstr "Normal\\Niveaux normaux" + +msgid "Not enough energy" +msgstr "Pas assez d'énergie" + +msgid "Not enough energy yet" +msgstr "Pas encore assez d'énergie" + +msgid "Not found anything to destroy" +msgstr "Rien trouvé à détruire" + +msgid "Nothing to analyze" +msgstr "Rien à analyser" + +msgid "Nothing to drop" +msgstr "Rien à déposer" + +msgid "Nothing to grab" +msgstr "Rien à prendre" + +msgid "Nothing to recycle" +msgstr "Rien à recycler" + +msgid "Nuclear power cell" +msgstr "Pile nucléaire" + +msgid "Nuclear power cell available" +msgstr "Pile nucléaire disponible" + +msgid "Nuclear power station" +msgstr "Centrale nucléaire" + +msgid "Number missing" +msgstr "Un nombre est attendu" + +msgid "Number of insects detected" +msgstr "Nombre d'insectes détectés" + +msgid "Number of particles\\Explosions, dust, reflections, etc." +msgstr "Quantité de particules\\Explosions, poussières, reflets, etc." + +msgid "OK" +msgstr "D'accord" + +msgid "OK\\Choose the selected player" +msgstr "D'accord\\Choisir le joueur" + +msgid "OK\\Close program editor and return to game" +msgstr "D'accord\\Compiler le programme" + +msgid "Object too close" +msgstr "Objet trop proche" + +msgid "Octal value out of range" +msgstr "Valeur octale impossible" + +msgid "One step" +msgstr "Un pas" + +msgid "Open" +msgstr "Ouvrir" + +msgid "Open (Ctrl+O)" +msgstr "Ouvrir (Ctrl+O)" + +msgid "Opening brace missing" +msgstr "Début d'un bloc attendu" + +msgid "Opening bracket missing" +msgstr "Une parenthèse ouvrante est attendue" + +msgid "Operation impossible with value \"nan\"" +msgstr "Opération sur un \"nan\"" + +msgid "Options" +msgstr "Options" + +msgid "Options\\Preferences" +msgstr "Options\\Réglages" + +msgid "Organic matter" +msgstr "Matière organique" + +msgid "Origin of last message\\Shows where the last message was sent from" +msgstr "Montrer le lieu d'un message\\Montrer le lieu du dernier message" + +msgid "Original game developed by:" +msgstr "Jeu original développé par :" + +msgid "Parameters missing" +msgstr "Pas assez de paramètres" + +msgid "Particles in the interface\\Steam clouds and sparks in the interface" +msgstr "Particules dans l'interface\\Pluie de particules" + +msgid "Paste (Ctrl+V)" +msgstr "Coller (Ctrl+V)" + +msgid "Pause blur\\Blur the background on the pause screen" +msgstr "Flouter les pauses\\Floute le fond de l'écran de pause" + +msgid "Pause in background\\Pause the game when the window is unfocused" +msgstr "Pause en arrière-plan\\Met le jeu en pause quand la fenêtre n'a plus le focus" + +msgid "Pause/continue" +msgstr "Pause/continuer" + +msgid "Pause\\Pause the game without opening menu" +msgstr "Pause\\Mettre le jeu en pause sans ouvrir le menu" + +msgid "Phazer shooter" +msgstr "Robot canon à phases" + +msgid "Photography" +msgstr "Vue de la mission" + +msgid "Place occupied" +msgstr "Emplacement occupé" + +msgid "Planets:" +msgstr "Liste des planètes :" + +msgid "Plans for defense tower available" +msgstr "Construction d'une tour de défense possible" + +msgid "Plans for nuclear power plant available" +msgstr "Construction d'une centrale nucléaire possible" + +msgid "Plans for phazer shooter available" +msgstr "Fabrication des robots canon à phases possible" + +msgid "Plans for shielder available" +msgstr "Fabrication d'un robot bouclier possible" + +msgid "Plans for shooter available" +msgstr "Fabrication des robots tireurs possible" + +msgid "Plans for thumper available" +msgstr "Fabrication d'un robot secoueur possible" + +msgid "Plans for tracked robots available" +msgstr "Fabrication des robots à chenilles possible" + +msgid "Plant a flag" +msgstr "Pose un drapeau de couleur" + +msgid "Play\\Start mission!" +msgstr "Jouer ...\\Démarrer l'action!" + +msgid "Player" +msgstr "Joueur" + +msgid "Player name" +msgstr "Nom du joueur" + +msgid "Player's name" +msgstr "Nom du joueur" + +msgid "Power cell" +msgstr "Pile normale" + +msgid "Power cell available" +msgstr "Pile disponible" + +msgid "Power cell factory" +msgstr "Fabrique de piles" + +msgid "Power station" +msgstr "Station de recharge" + +msgid "Practice bot" +msgstr "Robot d'entraînement" + +msgid "Press \\key help; to read instructions on your SatCom" +msgstr "Consultez votre SatCom en appuyant sur \\key help;" + +msgid "Previous" +msgstr "Précédent" + +msgid "Previous object\\Selects the previous object" +msgstr "Sélection précédente\\Sélectionne l'objet précédent" + +msgid "Previous selection (\\key desel;)" +msgstr "Sélection précédente (\\key desel;)" + +msgid "Private element" +msgstr "Elément protégé (privé)" + +msgid "Private\\Private folder" +msgstr "Privé\\Dossier privé" + +msgid "Processing level file" +msgstr "Analyse du fichier de niveau" + +msgid "Program cloned" +msgstr "Programme dupliqué" + +msgid "Program editor" +msgstr "Édition du programme" + +msgid "Program finished" +msgstr "Programme terminé" + +msgid "Program infected by a virus" +msgstr "Un programme est infecté par un virus" + +msgid "Programming exercises" +msgstr "Programmation" + +msgid "Programming help" +msgstr "Aide à la programmation" + +msgid "Programming help (\\key prog;)" +msgstr "Aide à la programmation (\\key prog;)" + +msgid "Programming help\\Gives more detailed help with programming" +msgstr "Instructions programmation\\Explication sur la programmation" + +msgid "Programs dispatched by Houston" +msgstr "Programmes envoyés par Houston" + +msgid "Public required" +msgstr "Public requis" + +msgid "Public\\Common folder" +msgstr "Public\\Dossier commun à tous les joueurs" + +msgid "Quake at explosions\\The screen shakes at explosions" +msgstr "Secousses lors d'explosions\\L'écran vibre lors d'une explosion" + +msgid "Quick load\\Immediately load game" +msgstr "Chargement rapide\\Chargement direct d'une sauvegarde" + +msgid "Quick save\\Immediately save game" +msgstr "Sauvegarde rapide\\Sauvegarde direct" + +msgid "Quicksave slot not found" +msgstr "Emplacement de sauvegarde rapide non trouvé" + +msgid "Quit\\Quit Colobot: Gold Edition" +msgstr "Quitter\\Quitter Colobot : Édition Gold" + +msgid "Quit\\Quit the current mission or exercise" +msgstr "Quitter la mission en cours\\Terminer un exercice ou une mssion" + +msgid "Radar station" +msgstr "Radar" + +msgid "Read error" +msgstr "Erreur à la lecture" + +msgid "Recorder" +msgstr "Enregistreur" + +msgid "Recycle (\\key action;)" +msgstr "Recycle (\\key action;)" + +msgid "Recycler" +msgstr "Robot recycleur" + +msgid "Red" +msgstr "Rouge" + +# toCheck : capital (for team?) +msgid "Red flag" +msgstr "Drapeau rouge" + +msgid "Reflections on the buttons \\Shiny buttons" +msgstr "Reflets sur les boutons\\Boutons brillants" + +msgid "Remains of Apollo mission" +msgstr "Vestige d'une mission Apollo" + +msgid "Remove a flag" +msgstr "Enlève un drapeau" + +msgid "Remove selected program" +msgstr "Supprimer le programme sélectionné" + +msgid "Render distance\\Maximum visibility" +msgstr "Profondeur de champ\\Distance de vue maximale " + +msgid "Repair center" +msgstr "Centre de réparation" + +msgid "Research center" +msgstr "Centre de recherches" + +msgid "Research program already performed" +msgstr "Recherche déjà effectuée" + +msgid "Research program completed" +msgstr "Recherche terminée" + +msgid "Reserved keyword of CBOT language" +msgstr "Ce mot-clé est réservé au langage CBOT" + +msgid "Resolution" +msgstr "Résolution" + +msgid "Resolution:" +msgstr "Résolutions :" + +msgid "Resources" +msgstr "Ressources" + +msgid "Restart\\Restart the mission from the beginning" +msgstr "Recommencer\\Recommencer la mission au début" + +msgid "Restoring CBot execution state" +msgstr "Restaurer l'état d'exécution CBOT" + +msgid "Restoring saved objects" +msgstr "Restaurer des objets sauvés" + +msgid "Results" +msgstr "Résultats" + +msgid "Return to start" +msgstr "Remet au départ" + +msgid "Robbie" +msgstr "Robbie" + +msgid "Ruin" +msgstr "Bâtiment en ruine" + +msgid "Run research program for defense tower" +msgstr "Recherche la tour de défense" + +msgid "Run research program for legged bots" +msgstr "Recherche du fonctionnement des pattes" + +msgid "Run research program for nuclear power" +msgstr "Recherche du programme nucléaire" + +msgid "Run research program for orga shooter" +msgstr "Recherche le canon organique" + +msgid "Run research program for phazer shooter" +msgstr "Recherche le canon à phases" + +msgid "Run research program for shielder" +msgstr "Recherche le bouclier" + +msgid "Run research program for shooter" +msgstr "Recherche le canon de tir" + +msgid "Run research program for thumper" +msgstr "Recherche le secoueur" + +msgid "Run research program for tracked bots" +msgstr "Recherche du fonctionnement des chenilles" + +msgid "Run research program for winged bots" +msgstr "Recherche du fonctionnement du jet" + +msgid "SatCom" +msgstr "SatCom" + +msgid "Satellite report" +msgstr "Rapport du satellite" + +msgid "Save" +msgstr "Enregistrer" + +msgid "Save (Ctrl+S)" +msgstr "Enregistrer (Ctrl+S)" + +msgid "Save the current mission" +msgstr "Enregistrement de la mission en cours" + +msgid "Save\\Save the current mission" +msgstr "Enregistrer\\Enregistrer la mission en cours" + +msgid "Save\\Saves the current mission" +msgstr "Enregistrer\\Enregistrer la mission en cours" + +msgid "Select the astronaut\\Selects the astronaut" +msgstr "Sélectionner le cosmonaute\\Sélectionner le cosmonaute" + +msgid "Semicolon terminator missing" +msgstr "Terminateur point-virgule non trouvé" + +msgid "Shadow resolution\\Higher means better range and quality, but slower" +msgstr "Résolution des ombres\\Plus grand implique une meilleure qualité et amplitude, mais plus lent" + +msgid "Shield level" +msgstr "Niveau du bouclier" + +msgid "Shield radius" +msgstr "Rayon du bouclier" + +msgid "Shielder" +msgstr "Robot bouclier" + +msgid "Shoot (\\key action;)" +msgstr "Tir (\\key action;)" + +msgid "Show if the ground is flat" +msgstr "Montre si le sol est plat" + +msgid "Show the place" +msgstr "Montre l'endroit" + +msgid "Show the range" +msgstr "Montre le rayon d'action" + +msgid "Show the solution" +msgstr "Donne la solution" + +msgid "Sign \" : \" missing" +msgstr "Séparateur \" : \" attendu" + +msgid "Simple shadows\\Shadows spots on the ground" +msgstr "Ombres simples\\Ombres projetées au sol" + +msgid "Size 1" +msgstr "Taille 1" + +msgid "Size 2" +msgstr "Taille 2" + +msgid "Size 3" +msgstr "Taille 3" + +msgid "Size 4" +msgstr "Taille 4" + +msgid "Size 5" +msgstr "Taille 5" + +msgid "Sniff (\\key action;)" +msgstr "Cherche (\\key action;)" + +msgid "Solution" +msgstr "Solution" + +msgid "Sound effects:\\Volume of engines, voice, shooting, etc." +msgstr "Sons :\\Volume des moteurs, voix, etc." + +msgid "Sound\\Music and game sound volume" +msgstr "Son\\Volumes des sons & musiques" + +msgid "Spaceship" +msgstr "Vaisseau spatial" + +msgid "Spaceship ruin" +msgstr "Epave de vaisseau spatial" + +msgid "Spider" +msgstr "Araignée" + +msgid "Spider fatally wounded" +msgstr "Araignée mortellement touchée" + +msgid "Stack overflow" +msgstr "Débordement de la pile" + +msgid "Standard action\\Standard action of the bot (take/grab, shoot, sniff, etc)" +msgstr "Action standard\\Action du bouton avec le cadre rouge" + +msgid "Standard controls\\Standard key functions" +msgstr "Tout réinitialiser\\Remet toutes les touches standards" + +msgid "Standard speed\\Reset speed to normal" +msgstr "Vitesse standard\\Réinitialiser la vitesse à la normale" + +msgid "Standard\\Standard appearance settings" +msgstr "Standard\\Remet les couleurs standards" + +msgid "Start" +msgstr "Départ" + +msgid "Starting..." +msgstr "Lancement..." + +msgid "Still working ..." +msgstr "Travail en cours ..." + +msgid "String missing" +msgstr "Une chaîne de caractère est attendue" + +msgid "Strip color:" +msgstr "Couleur des bandes :" + +msgid "Subber" +msgstr "Robot sous-marin" + +msgid "Suit color:" +msgstr "Couleur de la combinaison :" + +msgid "Suit\\Astronaut suit" +msgstr "Corps\\Combinaison" + +msgid "Summary:" +msgstr "Résumé :" + +msgid "Survival kit" +msgstr "Sac de survie" + +msgid "Switch bots <-> buildings" +msgstr "Permute robots <-> bâtiments" + +msgid "Take off to finish the mission" +msgstr "Décolle pour terminer la mission" + +msgid "Target" +msgstr "Cible" + +msgid "Target bot" +msgstr "Cible d'entraînement" + +msgid "Terrain relief" +msgstr "Relief du terrain" + +msgid "Texture filtering\\Texture filtering" +msgstr "Filtrage de textures\\Filtrage de textures" + +msgid "Textures" +msgstr "Textures" + +msgid "The battle has ended" +msgstr "La bataille est terminée" + +msgid "The expression must return a boolean value" +msgstr "L'expression doit être un boolean" + +msgid "The function returned no value" +msgstr "La fonction n'a pas retourné de résultat" + +msgid "The mission is not accomplished yet (press \\key help; for more details)" +msgstr "La mission n'est pas terminée (appuyez sur \\key help; pour plus de détails)" + +msgid "The types of the two operands are incompatible" +msgstr "Les deux opérandes ne sont pas de types compatibles" + +msgid "This class already exists" +msgstr "Cette classe existe déjà" + +msgid "This class does not exist" +msgstr "Cette classe n'existe pas" + +msgid "This is example code that cannot be run directly" +msgstr "Ce code d'exemple ne peut pas être lancé directement" + +msgid "This is not a member of this class" +msgstr "Cet élément n'existe pas dans cette classe" + +msgid "This label does not exist" +msgstr "Cette étiquette n'existe pas" + +msgid "This menu is for userlevels from mods, but you didn't install any" +msgstr "Ce menu donne accès aux niveaux spéciaux (importés ou personnalisés), mais aucun n'est installé." + +msgid "This object is currently busy" +msgstr "Cet élément est actuellement occupé" + +msgid "This object is not a member of a class" +msgstr "L'objet n'est pas une instance d'une classe" + +msgid "This parameter needs a default value" +msgstr "Ce paramètre nécessite une valeur par défaut" + +msgid "This program is read-only, clone it to edit" +msgstr "Ce programme est en lecture-seule, le dupliquer pour pouvoir le modifier" + +msgid "Thump (\\key action;)" +msgstr "Secoue (\\key action;)" + +msgid "Thumper" +msgstr "Robot secoueur" + +#, c-format +msgid "Time: %s" +msgstr "Temps : %s" + +msgid "Titanium" +msgstr "Titane" + +msgid "Titanium available" +msgstr "Titane disponible" + +msgid "Titanium deposit (site for derrick)" +msgstr "Emplacement pour un derrick (minerai de titane)" + +msgid "Titanium ore" +msgstr "Minerai de titane" + +msgid "Titanium too close" +msgstr "Titane trop proche" + +msgid "Titanium too far away" +msgstr "Titane trop loin" + +msgid "Too close to a building" +msgstr "Trop proche d'un bâtiment" + +msgid "Too close to an existing flag" +msgstr "Trop proche d'un drapeau existant" + +msgid "Too close to space ship" +msgstr "Trop proche du vaisseau spatial" + +msgid "Too many flags of this color (maximum 5)" +msgstr "Trop de drapeaux de cette couleur (maximum 5)" + +msgid "Too many parameters" +msgstr "Trop de paramètres" + +msgid "Tracked grabber" +msgstr "Robot déménageur à chenilles" + +msgid "Tracked orga shooter" +msgstr "Robot tireur organique à chenilles" + +msgid "Tracked shooter" +msgstr "Robot tireur à chenilles" + +msgid "Tracked sniffer" +msgstr "Robot renifleur à chenilles" + +msgid "Transforms only titanium" +msgstr "Ne transforme que le titane" + +msgid "Transforms only uranium" +msgstr "Ne transforme que le minerai d'uranium" + +msgid "Transmitted information" +msgstr "Informations diffusées" + +msgid "Turn left (\\key left;)" +msgstr "Tourne à gauche (\\key left;)" + +msgid "Turn left\\turns the bot to the left" +msgstr "Tourner à gauche\\Moteur à gauche" + +msgid "Turn right (\\key right;)" +msgstr "Tourne à droite (\\key right;)" + +msgid "Turn right\\turns the bot to the right" +msgstr "Tourner à droite\\Moteur à droite" + +msgid "Type declaration missing" +msgstr "Déclaration de type attendu" + +msgid "Unable to control enemy objects" +msgstr "Impossible de contrôler les objets ennemis" + +msgid "Undo (Ctrl+Z)" +msgstr "Annuler (Ctrl+Z)" + +msgid "Unit" +msgstr "Unité" + +msgid "Unknown Object" +msgstr "Objet inconnu" + +msgid "Unknown command" +msgstr "Commande inconnue" + +msgid "Unknown escape sequence" +msgstr "Séquence d'échappement inconnue" + +msgid "Unknown function" +msgstr "Routine inconnue" + +msgid "Up (\\key gup;)" +msgstr "Monte (\\key gup;)" + +msgid "Uranium deposit (site for derrick)" +msgstr "Emplacement pour un derrick (minerai d'uranium)" + +msgid "Uranium ore" +msgstr "Minerai d'uranium" + +msgid "User levels" +msgstr "Niveaux supplémentaires" + +msgid "Variable name missing" +msgstr "Nom d'une variable attendu" + +msgid "Variable not declared" +msgstr "Variable non déclarée" + +msgid "Variable not initialized" +msgstr "Variable non initialisée" + +msgid "Vault" +msgstr "Coffre-fort" + +msgid "Violet flag" +msgstr "Drapeau violet" + +msgid "Void parameter" +msgstr "Paramètre void" + +msgid "Wasp" +msgstr "Guêpe" + +msgid "Wasp fatally wounded" +msgstr "Guêpe mortellement touchée" + +msgid "Waste" +msgstr "Déchet" + +msgid "Wheeled grabber" +msgstr "Robot déménageur à roues" + +msgid "Wheeled orga shooter" +msgstr "Robot tireur organique à roues" + +msgid "Wheeled shooter" +msgstr "Robot tireur à roues" + +msgid "Wheeled sniffer" +msgstr "Robot renifleur à roues" + +msgid "Winged grabber" +msgstr "Robot déménageur volant" + +msgid "Winged orga shooter" +msgstr "Robot tireur organique volant" + +msgid "Winged shooter" +msgstr "Robot tireur volant" + +msgid "Winged sniffer" +msgstr "Robot renifleur volant" + +msgid "Withdraw shield (\\key action;)" +msgstr "Refermer le bouclier (\\key action;)" + +msgid "Worm" +msgstr "Ver" + +msgid "Worm fatally wounded" +msgstr "Ver mortellement touché" + +msgid "Wreckage" +msgstr "Epave de robot" + +msgid "Write error" +msgstr "Erreur lors de l'écriture" + +msgid "Wrong type for the assignment" +msgstr "Mauvais type de résultat pour l'assignation" + +msgid "Yellow flag" +msgstr "Drapeau jaune" + +msgid "Yes" +msgstr "Oui" + +msgid "You can fly with the keys (\\key gup;) and (\\key gdown;)" +msgstr "Il est possible de voler avec les touches (\\key gup;) et (\\key gdown;)" + +msgid "You can not carry a radioactive object" +msgstr "Vous ne pouvez pas transporter un objet radioactif" + +msgid "You can not carry an object under water" +msgstr "Vous ne pouvez pas transporter un objet sous l'eau" + +#, c-format +msgid "You cannot use \"%s\" in this exercise (used: %d)" +msgstr "Vous ne pouvez pas utiliser «%s» dans cet exercice (utilisé : %d)" + +msgid "You found a usable object" +msgstr "Vous avez trouvé un objet utilisable" + +#, c-format +msgid "You have to use \"%1$s\" at least once in this exercise (used: %2$d)" +msgid_plural "You have to use \"%1$s\" at least %3$d times in this exercise (used: %2$d)" +msgstr[0] "Vous devez utiliser «%1$s» au moins une fois dans cet exercice (utilisé %2$d fois)" +msgstr[1] "Vous devez utiliser «%1$s» au moins %3$d fois dans cet exercice (utilisé %2$d fois)" + +#, c-format +msgid "You have to use \"%1$s\" at most once in this exercise (used: %2$d)" +msgid_plural "You have to use \"%1$s\" at most %3$d times in this exercise (used: %2$d)" +msgstr[0] "Vous devez utiliser «%1$s» au plus une fois dans cet exercice (utilisé %2$d fois)" +msgstr[1] "Vous devez utiliser «%1$s» au plus %3$d fois dans cet exercice (utilisé %2$d fois)" + +msgid "You must get on the spaceship to take off" +msgstr "Vous devez embarquer pour pouvoir décoller" + +msgid "Zoom mini-map" +msgstr "Zoom mini-carte" + +msgid "\\Blue flags" +msgstr "\\Drapeaux bleus" + +msgid "\\Eyeglasses 1" +msgstr "\\Lunettes 1" + +msgid "\\Eyeglasses 2" +msgstr "\\Lunettes 2" + +msgid "\\Eyeglasses 3" +msgstr "\\Lunettes 3" + +msgid "\\Eyeglasses 4" +msgstr "\\Lunettes 4" + +msgid "\\Eyeglasses 5" +msgstr "\\Lunettes 5" + +msgid "\\Face 1" +msgstr "\\Visage 1" + +msgid "\\Face 2" +msgstr "\\Visage 2" + +msgid "\\Face 3" +msgstr "\\Visage 3" + +msgid "\\Face 4" +msgstr "\\Visage 4" + +msgid "\\Green flags" +msgstr "\\Drapeaux verts" + +msgid "\\New player name" +msgstr "\\Nom du joueur à créer" + +msgid "\\No eyeglasses" +msgstr "\\Pas de lunettes" + +msgid "\\Raise the pencil" +msgstr "\\Relève le crayon" + +msgid "\\Red flags" +msgstr "\\Drapeaux rouges" + +msgid "\\Return to Colobot: Gold Edition" +msgstr "\\Revenir à Colobot : Édition Gold" + +msgid "\\SatCom on standby" +msgstr "\\Mettre le SatCom en veille" + +msgid "\\Start recording" +msgstr "\\Démarre l'enregistrement" + +msgid "\\Stop recording" +msgstr "\\Stoppe l'enregistrement" + +msgid "\\Turn left" +msgstr "\\Rotation à gauche" + +msgid "\\Turn right" +msgstr "\\Rotation à droite" + +msgid "\\Use the black pencil" +msgstr "\\Abaisse le crayon noir" + +msgid "\\Use the blue pencil" +msgstr "\\Abaisse le crayon bleu" + +msgid "\\Use the brown pencil" +msgstr "\\Abaisse le crayon brun" + +msgid "\\Use the green pencil" +msgstr "\\Abaisse le crayon vert" + +msgid "\\Use the orange pencil" +msgstr "\\Abaisse le crayon orange" + +msgid "\\Use the purple pencil" +msgstr "\\Abaisse le crayon violet" + +msgid "\\Use the red pencil" +msgstr "\\Abaisse le crayon rouge" + +msgid "\\Use the yellow pencil" +msgstr "\\Abaisse le crayon jaune" + +msgid "\\Violet flags" +msgstr "\\Drapeaux violets" + +msgid "\\Yellow flags" +msgstr "\\Drapeaux jaunes" + +msgid "colobot.info" +msgstr "colobot.info" + +msgid "epsitec.com" +msgstr "epsitec.com" + +#~ msgid " " +#~ msgstr " " + +#~ msgid " Drivers:" +#~ msgstr " Pilotes :" + +#~ msgid " Missions on this level:" +#~ msgstr " Missions du niveau :" + +#~ msgid "\"%s\" missing in this exercise" +#~ msgstr "Il manque \"%s\" dans le programme" + +#~ msgid "3D sound\\3D positioning of the sound" +#~ msgstr "Bruitages 3D\\Positionnement sonore dans l'espace" + +#~ msgid "Building too close" +#~ msgstr "Bâtiment trop proche" + +#~ msgid "COLOBOT" +#~ msgstr "COLOBOT" + +#~ msgid "Camera awayest" +#~ msgstr "Caméra plus loin" + +#~ msgid "Camera down\\Decrease camera angle while visiting message origin" +#~ msgstr "Caméra plus basse\\Réduit l'angle de caméra lors de la vue de l'origine des messages" + +#~ msgid "Camera nearest" +#~ msgstr "Caméra plus proche" + +#~ msgid "Camera to left" +#~ msgstr "Caméra à gauche" + +#~ msgid "Camera to right" +#~ msgstr "Caméra à droite" + +#~ msgid "Camera up\\Increase camera angle while visiting message origin" +#~ msgstr "Caméra plus haute\\Augmente l'angle de caméra lors de la vue de l'origine des messages" + +#~ msgid "Can not create this; there are too many objects" +#~ msgstr "Création impossible; il y a trop d'objets" + +#~ msgid "Cancel\\Keep current player name" +#~ msgstr "Annuler\\Conserver le joueur actuel" + +#~ msgid "Checkpoint crossed" +#~ msgstr "Indicateur atteint" + +#~ msgid "Compass" +#~ msgstr "Boussole" + +#~ msgid "Continue\\Continue the game" +#~ msgstr "Continuer\\Continuer de jouer" + +#~ msgid "Delete" +#~ msgstr "Détruire" + +#~ msgid "Details\\Visual quality of 3D objects" +#~ msgstr "Détails des objets\\Qualité des objets en 3D" + +#~ msgid "Developed by :" +#~ msgstr "Développé par :" + +#~ msgid "Do you want to quit Colobot: Gold Edition?" +#~ msgstr "Voulez-vous quitter Colobot: Édition Gold ?" + +#~ msgid "Exit film\\Film at the exit of exercises" +#~ msgstr "Retour animé\\Retour animé dans les exercices" + +#~ msgid "Friendly fire\\Your shooting can damage your own objects " +#~ msgstr "Dégâts à soi-même\\Vos tirs infligent des dommages à vos unités" + +#~ msgid "Ground inappropriate" +#~ msgstr "Terrain inadapté" + +#~ msgid "Key word help\\More detailed help about key words" +#~ msgstr "Instructions mot-clé\\Explication sur le mot-clé" + +#~ msgid "Marks on the ground\\Marks on the ground" +#~ msgstr "Marques sur le sol\\Marques dessinées sur le sol" + +#~ msgid "Mouse shadow\\Gives the mouse a shadow" +#~ msgstr "Souris ombrée\\Jolie souris avec une ombre" + +#~ msgid "No other robot" +#~ msgstr "Pas d'autre robot" + +#~ msgid "Not yet enough energy" +#~ msgstr "Pas encore assez d'énergie" + +#~ msgid "Num of decorative objects\\Number of purely ornamental objects" +#~ msgstr "Nb d'objets décoratifs\\Qualité d'objets non indispensables" + +#~ msgid "Planets and stars\\Astronomical objects in the sky" +#~ msgstr "Planètes et étoiles\\Motifs mobiles dans le ciel" + +#~ msgid "Quit the mission?" +#~ msgstr "Quitter la mission ?" + +#~ msgid "Quit\\Quit COLOBOT" +#~ msgstr "Quitter\\Quitter COLOBOT" + +#~ msgid "Robbie\\Your assistant" +#~ msgstr "Robbie\\Votre assistant" + +#~ msgid "Sky\\Clouds and nebulae" +#~ msgstr "Ciel\\Ciel et nuages" + +#~ msgid "Speed 0.5x\\Half speed" +#~ msgstr "Vitesse 0.5x\\Demi-vitesse" + +#~ msgid "Speed 1.0x\\Normal speed" +#~ msgstr "Vitesse 1.0x\\Vitesse normale" + +#~ msgid "Speed 1.5x\\1.5 times faster" +#~ msgstr "Vitesse 1.5x\\Une fois et demi plus rapide" + +#~ msgid "Speed 3.0x\\Three times faster" +#~ msgstr "Vitesse 3.0x\\Trois fois plus rapide" + +#~ msgid "Speed 3.0x\\Triple speed" +#~ msgstr "Vitesse 3.0x\\Trois fois plus rapide " + +#~ msgid "Speed 4.0x\\Quadruple speed" +#~ msgstr "Vitesse 4.0x\\Quatre fois plus rapide" + +#~ msgid "Speed 6.0x\\Sextuple speed" +#~ msgstr "Vitesse 6.0x\\Six fois plus rapide" + +#~ msgid "Sunbeams\\Sunbeams in the sky" +#~ msgstr "Rayons du soleil\\Rayons selon l'orientation" + +#~ msgid "System mouse\\Use system mouse cursor" +#~ msgstr "Souris système\\Utiliser le curseur de la souris système" + +#~ msgid "Textures\\Quality of textures " +#~ msgstr "Qualité des textures\\Qualité des images" + +#~ msgid "The list is only available if a \\l;radar station\\u object\\radar; is working.\n" +#~ msgstr "Liste non disponible sans \\l;radar\\u object\\radar;.\n" + +#~ msgid "Use a joystick\\Joystick or keyboard" +#~ msgstr "Utilise un joystick\\Joystick ou clavier" + +#~ msgid "User\\User levels" +#~ msgstr "Suppl.\\Niveaux supplémentaires" + +#~ msgid "\\Return to COLOBOT" +#~ msgstr "\\Retourner dans COLOBOT" + +#~ msgid "\\b;Aliens\n" +#~ msgstr "\\b;Listes des ennemis\n" + +#~ msgid "\\b;Buildings\n" +#~ msgstr "\\b;Listes des bâtiments\n" + +#~ msgid "\\b;Error\n" +#~ msgstr "\\b;Erreur\n" + +#~ msgid "\\b;List of objects\n" +#~ msgstr "\\b;Listes des objets\n" + +#~ msgid "\\b;Moveable objects\n" +#~ msgstr "\\b;Listes des objets transportables\n" + +#~ msgid "\\b;Robots\n" +#~ msgstr "\\b;Listes des robots\n" + +#~ msgid "\\c; (none)\\n;\n" +#~ msgstr "\\c; (aucun)\\n;\n" From 4c3440bbe6f43d84ecd12c5a8cb28bb6dac2205d Mon Sep 17 00:00:00 2001 From: krzys-h Date: Wed, 16 May 2018 11:55:06 +0200 Subject: [PATCH 079/109] Fix building of colobot.rc on Windows --- desktop/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/desktop/CMakeLists.txt b/desktop/CMakeLists.txt index dcca3b77..b49ef2d3 100644 --- a/desktop/CMakeLists.txt +++ b/desktop/CMakeLists.txt @@ -145,7 +145,12 @@ if(PLATFORM_MACOSX) endif(PLATFORM_MACOSX) if(PLATFORM_WINDOWS) - set(COLOBOT_VERSION_4COMMAS "${COLOBOT_VERSION_MAJOR},${COLOBOT_VERSION_MINOR},${COLOBOT_VERSION_REVISION},0") + if(COLOBOT_VERSION_REVISION MATCHES "([0-9]+)\\.([0-9]+)") + string(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\1,\\2" COLOBOT_VERSION_REVISION_COMMA "${COLOBOT_VERSION_REVISION}") + set(COLOBOT_VERSION_4COMMAS "${COLOBOT_VERSION_MAJOR},${COLOBOT_VERSION_MINOR},${COLOBOT_VERSION_REVISION_COMMA}") + else() + set(COLOBOT_VERSION_4COMMAS "${COLOBOT_VERSION_MAJOR},${COLOBOT_VERSION_MINOR},${COLOBOT_VERSION_REVISION},0") + endif() configure_file(colobot.rc.cmake ${CMAKE_CURRENT_BINARY_DIR}/colobot.rc) endif(PLATFORM_WINDOWS) From 086e07168d3fbdac8ff806864dde3990cf208642 Mon Sep 17 00:00:00 2001 From: suve Date: Sat, 2 Feb 2019 18:53:36 +0100 Subject: [PATCH 080/109] Use sizeof() instead of magic number for strncpy in ModelOutput::WriteOldModel --- src/graphics/model/model_output.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/graphics/model/model_output.cpp b/src/graphics/model/model_output.cpp index 15ebeb75..ef94a3a5 100644 --- a/src/graphics/model/model_output.cpp +++ b/src/graphics/model/model_output.cpp @@ -328,7 +328,10 @@ void ModelOutput::WriteOldModel(const CModel& model, std::ostream &stream) t.material.ambient = triangle.ambient; t.material.diffuse = triangle.diffuse; t.material.specular = triangle.specular; - strncpy(t.texName, triangle.tex1Name.c_str(), 20); + + strncpy(t.texName, triangle.tex1Name.c_str(), sizeof(t.texName)-1); + t.texName[sizeof(t.texName)-1] = '\0'; + t.min = 0.0f; t.max = 1000000.0f; t.state = ConvertToOldState(triangle); From 0f6e1d7d4a516db1ef6c54f0ccbde10f3a90cba8 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Tue, 29 Jan 2019 20:39:46 +0100 Subject: [PATCH 081/109] Style fix --- src/graphics/engine/engine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 24c68098..348514bb 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -4048,7 +4048,8 @@ void CEngine::UseMSAA(bool enable) } } - if (framebuffer != nullptr) { + if (framebuffer != nullptr) + { framebuffer->Bind(); } From a46750ede2d70271320461266c68aab036de6f2d Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Wed, 30 Jan 2019 21:06:07 +0100 Subject: [PATCH 082/109] Fix crash when destroying unpowered PowerPlant with Titanium Appendix to pull #1206 --- src/object/auto/autopowerplant.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/object/auto/autopowerplant.cpp b/src/object/auto/autopowerplant.cpp index 37b2d7d5..d7294b93 100644 --- a/src/object/auto/autopowerplant.cpp +++ b/src/object/auto/autopowerplant.cpp @@ -82,12 +82,14 @@ void CAutoPowerPlant::DeleteObject(bool all) CObject* cargo = SearchMetal(); if ( cargo != nullptr ) { + m_object->SetPower(nullptr); CObjectManager::GetInstancePointer()->DeleteObject(cargo); } cargo = SearchPower(); if ( cargo != nullptr ) { + m_object->SetPower(nullptr); CObjectManager::GetInstancePointer()->DeleteObject(cargo); } } From e02a3373fd60d8b3bbb68c02299ee6d64dab5266 Mon Sep 17 00:00:00 2001 From: krzys_h Date: Mon, 18 Feb 2019 19:18:53 +0100 Subject: [PATCH 083/109] Update Jenkinsfile for dockerized build environment (#1240) --- Jenkinsfile | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 9ba966a7..3ebe5751 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,7 +1,7 @@ #!/usr/bin/env groovy pipeline { - agent { label 'colobot-build' } + agent none options { buildDiscarder(logRotator(artifactDaysToKeepStr: '30', artifactNumToKeepStr: '20')) } @@ -19,13 +19,17 @@ pipeline { stage('Build') { parallel { stage('Build Windows') { + agent { + docker { image 'krzysh/colobot-build:latest' } + } steps { sh 'mkdir -p build/windows' dir('build/windows') { sh ''' - cmake \ + # FIXME: without -lsetupapi linking sdl2 fails + /opt/mxe/usr/bin/i686-w64-mingw32.static-cmake \ + -DCMAKE_CXX_STANDARD_LIBRARIES="-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -lsetupapi" \ -DCMAKE_INSTALL_PREFIX=/install \ - -DCMAKE_TOOLCHAIN_FILE=/opt/mxe/usr/i686-w64-mingw32.static/share/cmake/mxe-conf.cmake \ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEV_BUILD=1 -DPORTABLE=1 -DTOOLS=1 -DTESTS=0 ../.. make rm -rf install @@ -42,13 +46,15 @@ pipeline { } stage('Build Linux') { + agent { + docker { image 'krzysh/colobot-build:latest' } + } steps { sh 'mkdir -p build/linux' dir('build/linux') { sh ''' cmake \ -DCMAKE_INSTALL_PREFIX=/install -DCOLOBOT_INSTALL_BIN_DIR=/install -DCOLOBOT_INSTALL_LIB_DIR=/install -DCOLOBOT_INSTALL_DATA_DIR=/install/data -DCOLOBOT_INSTALL_I18N_DIR=/install/lang -DCMAKE_SKIP_INSTALL_RPATH=ON \ - -DBOOST_STATIC=ON -DGLEW_STATIC=ON -DGLEW_LIBRARY=/usr/lib64/libGLEW.a \ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEV_BUILD=1 -DPORTABLE=1 -DTOOLS=1 -DTESTS=1 -DDESKTOP=0 ../.. make rm -rf install @@ -68,6 +74,9 @@ pipeline { } stage('Generate docs') { + agent { + docker { image 'krzysh/colobot-build:latest' } + } steps { dir('build/linux') { sh 'make doc' @@ -81,6 +90,9 @@ pipeline { } stage('Run tests') { + agent { + docker { image 'krzysh/colobot-build:latest' } + } steps { dir('build/linux') { sh './colobot_ut --gtest_output=xml:gtestresults.xml || true' @@ -91,6 +103,9 @@ pipeline { } stage('Run colobot-lint') { + agent { + label 'colobot-build' + } environment { CC = '/usr/lib/llvm-3.6/bin/clang' CXX = '/usr/lib/llvm-3.6/bin/clang++' @@ -245,11 +260,10 @@ exit $ret } } - // TODO: cppcheck publisher STILL doesn't have pipeline support - // There is an open pull request though, merged but no release yet... https://github.com/jenkinsci/cppcheck-plugin/pull/36 - + publishCppcheck pattern: 'build/lint/colobot_lint_report.xml' publishHTML([reportName: 'Colobot-lint HTML report', reportDir: 'build/lint/html_report', reportFiles: 'index.html', reportTitles: '', allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true]) } } } } + From 275724ab97be998fa8b787c270c1eadfb581d815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Przyby=C5=82?= Date: Thu, 21 Feb 2019 17:46:11 +0100 Subject: [PATCH 084/109] Build AppImage in Jenkins (#1243) --- Jenkinsfile | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 3ebe5751..95b567a8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -54,8 +54,8 @@ pipeline { dir('build/linux') { sh ''' cmake \ - -DCMAKE_INSTALL_PREFIX=/install -DCOLOBOT_INSTALL_BIN_DIR=/install -DCOLOBOT_INSTALL_LIB_DIR=/install -DCOLOBOT_INSTALL_DATA_DIR=/install/data -DCOLOBOT_INSTALL_I18N_DIR=/install/lang -DCMAKE_SKIP_INSTALL_RPATH=ON \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEV_BUILD=1 -DPORTABLE=1 -DTOOLS=1 -DTESTS=1 -DDESKTOP=0 ../.. + -DCMAKE_INSTALL_PREFIX=/install -DCMAKE_SKIP_INSTALL_RPATH=ON \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEV_BUILD=1 -DPORTABLE=1 -DTOOLS=1 -DTESTS=1 -DDESKTOP=1 ../.. make rm -rf install DESTDIR=. make install @@ -66,7 +66,31 @@ pipeline { post { success { sh 'rm -f linux-debug.zip' - zip zipFile: 'linux-debug.zip', archive: true, dir: 'build/linux/install' + dir('build/linux') { + sh ''' + # Clean up + rm -rf squashfs-root + rm -rf colobot.AppDir + rm -rf appimage + rm -f Colobot-x86_64.AppImage + + # Download app image tool + wget -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage + chmod +x linuxdeploy-x86_64.AppImage + ./linuxdeploy-x86_64.AppImage --appimage-extract + + # Create AppImage + NO_STRIP=1 ./squashfs-root/AppRun -e colobot --output appimage --appdir colobot.AppDir -d desktop/colobot.desktop -i ../../desktop/colobot.svg + chmod +x Colobot-x86_64.AppImage + + # Prepare folder for zip + mkdir -p appimage + cp -rp install/data appimage/data + cp -rp install/lang appimage/lang + cp -p Colobot-x86_64.AppImage appimage/colobot + ''' + } + zip zipFile: 'linux-debug.zip', archive: true, dir: 'build/linux/appimage' } } } From 0eb31a1f450e099845251cd26ad63865825ca01a Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Sat, 23 Feb 2019 13:12:37 +0100 Subject: [PATCH 085/109] Fix PORTABLE_SAVES flag not working --- src/common/system/system.cpp | 2 -- src/common/system/system.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/system/system.cpp b/src/common/system/system.cpp index 44064556..12dc1d36 100644 --- a/src/common/system/system.cpp +++ b/src/common/system/system.cpp @@ -20,8 +20,6 @@ #include "common/system/system.h" -#include "common/config.h" - #include "common/make_unique.h" #if defined(PLATFORM_WINDOWS) diff --git a/src/common/system/system.h b/src/common/system/system.h index aaf54954..36e736c9 100644 --- a/src/common/system/system.h +++ b/src/common/system/system.h @@ -24,6 +24,8 @@ #pragma once +#include "common/config.h" + #include #include #include From aca552242f5ee9a16240544d76d0968c1d45a7e9 Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Sat, 23 Feb 2019 18:51:37 +0100 Subject: [PATCH 086/109] Update po files --- po/fr.po | 2 +- po/pt.po | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/po/fr.po b/po/fr.po index a9222d72..c8d48217 100644 --- a/po/fr.po +++ b/po/fr.po @@ -9,6 +9,7 @@ msgstr "" "POT-Creation-Date: DATE\n" "PO-Revision-Date: 2019-01-09 23:07+0100\n" "Last-Translator: B-CE\n" +"Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -17,7 +18,6 @@ msgstr "" "X-Generator: Poedit 2.0.6\n" "X-Language: fr_FR\n" "X-Source-Language: en_US\n" -"Language-Team: \n" msgid " or " msgstr " ou " diff --git a/po/pt.po b/po/pt.po index dc710c46..f99a9cbf 100644 --- a/po/pt.po +++ b/po/pt.po @@ -1678,6 +1678,9 @@ msgstr "Variável não inicializada" msgid "Vault" msgstr "Cofre" +msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" +msgstr "" + msgid "Violet flag" msgstr "Bandeira violeta" From 46098834a15598dd897ac23636b34efe314a36c4 Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Sat, 23 Feb 2019 18:54:39 +0100 Subject: [PATCH 087/109] Update data submodule --- data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data b/data index 8597221e..dd12dbe3 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 8597221e4ddbb9016e7aba46c508dca84f3aa1d6 +Subproject commit dd12dbe39a7ad896ac6c73fd4e40c333259e1c84 From 7d99aa954bbadeae884ffa403804b1216dc69d06 Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Sat, 23 Feb 2019 20:01:21 +0100 Subject: [PATCH 088/109] Fix release.py --- tools/release.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/release.py b/tools/release.py index 918b230a..3797fe90 100755 --- a/tools/release.py +++ b/tools/release.py @@ -73,7 +73,7 @@ codename = None data = open('CMakeLists.txt', 'r').readlines() for i in range(len(data)): - m = re.match(r'^set\(COLOBOT_VERSION_(MAJOR|MINOR|REVISION)( +)([0-9]+)\)$', data[i]) + m = re.match(r'^set\(COLOBOT_VERSION_(MAJOR|MINOR|REVISION)( +)([0-9]+(\.[0-9]+)?)\)$', data[i]) if m: x = m.group(3) if m.group(1) == 'MAJOR': From ef6b692d41121d9a8a67450c98a1b13891db0ed3 Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Sat, 23 Feb 2019 20:01:33 +0100 Subject: [PATCH 089/109] Post-release 0.1.12-alpha --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c40e085..887cf06d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,9 +16,9 @@ set(COLOBOT_VERSION_MINOR 1) set(COLOBOT_VERSION_REVISION 12) # Used on official releases -set(COLOBOT_VERSION_RELEASE_CODENAME "-alpha") +#set(COLOBOT_VERSION_RELEASE_CODENAME "-alpha") # Used on unreleased, development builds -#set(COLOBOT_VERSION_UNRELEASED "+alpha") +set(COLOBOT_VERSION_UNRELEASED "+alpha") # Append git characteristics to version if(DEFINED COLOBOT_VERSION_UNRELEASED) From d4ab82eaae32fa3a68d0699a941db67bc7fb9c18 Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Sat, 23 Feb 2019 20:01:33 +0100 Subject: [PATCH 090/109] Release 0.1.12-alpha: Bump version --- CMakeLists.txt | 6 +++--- data | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8881e0e3..0c40e085 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,12 +13,12 @@ project(colobot C CXX) set(COLOBOT_VERSION_CODENAME "Gold") set(COLOBOT_VERSION_MAJOR 0) set(COLOBOT_VERSION_MINOR 1) -set(COLOBOT_VERSION_REVISION 11.1) +set(COLOBOT_VERSION_REVISION 12) # Used on official releases -#set(COLOBOT_VERSION_RELEASE_CODENAME "-alpha") +set(COLOBOT_VERSION_RELEASE_CODENAME "-alpha") # Used on unreleased, development builds -set(COLOBOT_VERSION_UNRELEASED "+alpha") +#set(COLOBOT_VERSION_UNRELEASED "+alpha") # Append git characteristics to version if(DEFINED COLOBOT_VERSION_UNRELEASED) diff --git a/data b/data index dd12dbe3..c467bd99 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit dd12dbe39a7ad896ac6c73fd4e40c333259e1c84 +Subproject commit c467bd994e60fb54cf977fbe8583f92957330695 From d038d18943c8b535143bb1ffa8ce5739fcc0b64d Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Mon, 25 Feb 2019 19:31:16 +0100 Subject: [PATCH 091/109] Add trailing ; to Keywords entry in colobot.desktop Related issue: #1246 --- desktop/colobot.ini | 2 +- desktop/po/colobot-desktop.pot | 2 +- desktop/po/fr.po | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/desktop/colobot.ini b/desktop/colobot.ini index 0cba2158..3a78019a 100644 --- a/desktop/colobot.ini +++ b/desktop/colobot.ini @@ -1,4 +1,4 @@ Name="Colobot" GenericName="Game to learn programming" Comment="Colonize with bots" -Keywords="robots;3d;space;astronaut;java;c++" +Keywords="robots;3d;space;astronaut;java;c++;" diff --git a/desktop/po/colobot-desktop.pot b/desktop/po/colobot-desktop.pot index 52e6e1a8..c33ab83d 100644 --- a/desktop/po/colobot-desktop.pot +++ b/desktop/po/colobot-desktop.pot @@ -37,7 +37,7 @@ msgstr "" #. type: Keywords= #: colobot.ini:4 #, no-wrap -msgid "robots;3d;space;astronaut;java;c++" +msgid "robots;3d;space;astronaut;java;c++;" msgstr "" #. type: =head1 diff --git a/desktop/po/fr.po b/desktop/po/fr.po index 5032271f..1da026a4 100644 --- a/desktop/po/fr.po +++ b/desktop/po/fr.po @@ -37,8 +37,8 @@ msgstr "Colonise avec des roBots" #. type: Keywords= #: colobot.ini:4 #, no-wrap -msgid "robots;3d;space;astronaut;java;c++" -msgstr "robots;3d;espace;astronaute;cosmonaute;java;c++" +msgid "robots;3d;space;astronaut;java;c++;" +msgstr "robots;3d;espace;astronaute;cosmonaute;java;c++;" #. type: =head1 #: colobot.pod:3 From 16a1dc7b9d6dfaf56764802fde4d944d26f98149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Kapu=C5=9Bci=C5=84ski?= Date: Mon, 4 Mar 2019 21:40:59 +0100 Subject: [PATCH 092/109] Removed unnecessary dependency on libwebp which causes compilation problems with static builds. --- src/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c58172bd..5c014445 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,7 +63,6 @@ elseif(PLATFORM_WINDOWS) find_library(BZ2_LIBRARY NAMES bz2.lib) find_library(JPEG_LIBRARY NAMES jpeg.lib) find_library(TIFF_LIBRARY NAMES tiff.lib) - find_library(WEBP_LIBRARY NAMES webp.lib) find_library(LZMA_LIBRARY NAMES lzma.lib) find_library(FREETYPE_LIBRARY NAMES freetype.lib) set(MSVC_LIBS @@ -72,7 +71,6 @@ elseif(PLATFORM_WINDOWS) ${JPEG_LIBRARY} ${TIFF_LIBRARY} ${BZ2_LIBRARY} - ${WEBP_LIBRARY} ${LZMA_LIBRARY} ${FREETYPE_LIBRARY} winmm.lib From 44083053ce13662e91415a7bdc676718fbf5984b Mon Sep 17 00:00:00 2001 From: fernape Date: Sat, 9 Mar 2019 19:04:00 +0100 Subject: [PATCH 093/109] Add FreeBSD support. Add a new PLATFORM_FREEBSD variable. We can compile like MacOS with just an extra linker flag. --- CMakeLists.txt | 24 ++++++++++++++++++++++++ src/CMakeLists.txt | 4 ++++ 2 files changed, 28 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c40e085..306d18f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,6 +60,7 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES "Windows") set(PLATFORM_GNU 0) set(PLATFORM_LINUX 0) set(PLATFORM_MACOSX 0) + set(PLATFORM_FREEBSD 0) set(PLATFORM_OTHER 0) # Platform-dependent implementation of system.h @@ -71,6 +72,7 @@ elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") set(PLATFORM_LINUX 1) set(PLATFORM_GNU 1) set(PLATFORM_MACOSX 0) + set(PLATFORM_FREEBSD 0) set(PLATFORM_OTHER 0) # Platform-dependent implementation of system.h @@ -82,6 +84,7 @@ elseif("${CMAKE_SYSTEM_NAME}" MATCHES "kFreeBSD" OR "${CMAKE_SYSTEM_NAME}" STREQ set(PLATFORM_LINUX 0) set(PLATFORM_GNU 1) set(PLATFORM_MACOSX 0) + set(PLATFORM_FREEBSD 0) set(PLATFORM_OTHER 0) # Platform-dependent implementation of system.h @@ -94,18 +97,35 @@ elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin") set(PLATFORM_GNU 0) set(PLATFORM_MACOSX 1) set(PLATFORM_OTHER 0) + set(PLATFORM_FREEBSD 0) # Platform-dependent implementation of system.h set(SYSTEM_CPP_MODULE "system_macosx.cpp") set(SYSTEM_H_MODULE "system_macosx.h") # To avoid CMake warning set(CMAKE_MACOSX_RPATH 1) +elseif("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD") + message(STATUS "Build for FreeBSD system") + set(PLATFORM_WINDOWS 0) + set(PLATFORM_LINUX 0) + set(PLATFORM_GNU 0) + set(PLATFORM_MACOSX 0) + set(PLATFORM_FREEBSD 1) + set(PLATFORM_OTHER 0) + + # Platform-dependent implementation of system.h + # On FreeBSD we can use *_other + set(SYSTEM_CPP_MODULE "system_other.cpp") + set(SYSTEM_H_MODULE "system_other.h") + # To avoid CMake warning + set(CMAKE_MACOSX_RPATH 1) else() message(STATUS "Build for other system") set(PLATFORM_WINDOWS 0) set(PLATFORM_LINUX 0) set(PLATFORM_GNU 0) set(PLATFORM_MACOSX 0) + set(PLATFORM_FREEBSD 0) set(PLATFORM_OTHER 1) # Platform-dependent implementation of system.h @@ -153,6 +173,10 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") message(STATUS "Detected Clang version 3.1+") + if (${PLATFORM_FREEBSD}) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=bfd") + endif() + set(NORMAL_CXX_FLAGS "-std=c++11 -Wall -Werror -Wold-style-cast -pedantic-errors -Wmissing-prototypes") set(NORMAL_CXX_FLAGS "${NORMAL_CXX_FLAGS} -Wno-error=deprecated-declarations") # updated version of physfs is not available on some platforms so we keep using deprecated functions, see #958 set(RELEASE_CXX_FLAGS "-O2") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c58172bd..7f75a7e1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -101,6 +101,10 @@ elseif(PLATFORM_MACOSX) find_library(LIBINTL_LIBRARY NAMES intl libintl) find_path(LIBINTL_INCLUDE_PATH NAMES libintl.h) set(PLATFORM_LIBS ${LIBINTL_LIBRARY}) +elseif(PLATFORM_FREEBSD) + find_library(LIBINTL_LIBRARY NAMES intl libintl) + find_path(LIBINTL_INCLUDE_PATH NAMES libintl.h) + set(PLATFORM_LIBS ${LIBINTL_LIBRARY}) endif() From a66b3d06723a5e97655c65e178ceb2f05da1a233 Mon Sep 17 00:00:00 2001 From: melex750 Date: Thu, 11 Apr 2019 04:13:13 -0400 Subject: [PATCH 094/109] Refactor SaveState and RestoreState to use streams --- src/CBot/CBotClass.cpp | 40 +- src/CBot/CBotClass.h | 16 +- src/CBot/CBotFileUtils.cpp | 380 ++++++++++++------ src/CBot/CBotFileUtils.h | 217 ++++++---- src/CBot/CBotProgram.cpp | 42 +- src/CBot/CBotProgram.h | 15 +- src/CBot/CBotStack.cpp | 157 ++++---- src/CBot/CBotStack.h | 4 +- src/CBot/CBotUtils.cpp | 32 -- src/CBot/CBotUtils.h | 29 +- src/CBot/CBotVar/CBotVar.cpp | 2 +- src/CBot/CBotVar/CBotVar.h | 12 +- src/CBot/CBotVar/CBotVarArray.cpp | 7 +- src/CBot/CBotVar/CBotVarArray.h | 2 +- src/CBot/CBotVar/CBotVarBoolean.cpp | 4 +- src/CBot/CBotVar/CBotVarBoolean.h | 2 +- src/CBot/CBotVar/CBotVarClass.cpp | 10 +- src/CBot/CBotVar/CBotVarClass.h | 2 +- src/CBot/CBotVar/CBotVarFloat.cpp | 4 +- src/CBot/CBotVar/CBotVarFloat.h | 2 +- src/CBot/CBotVar/CBotVarInt.cpp | 19 +- src/CBot/CBotVar/CBotVarInt.h | 4 +- src/CBot/CBotVar/CBotVarPointer.cpp | 11 +- src/CBot/CBotVar/CBotVarPointer.h | 2 +- src/CBot/CBotVar/CBotVarString.cpp | 4 +- src/CBot/CBotVar/CBotVarString.h | 2 +- src/CBot/CBotVar/CBotVarValue.h | 5 +- src/level/robotmain.cpp | 112 ++++-- src/level/robotmain.h | 4 +- .../implementation/programmable_impl.cpp | 45 ++- src/object/implementation/programmable_impl.h | 4 +- src/object/interface/programmable_object.h | 4 +- src/script/script.cpp | 20 +- src/script/script.h | 4 +- test/unit/CBot/CBot_test.cpp | 32 +- test/unit/main.cpp | 10 + 36 files changed, 767 insertions(+), 494 deletions(-) diff --git a/src/CBot/CBotClass.cpp b/src/CBot/CBotClass.cpp index f1a658ad..628bb907 100644 --- a/src/CBot/CBotClass.cpp +++ b/src/CBot/CBotClass.cpp @@ -36,7 +36,6 @@ #include "CBot/CBotCStack.h" #include "CBot/CBotDefParam.h" #include "CBot/CBotUtils.h" -#include "CBot/CBotFileUtils.h" #include @@ -364,69 +363,70 @@ void CBotClass::RestoreMethode(long& nIdent, } //////////////////////////////////////////////////////////////////////////////// -bool CBotClass::SaveStaticState(FILE* pf) +bool CBotClass::SaveStaticState(std::ostream &ostr) { - if (!WriteWord( pf, CBOTVERSION*2)) return false; + if (!WriteLong(ostr, CBOTVERSION*2)) return false; // saves the state of static variables in classes for (CBotClass* p : m_publicClasses) { - if (!WriteWord( pf, 1 )) return false; + if (!WriteWord(ostr, 1)) return false; // save the name of the class - if (!WriteString( pf, p->GetName() )) return false; + if (!WriteString(ostr, p->GetName())) return false; CBotVar* pv = p->GetVar(); while( pv != nullptr ) { if ( pv->IsStatic() ) { - if (!WriteWord( pf, 1 )) return false; - if (!WriteString( pf, pv->GetName() )) return false; + if (!WriteWord(ostr, 1)) return false; + if (!WriteString(ostr, pv->GetName())) return false; - if ( !pv->Save0State(pf) ) return false; // common header - if ( !pv->Save1State(pf) ) return false; // saves as the child class - if ( !WriteWord( pf, 0 ) ) return false; + if (!pv->Save0State(ostr)) return false; // common header + if (!pv->Save1State(ostr)) return false; // saves as the child class + if (!WriteWord(ostr, 0)) return false; } pv = pv->GetNext(); } - if (!WriteWord( pf, 0 )) return false; + if (!WriteWord(ostr, 0)) return false; } - if (!WriteWord( pf, 0 )) return false; + if (!WriteWord(ostr, 0)) return false; return true; } //////////////////////////////////////////////////////////////////////////////// -bool CBotClass::RestoreStaticState(FILE* pf) +bool CBotClass::RestoreStaticState(std::istream &istr) { std::string ClassName, VarName; CBotClass* pClass; unsigned short w; - if (!ReadWord( pf, w )) return false; - if ( w != CBOTVERSION*2 ) return false; + long version; + if (!ReadLong(istr, version)) return false; + if (version != CBOTVERSION*2) return false; while (true) { - if (!ReadWord( pf, w )) return false; + if (!ReadWord(istr, w)) return false; if ( w == 0 ) return true; - if (!ReadString( pf, ClassName )) return false; + if (!ReadString(istr, ClassName)) return false; pClass = Find(ClassName); while (true) { - if (!ReadWord( pf, w )) return false; + if (!ReadWord(istr, w)) return false; if ( w == 0 ) break; CBotVar* pVar = nullptr; CBotVar* pv = nullptr; - if (!ReadString( pf, VarName )) return false; + if (!ReadString(istr, VarName)) return false; if ( pClass != nullptr ) pVar = pClass->GetItem(VarName); - if (!CBotVar::RestoreState(pf, pv)) return false; // the temp variable + if (!CBotVar::RestoreState(istr, pv)) return false; // the temp variable if ( pVar != nullptr ) pVar->Copy(pv); delete pv; diff --git a/src/CBot/CBotClass.h b/src/CBot/CBotClass.h index 0f9a8ce4..eeafe2d1 100644 --- a/src/CBot/CBotClass.h +++ b/src/CBot/CBotClass.h @@ -331,18 +331,18 @@ public: static void ClearPublic(); /*! - * \brief SaveStaticState - * \param pf - * \return + * \brief Save all static variables from each public class + * \param ostr Output stream + * \return true on success */ - static bool SaveStaticState(FILE* pf); + static bool SaveStaticState(std::ostream &ostr); /*! - * \brief RestoreStaticState - * \param pf - * \return + * \brief Restore all static variables in each public class + * \param istr Input stream + * \return true on success */ - static bool RestoreStaticState(FILE* pf); + static bool RestoreStaticState(std::istream &istr); /** * \brief Request a lock on this class (for "synchronized" keyword) diff --git a/src/CBot/CBotFileUtils.cpp b/src/CBot/CBotFileUtils.cpp index c473493a..ccde313c 100644 --- a/src/CBot/CBotFileUtils.cpp +++ b/src/CBot/CBotFileUtils.cpp @@ -21,129 +21,251 @@ #include "CBot/CBotClass.h" #include "CBot/CBotEnums.h" -#include "CBot/CBotUtils.h" namespace CBot { - -// file management - -// necessary because it is not possible to do the fopen in the main program -// fwrite and fread in a dll or using the FILE * returned. - -//////////////////////////////////////////////////////////////////////////////// -FILE* fOpen(const char* name, const char* mode) +template +static bool WriteBinary(std::ostream &ostr, T value, unsigned padTo = 0) { - return fopen(name, mode); -} - -//////////////////////////////////////////////////////////////////////////////// -int fClose(FILE* filehandle) -{ - return fclose(filehandle); -} - -//////////////////////////////////////////////////////////////////////////////// -std::size_t fWrite(const void *buffer, - std::size_t elemsize, - std::size_t length, - FILE* filehandle) -{ - return fwrite(buffer, elemsize, length, filehandle); -} - -//////////////////////////////////////////////////////////////////////////////// -std::size_t fRead(void *buffer, - std::size_t elemsize, - std::size_t length, - FILE* filehandle) -{ - return fread(buffer, elemsize, length, filehandle); -} - - -//////////////////////////////////////////////////////////////////////////////// -bool ReadWord(FILE* pf, unsigned short& w) -{ - size_t lg; - - lg = fread(&w, sizeof( unsigned short ), 1, pf ); - - return (lg == 1); -} - -//////////////////////////////////////////////////////////////////////////////// -bool ReadFloat(FILE* pf, float& w) -{ - size_t lg; - - lg = fread(&w, sizeof( float ), 1, pf ); - - return (lg == 1); -} - -//////////////////////////////////////////////////////////////////////////////// -bool WriteLong(FILE* pf, long w) -{ - size_t lg; - - lg = fwrite(&w, sizeof( long ), 1, pf ); - - return (lg == 1); -} - -//////////////////////////////////////////////////////////////////////////////// -bool ReadLong(FILE* pf, long& w) -{ - size_t lg; - - lg = fread(&w, sizeof( long ), 1, pf ); - - return (lg == 1); -} - -//////////////////////////////////////////////////////////////////////////////// -bool ReadString(FILE* pf, std::string& s) -{ - unsigned short w; - char buf[1000]; - size_t lg1, lg2; - - if (!ReadWord(pf, w)) return false; - lg1 = w; - lg2 = fread(buf, 1, lg1, pf ); - buf[lg2] = 0; - - s = buf; - return (lg1 == lg2); -} - -//////////////////////////////////////////////////////////////////////////////// -bool WriteType(FILE* pf, const CBotTypResult &type) -{ - int typ = type.GetType(); - if ( typ == CBotTypIntrinsic ) typ = CBotTypClass; - if ( !WriteWord(pf, typ) ) return false; - if ( typ == CBotTypClass ) + unsigned char chr; + unsigned count = 1; + while (value > 127) // unsigned LEB128 { - CBotClass* p = type.GetClass(); - if ( !WriteString(pf, p->GetName()) ) return false; + ++count; + chr = (value & 0x7F) | 0x80; + if (!ostr.write(reinterpret_cast(&chr), 1)) return false; + value >>= 7; } - if ( type.Eq( CBotTypArrayBody ) || - type.Eq( CBotTypArrayPointer ) ) + chr = value & 0x7F; + if (count < padTo) chr |= 0x80; + if (!ostr.write(reinterpret_cast(&chr), 1)) return false; + + if (count < padTo) { - if ( !WriteWord(pf, type.GetLimite()) ) return false; - if ( !WriteType(pf, type.GetTypElem()) ) return false; + while (++count < padTo) + if (!(ostr << '\x80')) return false; + if (!(ostr << '\x00')) return false; } return true; } -//////////////////////////////////////////////////////////////////////////////// -bool ReadType(FILE* pf, CBotTypResult &type) +template +static bool ReadBinary(std::istream &istr, T &value) +{ + value = 0; + unsigned char chr; + unsigned shift = 0; + while (true) // unsigned LEB128 + { + if (!istr.read(reinterpret_cast(&chr), 1)) return false; + if (shift < sizeof(T) * 8 - 1) + value |= static_cast(chr & 0x7F) << shift; + shift += 7; + if ((chr & 0x80) == 0) break; + } + return true; +} + +template +static bool WriteSignedBinary(std::ostream &ostr, T value, unsigned padTo = 0) +{ + signed char sign = value >> (8 * sizeof(T) - 1); + unsigned count = 0; + while (true) // signed LEB128 + { + ++count; + unsigned char chr = value & 0x7F; + value >>= 7; + if (!(value != sign || ((chr ^ sign) & 0x40) != 0)) + { + if (count < padTo) chr |= 0x80; + if (!ostr.write(reinterpret_cast(&chr), 1)) return false; + break; + } + chr |= 0x80; + if (!ostr.put(chr)) return false; + } + + if (count < padTo) + { + char chr = (sign < 0) ? 0x7F : 0x00; + while (++count < padTo) + if (!ostr.put(chr | 0x80)) return false; + if (!ostr.put(chr)) return false; + } + return true; +} + +template +static bool ReadSignedBinary(std::istream &istr, T &value) +{ + value = 0; + unsigned char chr; + unsigned shift = 0; + while (true) // signed LEB128 + { + if (!istr.read(reinterpret_cast(&chr), 1)) return false; + if (shift < sizeof(T) * 8 - 1) + value |= (static_cast(chr & 0x7F) << shift); + shift += 7; + if ((chr & 0x80) == 0) break; + } + + if (shift >= 8 * sizeof(T) - 1) shift = 8 * sizeof(T) - 1; + if ((chr & 0x40) != 0) + value |= static_cast(-1) << shift; + + return true; +} + +bool WriteWord(std::ostream &ostr, unsigned short w) +{ + return WriteBinary(ostr, w); +} + +bool ReadWord(std::istream &istr, unsigned short &w) +{ + return ReadBinary(istr, w); +} + +bool WriteByte(std::ostream &ostr, char c) +{ + if (!ostr.put(c)) return false; + return true; +} + +bool ReadByte(std::istream &istr, char& c) +{ + if (!istr.get(c)) return false; + return true; +} + +bool WriteShort(std::ostream &ostr, short s) +{ + return WriteSignedBinary(ostr, s); +} + +bool ReadShort(std::istream &istr, short &s) +{ + return ReadSignedBinary(istr, s); +} + +bool WriteInt(std::ostream &ostr, int i) +{ + return WriteSignedBinary(ostr, i); +} + +bool ReadInt(std::istream &istr, int &i) +{ + return ReadSignedBinary(istr, i); +} + +bool WriteLong(std::ostream &ostr, long l, unsigned padTo) +{ + return WriteSignedBinary(ostr, l, padTo); +} + +bool ReadLong(std::istream &istr, long &l) +{ + return ReadSignedBinary(istr, l); +} + +bool WriteFloat(std::ostream &ostr, float f) +{ + union {float fValue; unsigned int iValue;} u; + u.fValue = 0.0f; + u.iValue = 0; + + u.fValue = f; + return WriteBinary(ostr, u.iValue); +} + +bool ReadFloat(std::istream &istr, float &f) +{ + union {float fValue; unsigned int iValue;} u; + u.fValue = 0.0f; + u.iValue = 0; + + if (!ReadBinary(istr, u.iValue)) return false; + f = u.fValue; + return true; +} + +bool WriteDouble(std::ostream &ostr, double d) +{ + union {double dValue; unsigned long iValue;} u; + u.dValue = 0.0; + u.iValue = 0; + + u.dValue = d; + return WriteBinary(ostr, u.iValue); +} + +bool ReadDouble(std::istream &istr, double &d) +{ + union {double dValue; unsigned long iValue;} u; + u.dValue = 0.0; + u.iValue = 0; + + if (!ReadBinary(istr, u.iValue)) return false; + d = u.dValue; + return true; +} + +bool WriteString(std::ostream &ostr, const std::string &s) +{ + if (!WriteBinary(ostr, s.size())) return false; + if (!ostr.write(&(s[0]), s.size())) return false; + + return true; +} + +bool ReadString(std::istream &istr, std::string &s) +{ + size_t length = 0; + if (!ReadBinary(istr, length)) return false; + + s.resize(length); + if (length != 0) + { + if (!istr.read(&(s[0]), length)) return false; + } + return true; +} + +bool WriteType(std::ostream &ostr, const CBotTypResult &type) +{ + int typ = type.GetType(); + if ( typ == CBotTypIntrinsic ) typ = CBotTypClass; + if ( !WriteWord(ostr, typ) ) return false; + if ( typ == CBotTypClass ) + { + CBotClass* p = type.GetClass(); + if (!WriteString(ostr, p->GetName())) return false; + } + if ( type.Eq( CBotTypArrayBody ) || + type.Eq( CBotTypArrayPointer ) ) + { + if (!WriteWord(ostr, type.GetLimite())) return false; + if (!WriteType(ostr, type.GetTypElem())) return false; + } + + if ( type.Eq(CBotTypPointer) ) + { + if (type.GetClass() != nullptr) + { + if (!WriteString(ostr, type.GetClass()->GetName())) return false; + } + else if (!WriteString(ostr, "")) return false; + } + return true; +} + +bool ReadType(std::istream &istr, CBotTypResult &type) { unsigned short w, ww; - if ( !ReadWord(pf, w) ) return false; + if (!ReadWord(istr, w)) return false; type.SetType(w); if ( type.Eq( CBotTypIntrinsic ) ) @@ -154,7 +276,7 @@ bool ReadType(FILE* pf, CBotTypResult &type) if ( type.Eq( CBotTypClass ) ) { std::string s; - if ( !ReadString(pf, s) ) return false; + if (!ReadString(istr, s)) return false; type = CBotTypResult( w, s ); } @@ -162,11 +284,45 @@ bool ReadType(FILE* pf, CBotTypResult &type) type.Eq( CBotTypArrayBody ) ) { CBotTypResult r; - if ( !ReadWord(pf, ww) ) return false; - if ( !ReadType(pf, r) ) return false; + if (!ReadWord(istr, ww)) return false; + if (!ReadType(istr, r)) return false; type = CBotTypResult( w, r ); type.SetLimite(static_cast(ww)); } + + if ( type.Eq(CBotTypPointer) ) + { + std::string className; + if (!ReadString(istr, className)) return false; + type = CBotTypResult(w, className); + } + return true; +} + +bool WriteStream(std::ostream &ostr, std::istream& istr) +{ + if (!istr.seekg(0, istr.end)) return false; + auto size = istr.tellg(); + + if (size == 0) return WriteLong(ostr, 0); + if (!WriteLong(ostr, size)) return false; + + if (!istr.seekg(0, istr.beg)) return false; + if (!(ostr << istr.rdbuf())) return false; + + return true; +} + +bool ReadStream(std::istream& istr, std::ostream &ostr) +{ + long length; + if (!ReadLong(istr, length)) return false; + if (length == 0) return true; + + while (length-- > 0) + { + if (!(ostr << istr.get())) return false; + } return true; } diff --git a/src/CBot/CBotFileUtils.h b/src/CBot/CBotFileUtils.h index fec6298a..8f739cb4 100644 --- a/src/CBot/CBotFileUtils.h +++ b/src/CBot/CBotFileUtils.h @@ -19,7 +19,7 @@ #pragma once -#include +#include #include namespace CBot @@ -28,128 +28,173 @@ namespace CBot class CBotVar; class CBotTypResult; -/////////////////////////////////////////////////////////////////////////////// -// routines for file management (* FILE) - /*! - * \brief fOpen - * \param name - * \param mode - * \return + * \brief Save a linked list if variables + * \param ostr Output stream + * \param pVar First variable in the list + * \return true on success */ -FILE* fOpen(const char* name, const char* mode); - -/*! - * \brief fClose - * \param filehandle - * \return - */ -int fClose(FILE* filehandle); - -/*! - * \brief fWrite - * \param buffer - * \param elemsize - * \param length - * \param filehandle - * \return - */ -std::size_t fWrite(const void *buffer, - std::size_t elemsize, - std::size_t length, - FILE* filehandle); - -/*! - * \brief fRead - * \param buffer - * \param elemsize - * \param length - * \param filehandle - * \return - */ -std::size_t fRead(void *buffer, - std::size_t elemsize, - std::size_t length, - FILE* filehandle); - -/*! - * \brief SaveVars - * \param pf - * \param pVar - * \return - */ -bool SaveVars(FILE* pf, CBotVar* pVar); +bool SaveVars(std::ostream &ostr, CBotVar* pVar); /*! * \brief WriteWord - * \param pf + * \param ostr Output stream * \param w - * \return + * \return true on success */ -bool WriteWord(FILE* pf, unsigned short w); +bool WriteWord(std::ostream &ostr, unsigned short w); /*! * \brief ReadWord - * \param pf - * \param w - * \return + * \param istr Input stream + * \param[out] w + * \return true on success */ -bool ReadWord(FILE* pf, unsigned short& w); +bool ReadWord(std::istream &istr, unsigned short &w); /*! - * \brief ReadLong - * \param pf - * \param w - * \return + * \brief WriteByte + * \param ostr Output stream + * \param c + * \return true on success */ -bool ReadLong(FILE* pf, long& w); +bool WriteByte(std::ostream &ostr, char c); /*! - * \brief WriteFloat - * \param pf - * \param w - * \return + * \brief ReadByte + * \param istr Input stream + * \param[out] c + * \return true on success */ -bool WriteFloat(FILE* pf, float w); +bool ReadByte(std::istream &istr, char& c); + +/*! + * \brief WriteShort + * \param ostr Output stream + * \param s + * \return true on success + */ +bool WriteShort(std::ostream &ostr, short s); + +/*! + * \brief ReadShort + * \param istr Input stream + * \param[out] s + * \return true on success + */ +bool ReadShort(std::istream &istr, short &s); + +/*! + * \brief WriteInt + * \param ostr Output stream + * \param i + * \return true on success + */ +bool WriteInt(std::ostream &ostr, int i); + +/*! + * \brief ReadInt + * \param istr Input stream + * \param[out] i + * \return true on success + */ +bool ReadInt(std::istream &istr, int &i); /*! * \brief WriteLong - * \param pf - * \param w - * \return + * \param ostr Output stream + * \param l + * \param padTo minimum number of bytes to write + * \return true on success */ -bool WriteLong(FILE* pf, long w); +bool WriteLong(std::ostream &ostr, long l, unsigned padTo = 0); + +/*! + * \brief ReadLong + * \param istr Input stream + * \param[out] l + * \return true on success + */ +bool ReadLong(std::istream &istr, long &l); + +/*! + * \brief WriteFloat + * \param ostr Output stream + * \param f + * \return true on success + */ +bool WriteFloat(std::ostream &ostr, float f); /*! * \brief ReadFloat - * \param pf - * \param w - * \return + * \param istr Input stream + * \param[out] f + * \return true on success */ -bool ReadFloat(FILE* pf, float& w); +bool ReadFloat(std::istream &istr, float &f); + +/*! + * \brief WriteDouble + * \param ostr Output stream + * \param d + * \return true on success + */ +bool WriteDouble(std::ostream &ostr, double d); + +/*! + * \brief ReadDouble + * \param istr Input stream + * \param[out] d + * \return true on success + */ +bool ReadDouble(std::istream &istr, double &d); + +/*! + * \brief WriteString + * \param ostr Output stream + * \param s + * \return true on success + */ +bool WriteString(std::ostream &ostr, const std::string &s); /*! * \brief ReadString - * \param pf - * \param s - * \return + * \param istr Input stream + * \param[out] s + * \return true on success */ -bool ReadString(FILE* pf, std::string& s); +bool ReadString(std::istream &istr, std::string &s); /*! * \brief WriteType - * \param pf + * \param ostr Output stream * \param type - * \return + * \return true on success */ -bool WriteType(FILE* pf, const CBotTypResult &type); +bool WriteType(std::ostream &ostr, const CBotTypResult &type); /*! * \brief ReadType - * \param pf - * \param type - * \return + * \param istr Input stream + * \param[out] type + * \return true on success */ -bool ReadType(FILE* pf, CBotTypResult &type); +bool ReadType(std::istream &istr, CBotTypResult &type); + +/*! + * \brief WriteStream + * \param ostr Output stream + * \param istr Input stream + * \return true on success + */ +bool WriteStream(std::ostream &ostr, std::istream& istr); + +/*! + * \brief ReadStream + * \param istr Input stream + * \param ostr Output stream + * \return true on success + */ +bool ReadStream(std::istream& istr, std::ostream &ostr); } // namespace CBot diff --git a/src/CBot/CBotProgram.cpp b/src/CBot/CBotProgram.cpp index e8065f47..14ec2b2e 100644 --- a/src/CBot/CBotProgram.cpp +++ b/src/CBot/CBotProgram.cpp @@ -24,7 +24,6 @@ #include "CBot/CBotCStack.h" #include "CBot/CBotClass.h" #include "CBot/CBotUtils.h" -#include "CBot/CBotFileUtils.h" #include "CBot/CBotInstr/CBotFunction.h" @@ -332,51 +331,56 @@ bool CBotProgram::DefineNum(const std::string& name, long val) } //////////////////////////////////////////////////////////////////////////////// -bool CBotProgram::SaveState(FILE* pf) +bool CBotProgram::SaveState(std::ostream &ostr) { - if (!WriteWord( pf, CBOTVERSION)) return false; + if (!WriteLong(ostr, CBOTVERSION)) return false; if (m_stack != nullptr ) { - if (!WriteWord( pf, 1)) return false; - if (!WriteString( pf, m_entryPoint->GetName() )) return false; - if (!m_stack->SaveState(pf)) return false; + if (!WriteWord(ostr, 1)) return false; + if (!WriteString(ostr, m_entryPoint->GetName())) return false; + if (!m_stack->SaveState(ostr)) return false; } else { - if (!WriteWord( pf, 0)) return false; + if (!WriteWord(ostr, 0)) return false; } return true; } -bool CBotProgram::RestoreState(FILE* pf) +bool CBotProgram::RestoreState(std::istream &istr) { unsigned short w; std::string s; Stop(); - if (!ReadWord( pf, w )) return false; - if ( w != CBOTVERSION ) return false; + long version; + if (!ReadLong(istr, version)) return false; + if ( version != CBOTVERSION ) return false; - if (!ReadWord( pf, w )) return false; + if (!ReadWord(istr, w)) return false; if ( w == 0 ) return true; - if (!ReadString( pf, s )) return false; - Start(s); // point de reprise + // don't restore if compile error exists + if (m_error != CBotNoErr) return false; - if (m_stack != nullptr) + if (!ReadString(istr, s)) return false; + if (!Start(s)) return false; // point de reprise + // Start() already created the new stack + // and called m_stack->SetProgram(this); + + // retrieves the stack from the memory + if (!m_stack->RestoreState(istr, m_stack)) { m_stack->Delete(); m_stack = nullptr; + m_stack = CBotStack::AllocateStack(); // start from the top + m_stack->SetProgram(this); + return false; // signal error } - // retrieves the stack from the memory - m_stack = CBotStack::AllocateStack(); - if (!m_stack->RestoreState(pf, m_stack)) return false; - m_stack->SetProgram(this); // bases for routines - // restored some states in the stack according to the structure m_entryPoint->RestoreState(nullptr, m_stack, m_thisVar); return true; diff --git a/src/CBot/CBotProgram.h b/src/CBot/CBotProgram.h index e258fff0..c448b82c 100644 --- a/src/CBot/CBotProgram.h +++ b/src/CBot/CBotProgram.h @@ -282,27 +282,20 @@ public: /** * \brief Save the current execution status into a file - * \param pf - * \parblock - * file handle - * - * This file handle must have been opened by this library! Otherwise crashes on Windows - * - * TODO: Verify this - * \endparblock + * \param ostr Output stream * \return true on success, false on write error */ - bool SaveState(FILE* pf); + bool SaveState(std::ostream &ostr); /** * \brief Restore the execution state from a file * * The previous program code must already have been recompiled with Compile() before calling this function * - * \param pf file handle + * \param istr Input stream * \return true on success, false on read error */ - bool RestoreState(FILE* pf); + bool RestoreState(std::istream &istr); /** * \brief GetPosition Gives the position of a routine in the original text diff --git a/src/CBot/CBotStack.cpp b/src/CBot/CBotStack.cpp index 9f9db2d6..7f3c0b9a 100644 --- a/src/CBot/CBotStack.cpp +++ b/src/CBot/CBotStack.cpp @@ -26,7 +26,6 @@ #include "CBot/CBotVar/CBotVarPointer.h" #include "CBot/CBotVar/CBotVarClass.h" -#include "CBot/CBotFileUtils.h" #include "CBot/CBotUtils.h" #include "CBot/CBotExternalCall.h" @@ -687,108 +686,106 @@ CBotVar* CBotStack::GetStackVars(std::string& functionName, int level) } //////////////////////////////////////////////////////////////////////////////// -bool CBotStack::SaveState(FILE* pf) +bool CBotStack::SaveState(std::ostream &ostr) { if (m_next2 != nullptr) { - if (!WriteWord(pf, 2)) return false; // a marker of type (m_next2) - if (!m_next2->SaveState(pf)) return false; // saves the next element + if (!WriteWord(ostr, 2)) return false; // a marker of type (m_next2) + if (!m_next2->SaveState(ostr)) return false; // saves the next element } else { - if (!WriteWord(pf, 1)) return false; // a marker of type (m_next) + if (!WriteWord(ostr, 1)) return false; // a marker of type (m_next) } - if (!WriteWord(pf, static_cast(m_block))) return false; - if (!WriteWord(pf, m_state)) return false; - if (!WriteWord(pf, 0)) return false; // for backwards combatibility (m_bDontDelete) - if (!WriteWord(pf, m_step)) return false; + if (!WriteWord(ostr, static_cast(m_block))) return false; + if (!WriteInt(ostr, m_state)) return false; + if (!WriteWord(ostr, 0)) return false; // for backwards combatibility (m_bDontDelete) + if (!WriteInt(ostr, m_step)) return false; - - if (!SaveVars(pf, m_var)) return false; // current result - if (!SaveVars(pf, m_listVar)) return false; // local variables + if (!SaveVars(ostr, m_var)) return false; // current result + if (!SaveVars(ostr, m_listVar)) return false; // local variables if (m_next != nullptr) { - if (!m_next->SaveState(pf)) return false; // saves the next element + if (!m_next->SaveState(ostr)) return false; // saves the next element } else { - if (!WriteWord(pf, 0)) return false; // terminator + if (!WriteWord(ostr, 0)) return false; // 0 - CBotStack::SaveState terminator } return true; } -bool SaveVars(FILE* pf, CBotVar* pVar) +bool SaveVars(std::ostream &ostr, CBotVar* pVar) { while (pVar != nullptr) { - if (!pVar->Save0State(pf)) return false; // common header - if (!pVar->Save1State(pf)) return false; // saves the data + if (!pVar->Save0State(ostr)) return false; // common header + if (!pVar->Save1State(ostr)) return false; // saves the data pVar = pVar->GetNext(); } - return WriteWord(pf, 0); // terminator + return WriteWord(ostr, 0); // 0 - CBot::SaveVars terminator } //////////////////////////////////////////////////////////////////////////////// -bool CBotStack::RestoreState(FILE* pf, CBotStack* &pStack) +bool CBotStack::RestoreState(std::istream &istr, CBotStack* &pStack) { unsigned short w; if (pStack != this) pStack = nullptr; - if (!ReadWord(pf, w)) return false; - if ( w == 0 ) return true; // 0 - terminator + if (!ReadWord(istr, w)) return false; + if ( w == 0 ) return true; // 0 - CBotStack::SaveState terminator if (pStack == nullptr) pStack = AddStack(); if ( w == 2 ) // 2 - m_next2 { - if (!pStack->RestoreState(pf, pStack->m_next2)) return false; + if (!pStack->RestoreState(istr, pStack->m_next2)) return false; } - if (!ReadWord(pf, w)) return false; + if (!ReadWord(istr, w)) return false; pStack->m_block = static_cast(w); - if (!ReadWord(pf, w)) return false; - pStack->SetState(static_cast(w)); + int state; + if (!ReadInt(istr, state)) return false; + pStack->SetState(state); - if (!ReadWord(pf, w)) return false; // backwards compatibility (m_bDontDelete) + if (!ReadWord(istr, w)) return false; // backwards compatibility (m_bDontDelete) - if (!ReadWord(pf, w)) return false; - pStack->m_step = w; + if (!ReadInt(istr, state)) return false; + pStack->m_step = state; - if (!CBotVar::RestoreState(pf, pStack->m_var)) return false; // temp variable - if (!CBotVar::RestoreState(pf, pStack->m_listVar)) return false;// local variables + if (!CBotVar::RestoreState(istr, pStack->m_var)) return false; // temp variable + if (!CBotVar::RestoreState(istr, pStack->m_listVar)) return false; // local variables - return pStack->RestoreState(pf, pStack->m_next); + return pStack->RestoreState(istr, pStack->m_next); } //////////////////////////////////////////////////////////////////////////////// -bool CBotVar::Save0State(FILE* pf) +bool CBotVar::Save0State(std::ostream &ostr) { - if (!WriteWord(pf, 100+static_cast(m_mPrivate)))return false; // private variable? - if (!WriteWord(pf, m_bStatic))return false; // static variable? - if (!WriteWord(pf, m_type.GetType()))return false; // saves the type (always non-zero) + if (!WriteWord(ostr, 100+static_cast(m_mPrivate)))return false; // private variable? + if (!WriteWord(ostr, m_bStatic))return false; // static variable? + if (!WriteWord(ostr, m_type.GetType()))return false; // saves the type (always non-zero) if (m_type.Eq(CBotTypPointer) && GetPointer() != nullptr) { if (GetPointer()->m_bConstructor) // constructor was called? { - if (!WriteWord(pf, (2000 + static_cast(m_binit)) )) return false; - return WriteString(pf, m_token->GetString()); // and variable name + if (!WriteWord(ostr, (2000 + static_cast(m_binit)) )) return false; + return WriteString(ostr, m_token->GetString()); // and variable name } } - if (!WriteWord(pf, static_cast(m_binit))) return false; // variable defined? - return WriteString(pf, m_token->GetString()); // and variable name + if (!WriteWord(ostr, static_cast(m_binit))) return false; // variable defined? + return WriteString(ostr, m_token->GetString()); // and variable name } //////////////////////////////////////////////////////////////////////////////// -bool CBotVar::RestoreState(FILE* pf, CBotVar* &pVar) +bool CBotVar::RestoreState(std::istream &istr, CBotVar* &pVar) { unsigned short w, wi, prv, st; - float ww; - std::string name, s; delete pVar; @@ -798,27 +795,27 @@ bool CBotVar::RestoreState(FILE* pf, CBotVar* &pVar) while ( true ) // retrieves a list { - if (!ReadWord(pf, w)) return false; // private or type? - if ( w == 0 ) return true; + if (!ReadWord(istr, w)) return false; // private or type? + if ( w == 0 ) return true; // 0 - CBot::SaveVars terminator std::string defnum; if ( w == 200 ) { - if (!ReadString(pf, defnum)) return false; // number with identifier - if (!ReadWord(pf, w)) return false; // type + if (!ReadString(istr, defnum)) return false; // number with identifier + if (!ReadWord(istr, w)) return false; // type } prv = 100; st = 0; if ( w >= 100 ) { prv = w; - if (!ReadWord(pf, st)) return false; // static - if (!ReadWord(pf, w)) return false; // type + if (!ReadWord(istr, st)) return false; // static + if (!ReadWord(istr, w)) return false; // type } if ( w == CBotTypClass ) w = CBotTypIntrinsic; // necessarily intrinsic - if (!ReadWord(pf, wi)) return false; // init ? + if (!ReadWord(istr, wi)) return false; // init ? bool bConstructor = false; if (w == CBotTypPointer && wi >= 2000) { @@ -827,31 +824,40 @@ bool CBotVar::RestoreState(FILE* pf, CBotVar* &pVar) } CBotVar::InitType initType = static_cast(wi); - if (!ReadString(pf, name)) return false; // variable name - - CBotToken token(name, std::string()); + std::string varname; + if (!ReadString(istr, varname)) return false; // variable name + CBotToken token(varname, std::string()); bool isClass = false; switch (w) { - case CBotTypInt: case CBotTypBoolean: + char valByte; + if (!ReadByte(istr, valByte)) return false; pNew = CBotVar::Create(token, w); // creates a variable - if (!ReadWord(pf, w)) return false; - pNew->SetValInt(static_cast(w), defnum); + pNew->SetValInt(valByte); + break; + case CBotTypInt: + int valInt; + if (!ReadInt(istr, valInt)) return false; + pNew = CBotVar::Create(token, w); // creates a variable + pNew->SetValInt(valInt, defnum); break; case CBotTypFloat: + float valFloat; + if (!ReadFloat(istr, valFloat)) return false; pNew = CBotVar::Create(token, w); // creates a variable - if (!ReadFloat(pf, ww)) return false; - pNew->SetValFloat(ww); + pNew->SetValFloat(valFloat); break; case CBotTypString: - pNew = CBotVar::Create(token, w); // creates a variable - if (!ReadString(pf, s)) return false; - pNew->SetValString(s); - break; - + { + std::string valString; + if (!ReadString(istr, valString)) return false; + pNew = CBotVar::Create(token, w); // creates a variable + pNew->SetValString(valString); + break; + } // returns an intrinsic object or element of an array case CBotTypIntrinsic: isClass = true; @@ -859,17 +865,16 @@ bool CBotVar::RestoreState(FILE* pf, CBotVar* &pVar) { CBotTypResult r; long id; - if (!ReadType(pf, r)) return false; // complete type - if (!ReadLong(pf, id) ) return false; + if (!ReadType(istr, r)) return false; // complete type + if (!ReadLong(istr, id)) return false; -// if (!ReadString(pf, s)) return false; { CBotVar* p = nullptr; if ( id ) p = CBotVarClass::Find(id) ; pNew = new CBotVarClass(token, r); // directly creates an instance // attention cptuse = 0 - if ( !RestoreState(pf, (static_cast(pNew))->m_pVar)) return false; + if (!RestoreState(istr, (static_cast(pNew))->m_pVar)) return false; pNew->SetIdent(id); if (isClass && p == nullptr) // set id for each item in this instance @@ -895,18 +900,20 @@ bool CBotVar::RestoreState(FILE* pf, CBotVar* &pVar) case CBotTypPointer: case CBotTypNullPointer: - if (!ReadString(pf, s)) return false; // name of the class + { + std::string className; + if (!ReadString(istr, className)) return false; // name of the class { - CBotTypResult ptrType(w, s); - pNew = CBotVar::Create(token, ptrType);// creates a variable // CBotVarClass* p = nullptr; long id; - ReadLong(pf, id); + if (!ReadLong(istr, id)) return false; // if ( id ) p = CBotVarClass::Find(id); // found the instance (made by RestoreInstance) + CBotTypResult ptrType(w, className); + pNew = CBotVar::Create(token, ptrType); // creates a variable // returns a copy of the original instance CBotVar* pInstance = nullptr; - if ( !CBotVar::RestoreState( pf, pInstance ) ) return false; + if (!CBotVar::RestoreState(istr, pInstance)) return false; (static_cast(pNew))->SetPointer( pInstance ); // and point over if (bConstructor) pNew->ConstructorSet(); // constructor was called @@ -916,22 +923,22 @@ bool CBotVar::RestoreState(FILE* pf, CBotVar* &pVar) } break; - + } case CBotTypArrayPointer: { CBotTypResult r; - if (!ReadType(pf, r)) return false; + if (!ReadType(istr, r)) return false; pNew = CBotVar::Create(token, r); // creates a variable // returns a copy of the original instance CBotVar* pInstance = nullptr; - if ( !CBotVar::RestoreState( pf, pInstance ) ) return false; + if (!CBotVar::RestoreState(istr, pInstance)) return false; (static_cast(pNew))->SetPointer( pInstance ); // and point over } break; default: - assert(0); + return false; // signal error } if ( pPrev != nullptr ) pPrev->m_next = pNew; diff --git a/src/CBot/CBotStack.h b/src/CBot/CBotStack.h index a72b3e4a..498ccd78 100644 --- a/src/CBot/CBotStack.h +++ b/src/CBot/CBotStack.h @@ -434,8 +434,8 @@ public: //! \name Write to file //@{ - bool SaveState(FILE* pf); - bool RestoreState(FILE* pf, CBotStack* &pStack); + bool SaveState(std::ostream &ostr); + bool RestoreState(std::istream &istr, CBotStack* &pStack); //@} diff --git a/src/CBot/CBotUtils.cpp b/src/CBot/CBotUtils.cpp index a6c6ef9c..a87e2943 100644 --- a/src/CBot/CBotUtils.cpp +++ b/src/CBot/CBotUtils.cpp @@ -108,38 +108,6 @@ CBotTypResult ArrayType(CBotToken* &p, CBotCStack* pile, CBotTypResult type) return type; } -//////////////////////////////////////////////////////////////////////////////// -bool WriteWord(FILE* pf, unsigned short w) -{ - size_t lg; - - lg = fwrite(&w, sizeof( unsigned short ), 1, pf ); - - return (lg == 1); -} - -//////////////////////////////////////////////////////////////////////////////// -bool WriteString(FILE* pf, std::string s) -{ - size_t lg1, lg2; - - lg1 = s.size(); - if (!WriteWord(pf, lg1)) return false; - - lg2 = fwrite(s.c_str(), 1, lg1, pf ); - return (lg1 == lg2); -} - -//////////////////////////////////////////////////////////////////////////////// -bool WriteFloat(FILE* pf, float w) -{ - size_t lg; - - lg = fwrite(&w, sizeof( float ), 1, pf ); - - return (lg == 1); -} - //////////////////////////////////////////////////////////////////////////////// long GetNumInt(const std::string& str) { diff --git a/src/CBot/CBotUtils.h b/src/CBot/CBotUtils.h index 9042b0f8..5b58535c 100644 --- a/src/CBot/CBotUtils.h +++ b/src/CBot/CBotUtils.h @@ -19,9 +19,8 @@ #pragma once -#include "CBot/CBotTypResult.h" +#include "CBot/CBotFileUtils.h" -#include #include #include @@ -31,6 +30,8 @@ namespace CBot class CBotVar; class CBotToken; class CBotCStack; +class CBotTypResult; + /*! * \brief MakeListVars Transforms the array of pointers to variables in a @@ -58,30 +59,6 @@ CBotTypResult TypeParam(CBotToken* &p, CBotCStack* pile); */ CBotTypResult ArrayType(CBotToken* &p, CBotCStack* pile, CBotTypResult type); -/*! - * \brief WriteWord - * \param pf - * \param w - * \return - */ -bool WriteWord(FILE* pf, unsigned short w); - -/*! - * \brief WriteString - * \param pf - * \param s - * \return - */ -bool WriteString(FILE* pf, std::string s); - -/*! - * \brief WriteFloat - * \param pf - * \param w - * \return - */ -bool WriteFloat(FILE* pf, float w); - /*! * \brief GetNumInt Converts a string into integer may be of the form 0xabc123. * \param str diff --git a/src/CBot/CBotVar/CBotVar.cpp b/src/CBot/CBotVar/CBotVar.cpp index 62ba41f4..4886c033 100644 --- a/src/CBot/CBotVar/CBotVar.cpp +++ b/src/CBot/CBotVar/CBotVar.cpp @@ -134,7 +134,7 @@ void* CBotVar::GetUserPtr() } //////////////////////////////////////////////////////////////////////////////// -bool CBotVar::Save1State(FILE* pf) +bool CBotVar::Save1State(std::ostream &ostr) { // this routine "virtual" must never be called, // there must be a routine for each of the subclasses (CBotVarInt, CBotVarFloat, etc) diff --git a/src/CBot/CBotVar/CBotVar.h b/src/CBot/CBotVar/CBotVar.h index d2805ddf..980b8a71 100644 --- a/src/CBot/CBotVar/CBotVar.h +++ b/src/CBot/CBotVar/CBotVar.h @@ -623,28 +623,28 @@ public: /** * \brief Save common variable header (name, type, etc.) - * \param pf file pointer + * \param ostr Output stream * \return false on write error */ - virtual bool Save0State(FILE* pf); + virtual bool Save0State(std::ostream &ostr); /** * \brief Save variable data * * Overriden in child classes * - * \param pf file pointer + * \param ostr Output stream * \return false on write error */ - virtual bool Save1State(FILE* pf); + virtual bool Save1State(std::ostream &ostr); /** * \brief Restore variable - * \param pf file pointer + * \param istr Input stream * \param[out] pVar Pointer to recieve the variable * \return false on read error */ - static bool RestoreState(FILE* pf, CBotVar* &pVar); + static bool RestoreState(std::istream &istr, CBotVar* &pVar); //@} diff --git a/src/CBot/CBotVar/CBotVarArray.cpp b/src/CBot/CBotVar/CBotVarArray.cpp index 6462d119..05575dc1 100644 --- a/src/CBot/CBotVar/CBotVarArray.cpp +++ b/src/CBot/CBotVar/CBotVarArray.cpp @@ -20,7 +20,6 @@ #include "CBot/CBotVar/CBotVarArray.h" #include "CBot/CBotVar/CBotVarClass.h" #include "CBot/CBotToken.h" -#include "CBot/CBotFileUtils.h" #include "CBot/CBotEnums.h" @@ -137,10 +136,10 @@ std::string CBotVarArray::GetValString() } //////////////////////////////////////////////////////////////////////////////// -bool CBotVarArray::Save1State(FILE* pf) +bool CBotVarArray::Save1State(std::ostream &ostr) { - if ( !WriteType(pf, m_type) ) return false; - return SaveVars(pf, m_pInstance); // saves the instance that manages the table + if (!WriteType(ostr, m_type)) return false; + return SaveVars(ostr, m_pInstance); // saves the instance that manages the table } } // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarArray.h b/src/CBot/CBotVar/CBotVarArray.h index 68b00b28..fb211055 100644 --- a/src/CBot/CBotVar/CBotVarArray.h +++ b/src/CBot/CBotVar/CBotVarArray.h @@ -51,7 +51,7 @@ public: std::string GetValString() override; - bool Save1State(FILE* pf) override; + bool Save1State(std::ostream &ostr) override; private: //! Array data diff --git a/src/CBot/CBotVar/CBotVarBoolean.cpp b/src/CBot/CBotVar/CBotVarBoolean.cpp index d36de078..b733e933 100644 --- a/src/CBot/CBotVar/CBotVarBoolean.cpp +++ b/src/CBot/CBotVar/CBotVarBoolean.cpp @@ -40,9 +40,9 @@ void CBotVarBoolean::Not() SetValInt(!GetValInt()); } -bool CBotVarBoolean::Save1State(FILE* pf) +bool CBotVarBoolean::Save1State(std::ostream &ostr) { - return WriteWord(pf, m_val); // the value of the variable + return WriteByte(ostr, m_val); // the value of the variable } } // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarBoolean.h b/src/CBot/CBotVar/CBotVarBoolean.h index 44774a9f..da810e98 100644 --- a/src/CBot/CBotVar/CBotVarBoolean.h +++ b/src/CBot/CBotVar/CBotVarBoolean.h @@ -37,7 +37,7 @@ public: void XOr(CBotVar* left, CBotVar* right) override; void Not() override; - bool Save1State(FILE* pf) override; + bool Save1State(std::ostream &ostr) override; }; } // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarClass.cpp b/src/CBot/CBotVar/CBotVarClass.cpp index 36952d18..9d587c1f 100644 --- a/src/CBot/CBotVar/CBotVarClass.cpp +++ b/src/CBot/CBotVar/CBotVarClass.cpp @@ -23,8 +23,6 @@ #include "CBot/CBotStack.h" #include "CBot/CBotDefines.h" -#include "CBot/CBotFileUtils.h" - #include "CBot/CBotInstr/CBotInstr.h" #include @@ -464,12 +462,12 @@ bool CBotVarClass::Ne(CBotVar* left, CBotVar* right) } //////////////////////////////////////////////////////////////////////////////// -bool CBotVarClass::Save1State(FILE* pf) +bool CBotVarClass::Save1State(std::ostream &ostr) { - if ( !WriteType(pf, m_type) ) return false; - if ( !WriteLong(pf, m_ItemIdent) ) return false; + if (!WriteType(ostr, m_type)) return false; + if (!WriteLong(ostr, m_ItemIdent)) return false; - return SaveVars(pf, m_pVar); // content of the object + return SaveVars(ostr, m_pVar); // content of the object } } // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarClass.h b/src/CBot/CBotVar/CBotVarClass.h index 55bdd891..34ec732e 100644 --- a/src/CBot/CBotVar/CBotVarClass.h +++ b/src/CBot/CBotVar/CBotVarClass.h @@ -54,7 +54,7 @@ public: CBotVar* GetItemList() override; std::string GetValString() override; - bool Save1State(FILE* pf) override; + bool Save1State(std::ostream &ostr) override; void Update(void* pUser) override; diff --git a/src/CBot/CBotVar/CBotVarFloat.cpp b/src/CBot/CBotVar/CBotVarFloat.cpp index a1c4217f..bfa1c1f9 100644 --- a/src/CBot/CBotVar/CBotVarFloat.cpp +++ b/src/CBot/CBotVar/CBotVarFloat.cpp @@ -22,9 +22,9 @@ namespace CBot { -bool CBotVarFloat::Save1State(FILE* pf) +bool CBotVarFloat::Save1State(std::ostream &ostr) { - return WriteFloat(pf, m_val); // the value of the variable + return WriteFloat(ostr, m_val); // the value of the variable } } // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarFloat.h b/src/CBot/CBotVar/CBotVarFloat.h index 81cbcde0..dfdecd9b 100644 --- a/src/CBot/CBotVar/CBotVarFloat.h +++ b/src/CBot/CBotVar/CBotVarFloat.h @@ -32,7 +32,7 @@ class CBotVarFloat : public CBotVarNumber public: CBotVarFloat(const CBotToken &name) : CBotVarNumber(name) {} - bool Save1State(FILE* pf) override; + bool Save1State(std::ostream &ostr) override; }; } // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarInt.cpp b/src/CBot/CBotVar/CBotVarInt.cpp index 477629ae..852566f9 100644 --- a/src/CBot/CBotVar/CBotVarInt.cpp +++ b/src/CBot/CBotVar/CBotVarInt.cpp @@ -45,17 +45,17 @@ std::string CBotVarInt::GetValString() void CBotVarInt::Neg() { CBotVarNumber::Neg(); - m_defnum.empty(); + m_defnum.clear(); } void CBotVarInt::Inc() { CBotVarNumber::Inc(); - m_defnum.empty(); + m_defnum.clear(); } void CBotVarInt::Dec() { CBotVarNumber::Dec(); - m_defnum.empty(); + m_defnum.clear(); } void CBotVarInt::XOr(CBotVar* left, CBotVar* right) @@ -90,22 +90,23 @@ void CBotVarInt::SR(CBotVar* left, CBotVar* right) void CBotVarInt::Not() { m_val = ~m_val; + m_defnum.clear(); } -bool CBotVarInt::Save0State(FILE* pf) +bool CBotVarInt::Save0State(std::ostream &ostr) { if (!m_defnum.empty()) { - if(!WriteWord(pf, 200)) return false; // special marker - if(!WriteString(pf, m_defnum)) return false; + if(!WriteWord(ostr, 200)) return false; // special marker + if(!WriteString(ostr, m_defnum)) return false; } - return CBotVar::Save0State(pf); + return CBotVar::Save0State(ostr); } -bool CBotVarInt::Save1State(FILE* pf) +bool CBotVarInt::Save1State(std::ostream &ostr) { - return WriteWord(pf, m_val); + return WriteInt(ostr, m_val); } } // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarInt.h b/src/CBot/CBotVar/CBotVarInt.h index 906a402d..5e04135c 100644 --- a/src/CBot/CBotVar/CBotVarInt.h +++ b/src/CBot/CBotVar/CBotVarInt.h @@ -50,8 +50,8 @@ public: void SR(CBotVar* left, CBotVar* right) override; void ASR(CBotVar* left, CBotVar* right) override; - bool Save0State(FILE* pf) override; - bool Save1State(FILE* pf) override; + bool Save0State(std::ostream &ostr) override; + bool Save1State(std::ostream &ostr) override; protected: //! The name if given by DefineNum. diff --git a/src/CBot/CBotVar/CBotVarPointer.cpp b/src/CBot/CBotVar/CBotVarPointer.cpp index 2f78c90a..24f9a5cb 100644 --- a/src/CBot/CBotVar/CBotVarPointer.cpp +++ b/src/CBot/CBotVar/CBotVarPointer.cpp @@ -24,7 +24,6 @@ #include "CBot/CBotEnums.h" #include "CBot/CBotUtils.h" -#include "CBot/CBotFileUtils.h" #include @@ -171,21 +170,21 @@ CBotClass* CBotVarPointer::GetClass() } //////////////////////////////////////////////////////////////////////////////// -bool CBotVarPointer::Save1State(FILE* pf) +bool CBotVarPointer::Save1State(std::ostream &ostr) { if ( m_type.GetClass() != nullptr ) { - if (!WriteString(pf, m_type.GetClass()->GetName())) return false; // name of the class + if (!WriteString(ostr, m_type.GetClass()->GetName())) return false; // name of the class } else { - if (!WriteString(pf, "")) return false; + if (!WriteString(ostr, "")) return false; } - if (!WriteLong(pf, GetIdent())) return false; // the unique reference + if (!WriteLong(ostr, GetIdent())) return false; // the unique reference // also saves the proceedings copies - return SaveVars(pf, GetPointer()); + return SaveVars(ostr, GetPointer()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/CBot/CBotVar/CBotVarPointer.h b/src/CBot/CBotVar/CBotVarPointer.h index 75c9bc98..6f9c0155 100644 --- a/src/CBot/CBotVar/CBotVarPointer.h +++ b/src/CBot/CBotVar/CBotVarPointer.h @@ -61,7 +61,7 @@ public: void ConstructorSet() override; - bool Save1State(FILE* pf) override; + bool Save1State(std::ostream &ostr) override; void Update(void* pUser) override; diff --git a/src/CBot/CBotVar/CBotVarString.cpp b/src/CBot/CBotVar/CBotVarString.cpp index 91a0e618..90856b82 100644 --- a/src/CBot/CBotVar/CBotVarString.cpp +++ b/src/CBot/CBotVar/CBotVarString.cpp @@ -37,9 +37,9 @@ bool CBotVarString::Ne(CBotVar* left, CBotVar* right) return left->GetValString() != right->GetValString(); } -bool CBotVarString::Save1State(FILE* pf) +bool CBotVarString::Save1State(std::ostream &ostr) { - return WriteString(pf, m_val); + return WriteString(ostr, m_val); } } // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarString.h b/src/CBot/CBotVar/CBotVarString.h index d01a80f6..ac04a310 100644 --- a/src/CBot/CBotVar/CBotVarString.h +++ b/src/CBot/CBotVar/CBotVarString.h @@ -63,7 +63,7 @@ public: bool Eq(CBotVar* left, CBotVar* right) override; bool Ne(CBotVar* left, CBotVar* right) override; - bool Save1State(FILE* pf) override; + bool Save1State(std::ostream &ostr) override; private: template diff --git a/src/CBot/CBotVar/CBotVarValue.h b/src/CBot/CBotVar/CBotVarValue.h index 76e820e8..5e58075d 100644 --- a/src/CBot/CBotVar/CBotVarValue.h +++ b/src/CBot/CBotVar/CBotVarValue.h @@ -86,7 +86,10 @@ template class CBotVarNumberBase : public CBotVarValue { public: - CBotVarNumberBase(const CBotToken &name) : CBotVarValue(name) {} + CBotVarNumberBase(const CBotToken &name) : CBotVarValue(name) + { + this->m_val = static_cast(0); + } void SetValInt(int val, const std::string &s = "") override { diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 58d90541..dea86bcb 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -4449,10 +4449,8 @@ void CRobotMain::SaveOneScript(CObject *obj) } //! Saves the stack of the program in execution of a robot -bool CRobotMain::SaveFileStack(CObject *obj, FILE *file, int objRank) +bool CRobotMain::SaveFileStack(CObject *obj, std::ostream &ostr) { - if (objRank == -1) return true; - if (! obj->Implements(ObjectInterfaceType::Programmable)) return true; CProgrammableObject* programmable = dynamic_cast(obj); @@ -4460,14 +4458,24 @@ bool CRobotMain::SaveFileStack(CObject *obj, FILE *file, int objRank) ObjectType type = obj->GetType(); if (type == OBJECT_HUMAN) return true; - return programmable->WriteStack(file); + long status = 1; + std::stringstream sstr(""); + + if (!programmable->WriteStack(sstr)) + { + GetLogger()->Error("WriteStack failed at object id = %i\n", obj->GetID()); + status = 100; // marked bad + } + + if (!CBot::WriteLong(ostr, status)) return false; + if (!CBot::WriteStream(ostr, sstr)) return false; + + return true; } //! Resumes the execution stack of the program in a robot -bool CRobotMain::ReadFileStack(CObject *obj, FILE *file, int objRank) +bool CRobotMain::ReadFileStack(CObject *obj, std::istream &istr) { - if (objRank == -1) return true; - if (! obj->Implements(ObjectInterfaceType::Programmable)) return true; CProgrammableObject* programmable = dynamic_cast(obj); @@ -4475,7 +4483,29 @@ bool CRobotMain::ReadFileStack(CObject *obj, FILE *file, int objRank) ObjectType type = obj->GetType(); if (type == OBJECT_HUMAN) return true; - return programmable->ReadStack(file); + long status; + if (!CBot::ReadLong(istr, status)) return false; + + if (status == 100) // was marked bad ? + { + if (!CBot::ReadLong(istr, status)) return false; + if (!istr.seekg(status, istr.cur)) return false; + return true; // next program + } + + if (status == 1) + { + std::stringstream sstr(""); + if (!CBot::ReadStream(istr, sstr)) return false; + + if (!programmable->ReadStack(sstr)) + { + GetLogger()->Error("ReadStack failed at object id = %i\n", obj->GetID()); + } + return true; // next program + } + + return false; // error: status == ?? } std::vector CRobotMain::GetNewScriptNames(ObjectType type) @@ -4670,25 +4700,36 @@ bool CRobotMain::IOWriteScene(std::string filename, std::string filecbot, std::s } // Writes the file of stacks of execution. - FILE* file = CBot::fOpen((CResourceManager::GetSaveLocation() + "/" + filecbot).c_str(), "wb"); - if (file == nullptr) return false; + COutputStream ostr(filecbot); + if (!ostr.is_open()) return false; + bool bError = false; long version = 1; - CBot::fWrite(&version, sizeof(long), 1, file); // version of COLOBOT + CBot::WriteLong(ostr, version); // version of COLOBOT version = CBot::CBotProgram::GetVersion(); - CBot::fWrite(&version, sizeof(long), 1, file); // version of CBOT + CBot::WriteLong(ostr, version); // version of CBOT + CBot::WriteWord(ostr, 0); // TODO - objRank = 0; for (CObject* obj : m_objMan->GetAllObjects()) { if (obj->GetType() == OBJECT_TOTO) continue; if (IsObjectBeingTransported(obj)) continue; if (obj->Implements(ObjectInterfaceType::Destroyable) && dynamic_cast(obj)->IsDying()) continue; - if (!SaveFileStack(obj, file, objRank++)) break; + if (!SaveFileStack(obj, ostr)) + { + GetLogger()->Error("SaveFileStack failed at object id = %i\n", obj->GetID()); + bError = true; + break; + } } - CBot::CBotClass::SaveStaticState(file); - CBot::fClose(file); + + if (!bError && !CBot::CBotClass::SaveStaticState(ostr)) + { + GetLogger()->Error("CBotClass save static state failed\n"); + } + + ostr.close(); if (!emergencySave) { @@ -4846,29 +4887,48 @@ CObject* CRobotMain::IOReadScene(std::string filename, std::string filecbot) m_ui->GetLoadingScreen()->SetProgress(0.95f, RT_LOADING_CBOT_SAVE); // Reads the file of stacks of execution. - FILE* file = CBot::fOpen((CResourceManager::GetSaveLocation() + "/" + filecbot).c_str(), "rb"); - if (file != nullptr) + CInputStream istr(filecbot); + + if (istr.is_open()) { - long version; - CBot::fRead(&version, sizeof(long), 1, file); // version of COLOBOT + bool bError = false; + long version = 0; + CBot::ReadLong(istr, version); // version of COLOBOT if (version == 1) { - CBot::fRead(&version, sizeof(long), 1, file); // version of CBOT + CBot::ReadLong(istr, version); // version of CBOT if (version == CBot::CBotProgram::GetVersion()) { - objRank = 0; - for (CObject* obj : m_objMan->GetAllObjects()) + unsigned short flag; + CBot::ReadWord(istr, flag); // TODO + bError = (flag != 0); + + if (!bError) for (CObject* obj : m_objMan->GetAllObjects()) { if (obj->GetType() == OBJECT_TOTO) continue; if (IsObjectBeingTransported(obj)) continue; if (obj->Implements(ObjectInterfaceType::Destroyable) && dynamic_cast(obj)->IsDying()) continue; - if (!ReadFileStack(obj, file, objRank++)) break; + if (!ReadFileStack(obj, istr)) + { + GetLogger()->Error("ReadFileStack failed at object id = %i\n", obj->GetID()); + bError = true; + break; + } + } + + if (!bError && !CBot::CBotClass::RestoreStaticState(istr)) + { + GetLogger()->Error("CBotClass restore static state failed\n"); + bError = true; } } + else + GetLogger()->Error("cbot.run file is wrong version: %i\n", version); } - CBot::CBotClass::RestoreStaticState(file); - CBot::fClose(file); + + if (bError) GetLogger()->Error("Restoring CBOT state failed at stream position: %li\n", istr.tellg()); + istr.close(); } m_ui->GetLoadingScreen()->SetProgress(1.0f, RT_LOADING_FINISHED); diff --git a/src/level/robotmain.h b/src/level/robotmain.h index 2614f2cc..2b4c7b03 100644 --- a/src/level/robotmain.h +++ b/src/level/robotmain.h @@ -308,8 +308,8 @@ public: void SaveAllScript(); void SaveOneScript(CObject *obj); - bool SaveFileStack(CObject *obj, FILE *file, int objRank); - bool ReadFileStack(CObject *obj, FILE *file, int objRank); + bool SaveFileStack(CObject *obj, std::ostream &ostr); + bool ReadFileStack(CObject *obj, std::istream &istr); //! Return list of scripts to load to robot created in BotFactory std::vector GetNewScriptNames(ObjectType type); diff --git a/src/object/implementation/programmable_impl.cpp b/src/object/implementation/programmable_impl.cpp index 5e370bdb..34be6c59 100644 --- a/src/object/implementation/programmable_impl.cpp +++ b/src/object/implementation/programmable_impl.cpp @@ -143,24 +143,43 @@ bool CProgrammableObjectImpl::IsProgram() // Load a stack of script implementation from a file. -bool CProgrammableObjectImpl::ReadStack(FILE *file) +bool CProgrammableObjectImpl::ReadStack(std::istream &istr) { short op; - CBot::fRead(&op, sizeof(short), 1, file); + if (!CBot::ReadShort(istr, op)) return false; if ( op == 1 ) // run ? { - CBot::fRead(&op, sizeof(short), 1, file); // program rank + if (!CBot::ReadShort(istr, op)) return false; // program rank if ( op >= 0 ) { if (m_object->Implements(ObjectInterfaceType::ProgramStorage)) { - assert(op < static_cast(dynamic_cast(m_object)->GetProgramCount())); + int count = static_cast(dynamic_cast(m_object)->GetProgramCount()); + if (!(op < count)) + { + GetLogger()->Info("Object program count: %i\n", count); + GetLogger()->Error("Error in file: program index out of range: %i\n", op); + return false; + } + m_currentProgram = dynamic_cast(m_object)->GetProgram(op); - if ( !m_currentProgram->script->ReadStack(file) ) return false; + if (!m_currentProgram->script->ReadStack(istr)) + { + GetLogger()->Error("Restore state failed at program index: %i\n", op); + int errNum = m_currentProgram->script->GetError(); + if (errNum != 0) + { + std::string errStr; + m_currentProgram->script->GetError(errStr); + GetLogger()->Error("Program reports error: %i:(%s)\n", errNum, errStr.c_str()); + } + return false; + } } else { + GetLogger()->Error("Object is not a program storage object\n"); return false; } } @@ -171,7 +190,7 @@ bool CProgrammableObjectImpl::ReadStack(FILE *file) // Save the script implementation stack of a file. -bool CProgrammableObjectImpl::WriteStack(FILE *file) +bool CProgrammableObjectImpl::WriteStack(std::ostream &ostr) { short op; @@ -179,21 +198,25 @@ bool CProgrammableObjectImpl::WriteStack(FILE *file) m_currentProgram->script->IsRunning() ) { op = 1; // run - CBot::fWrite(&op, sizeof(short), 1, file); + if (!CBot::WriteShort(ostr, op)) return false; op = -1; if (m_object->Implements(ObjectInterfaceType::ProgramStorage)) { op = dynamic_cast(m_object)->GetProgramIndex(m_currentProgram); } - CBot::fWrite(&op, sizeof(short), 1, file); + if (!CBot::WriteShort(ostr, op)) return false; - return m_currentProgram->script->WriteStack(file); + if (!m_currentProgram->script->WriteStack(ostr)) + { + GetLogger()->Error("Save state failed at program index: %i\n", op); + return false; + } + return true; } op = 0; // stop - CBot::fWrite(&op, sizeof(short), 1, file); - return true; + return CBot::WriteShort(ostr, op); } diff --git a/src/object/implementation/programmable_impl.h b/src/object/implementation/programmable_impl.h index a0b78096..38b8be7c 100644 --- a/src/object/implementation/programmable_impl.h +++ b/src/object/implementation/programmable_impl.h @@ -58,8 +58,8 @@ public: Program* GetCurrentProgram() override; void StopProgram() override; - bool ReadStack(FILE *file) override; - bool WriteStack(FILE *file) override; + bool ReadStack(std::istream &istr) override; + bool WriteStack(std::ostream &ostr) override; void TraceRecordStart() override; void TraceRecordStop() override; diff --git a/src/object/interface/programmable_object.h b/src/object/interface/programmable_object.h index 05f1a92c..1ce0d5d4 100644 --- a/src/object/interface/programmable_object.h +++ b/src/object/interface/programmable_object.h @@ -53,9 +53,9 @@ public: virtual bool IsProgram() = 0; //! Save current execution status to file - virtual bool WriteStack(FILE *file) = 0; + virtual bool WriteStack(std::ostream &ostr) = 0; //! Read current execution status from file - virtual bool ReadStack(FILE *file) = 0; + virtual bool ReadStack(std::istream &istr) = 0; //! Start recording trace virtual void TraceRecordStart() = 0; diff --git a/src/script/script.cpp b/src/script/script.cpp index a94e850f..22ae1024 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -1032,16 +1032,16 @@ bool CScript::WriteScript(const char* filename) // Reads a stack of script by execution as a file. -bool CScript::ReadStack(FILE *file) +bool CScript::ReadStack(std::istream &istr) { int nb; - CBot::fRead(&nb, sizeof(int), 1, file); - CBot::fRead(&m_ipf, sizeof(int), 1, file); - CBot::fRead(&m_errMode, sizeof(int), 1, file); + if (!CBot::ReadInt(istr, nb)) return false; + if (!CBot::ReadInt(istr, m_ipf)) return false; + if (!CBot::ReadInt(istr, m_errMode)) return false; if (m_botProg == nullptr) return false; - if ( !m_botProg->RestoreState(file) ) return false; + if (!m_botProg->RestoreState(istr)) return false; m_bRun = true; m_bContinue = false; @@ -1050,16 +1050,16 @@ bool CScript::ReadStack(FILE *file) // Writes a stack of script by execution as a file. -bool CScript::WriteStack(FILE *file) +bool CScript::WriteStack(std::ostream &ostr) { int nb; nb = 2; - CBot::fWrite(&nb, sizeof(int), 1, file); - CBot::fWrite(&m_ipf, sizeof(int), 1, file); - CBot::fWrite(&m_errMode, sizeof(int), 1, file); + if (!CBot::WriteInt(ostr, nb)) return false; + if (!CBot::WriteInt(ostr, m_ipf)) return false; + if (!CBot::WriteInt(ostr, m_errMode)) return false; - return m_botProg->SaveState(file); + return m_botProg->SaveState(ostr); } diff --git a/src/script/script.h b/src/script/script.h index f0f473fb..bc64dc23 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -88,8 +88,8 @@ public: bool SendScript(const char* text); bool ReadScript(const char* filename); bool WriteScript(const char* filename); - bool ReadStack(FILE *file); - bool WriteStack(FILE *file); + bool ReadStack(std::istream &istr); + bool WriteStack(std::ostream &ostr); bool Compare(CScript* other); void SetFilename(const std::string &filename); diff --git a/test/unit/CBot/CBot_test.cpp b/test/unit/CBot/CBot_test.cpp index cc3261b8..f16637bd 100644 --- a/test/unit/CBot/CBot_test.cpp +++ b/test/unit/CBot/CBot_test.cpp @@ -22,6 +22,9 @@ #include #include +extern bool g_cbotTestSaveState; +bool g_cbotTestSaveState = false; + using namespace CBot; class CBotUT : public testing::Test @@ -197,6 +200,23 @@ private: return ss.str(); } + static void TestSaveAndRestore(CBotProgram* program) + { + std::stringstream sstr(""); + // save + if (!program->SaveState(sstr)) + throw CBotTestFail("CBotProgram::SaveState Failed"); + + if (!CBotClass::SaveStaticState(sstr)) + throw CBotTestFail("CBotClass::SaveStaticState Failed"); + // restore + if (!program->RestoreState(sstr)) + throw CBotTestFail("CBotProgram::RestoreState Failed"); + + if (!CBotClass::RestoreStaticState(sstr)) + throw CBotTestFail("CBotClass::RestoreStaticState Failed"); + } + protected: std::unique_ptr ExecuteTest(const std::string& code, CBotError expectedError = CBotNoErr) { @@ -231,7 +251,17 @@ protected: try { program->Start(test); - while (!program->Run()); + if (g_cbotTestSaveState) + { + while (!program->Run(nullptr, 0)) // save/restore at each step + { + TestSaveAndRestore(program.get()); + } + } + else + { + while (!program->Run(nullptr, 0)); // execute in step mode + } program->GetError(error, cursor1, cursor2); if (error != expectedRuntimeError) { diff --git a/test/unit/main.cpp b/test/unit/main.cpp index 91d640de..8bed282c 100644 --- a/test/unit/main.cpp +++ b/test/unit/main.cpp @@ -21,11 +21,21 @@ #include +extern bool g_cbotTestSaveState; + int main(int argc, char* argv[]) { CLogger logger; ::testing::InitGoogleTest(&argc, argv); + // parse arguments not removed by InitGoogleTest + for (int i = 1; i < argc; ++i) + { + std::string arg(argv[i]); + if (arg == "--CBotUT_TestSaveState") + g_cbotTestSaveState = true; + } + return RUN_ALL_TESTS(); } From 250ea57e8b2dfd081116ae93b07122e582c87363 Mon Sep 17 00:00:00 2001 From: melex750 Date: Thu, 11 Apr 2019 04:15:27 -0400 Subject: [PATCH 095/109] Fix arithmetic operations with integers (#993) Also fixed unsigned right shift operator ">>>" --- src/CBot/CBotInstr/CBotInstrUtils.cpp | 7 +++ src/CBot/CBotToken.cpp | 2 +- src/CBot/CBotVar/CBotVar.cpp | 5 ++ src/CBot/CBotVar/CBotVar.h | 1 + src/CBot/CBotVar/CBotVarInt.cpp | 26 +------- src/CBot/CBotVar/CBotVarInt.h | 18 +++--- src/CBot/CBotVar/CBotVarValue.h | 91 ++++++++++++++++++++------- test/unit/CBot/CBot_test.cpp | 14 +++++ 8 files changed, 109 insertions(+), 55 deletions(-) diff --git a/src/CBot/CBotInstr/CBotInstrUtils.cpp b/src/CBot/CBotInstr/CBotInstrUtils.cpp index 04c42211..774a4e37 100644 --- a/src/CBot/CBotInstr/CBotInstrUtils.cpp +++ b/src/CBot/CBotInstr/CBotInstrUtils.cpp @@ -129,6 +129,13 @@ bool TypeCompatible(CBotTypResult& type1, CBotTypResult& type2, int op) return true; } + if (op == ID_ASR || op == ID_SR || op == ID_SL || + op == ID_ASSOR || op == ID_ASSSL || op == ID_ASSSR || + op == ID_ASSAND || op == ID_ASSXOR || op == ID_ASSASR) + { + if (max > CBotTypLong) return false; + } + type1.SetType(max); type2.SetType(max); return true; diff --git a/src/CBot/CBotToken.cpp b/src/CBot/CBotToken.cpp index ea31fad9..b3a5a461 100644 --- a/src/CBot/CBotToken.cpp +++ b/src/CBot/CBotToken.cpp @@ -103,7 +103,7 @@ static const boost::bimap KEYWORDS = makeBimap>>="}, {ID_ASSASR, ">>="}, {ID_SL, "<<"}, - {ID_SR, ">>"}, + {ID_SR, ">>>"}, {ID_ASR, ">>"}, {ID_INC, "++"}, {ID_DEC, "--"}, diff --git a/src/CBot/CBotVar/CBotVar.cpp b/src/CBot/CBotVar/CBotVar.cpp index 4886c033..d9947e5b 100644 --- a/src/CBot/CBotVar/CBotVar.cpp +++ b/src/CBot/CBotVar/CBotVar.cpp @@ -752,6 +752,11 @@ CBotClass* CBotVar::GetClass() return nullptr; } +CBotVar::operator bool() +{ + return static_cast(GetValInt()); +} + CBotVar::operator int() { return GetValInt(); diff --git a/src/CBot/CBotVar/CBotVar.h b/src/CBot/CBotVar/CBotVar.h index 980b8a71..1a9c1498 100644 --- a/src/CBot/CBotVar/CBotVar.h +++ b/src/CBot/CBotVar/CBotVar.h @@ -444,6 +444,7 @@ public: */ //@{ + operator bool(); operator int(); operator float(); operator std::string(); diff --git a/src/CBot/CBotVar/CBotVarInt.cpp b/src/CBot/CBotVar/CBotVarInt.cpp index 852566f9..cd602614 100644 --- a/src/CBot/CBotVar/CBotVarInt.cpp +++ b/src/CBot/CBotVar/CBotVarInt.cpp @@ -58,33 +58,9 @@ void CBotVarInt::Dec() m_defnum.clear(); } -void CBotVarInt::XOr(CBotVar* left, CBotVar* right) -{ - SetValInt(left->GetValInt() ^ right->GetValInt()); -} -void CBotVarInt::And(CBotVar* left, CBotVar* right) -{ - SetValInt(left->GetValInt() & right->GetValInt()); -} -void CBotVarInt::Or(CBotVar* left, CBotVar* right) -{ - SetValInt(left->GetValInt() | right->GetValInt()); -} - -void CBotVarInt::SL(CBotVar* left, CBotVar* right) -{ - SetValInt(left->GetValInt() << right->GetValInt()); -} -void CBotVarInt::ASR(CBotVar* left, CBotVar* right) -{ - SetValInt(left->GetValInt() >> right->GetValInt()); -} void CBotVarInt::SR(CBotVar* left, CBotVar* right) { - int source = left->GetValInt(); - int shift = right->GetValInt(); - if (shift >= 1) source &= 0x7fffffff; - SetValInt(source >> shift); + SetValInt(static_cast(left->GetValInt()) >> right->GetValInt()); } void CBotVarInt::Not() diff --git a/src/CBot/CBotVar/CBotVarInt.h b/src/CBot/CBotVar/CBotVarInt.h index 5e04135c..6fb51208 100644 --- a/src/CBot/CBotVar/CBotVarInt.h +++ b/src/CBot/CBotVar/CBotVarInt.h @@ -27,10 +27,10 @@ namespace CBot /** * \brief CBotVar subclass for managing integer values (::CBotTypInt) */ -class CBotVarInt : public CBotVarNumber +class CBotVarInt : public CBotVarInteger { public: - CBotVarInt(const CBotToken &name) : CBotVarNumber(name) {} + CBotVarInt(const CBotToken &name) : CBotVarInteger(name) {} void SetValInt(int val, const std::string& s = "") override; std::string GetValString() override; @@ -40,19 +40,21 @@ public: void Neg() override; void Inc() override; void Dec() override; - - void XOr(CBotVar* left, CBotVar* right) override; - void Or(CBotVar* left, CBotVar* right) override; - void And(CBotVar* left, CBotVar* right) override; void Not() override; - void SL(CBotVar* left, CBotVar* right) override; void SR(CBotVar* left, CBotVar* right) override; - void ASR(CBotVar* left, CBotVar* right) override; bool Save0State(std::ostream &ostr) override; bool Save1State(std::ostream &ostr) override; +protected: + + void SetValue(int val) override + { + CBotVarNumberBase::SetValue(val); + m_defnum.clear(); + } + protected: //! The name if given by DefineNum. std::string m_defnum; diff --git a/src/CBot/CBotVar/CBotVarValue.h b/src/CBot/CBotVar/CBotVarValue.h index 5e58075d..9c0b0361 100644 --- a/src/CBot/CBotVar/CBotVarValue.h +++ b/src/CBot/CBotVar/CBotVarValue.h @@ -74,6 +74,13 @@ public: return s.str(); } +protected: + virtual void SetValue(T val) + { + this->m_val = val; + this->m_binit = CBotVar::InitType::DEF; + } + protected: //! The value T m_val; @@ -93,14 +100,12 @@ public: void SetValInt(int val, const std::string &s = "") override { - this->m_val = static_cast(val); - this->m_binit = CBotVar::InitType::DEF; + this->SetValue(static_cast(val)); } void SetValFloat(float val) override { - this->m_val = static_cast(val); - this->m_binit = CBotVar::InitType::DEF; + this->SetValue(static_cast(val)); } int GetValInt() override @@ -116,11 +121,11 @@ public: bool Eq(CBotVar* left, CBotVar* right) override { - return left->GetValFloat() == right->GetValFloat(); + return static_cast(*left) == static_cast(*right); } bool Ne(CBotVar* left, CBotVar* right) override { - return left->GetValFloat() != right->GetValFloat(); + return static_cast(*left) != static_cast(*right); } }; @@ -135,33 +140,33 @@ public: void Mul(CBotVar* left, CBotVar* right) override { - this->SetValFloat(left->GetValFloat() * right->GetValFloat()); + this->SetValue(static_cast(*left) * static_cast(*right)); } void Power(CBotVar* left, CBotVar* right) override { - this->SetValFloat(pow(left->GetValFloat(), right->GetValFloat())); + this->SetValue(pow(static_cast(*left), static_cast(*right))); } CBotError Div(CBotVar* left, CBotVar* right) override { - float r = right->GetValFloat(); - if (r == 0) return CBotErrZeroDiv; - this->SetValFloat(left->GetValFloat() / r); + T r = static_cast(*right); + if ( r == static_cast(0) ) return CBotErrZeroDiv; + this->SetValue(static_cast(*left) / r); return CBotNoErr; } CBotError Modulo(CBotVar* left, CBotVar* right) override { - float r = right->GetValFloat(); - if (r == 0) return CBotErrZeroDiv; - this->SetValFloat(fmod(left->GetValFloat(), r)); + T r = static_cast(*right); + if ( r == static_cast(0) ) return CBotErrZeroDiv; + this->SetValue(fmod(static_cast(*left), r)); return CBotNoErr; } void Add(CBotVar* left, CBotVar* right) override { - this->SetValFloat(left->GetValFloat() + right->GetValFloat()); + this->SetValue(static_cast(*left) + static_cast(*right)); } void Sub(CBotVar* left, CBotVar* right) override { - this->SetValFloat(left->GetValFloat() - right->GetValFloat()); + this->SetValue(static_cast(*left) - static_cast(*right)); } void Neg() override @@ -179,21 +184,65 @@ public: bool Lo(CBotVar* left, CBotVar* right) override { - return left->GetValFloat() < right->GetValFloat(); + return static_cast(*left) < static_cast(*right); } bool Hi(CBotVar* left, CBotVar* right) override { - return left->GetValFloat() > right->GetValFloat(); + return static_cast(*left) > static_cast(*right); } bool Ls(CBotVar* left, CBotVar* right) override { - return left->GetValFloat() <= right->GetValFloat(); + return static_cast(*left) <= static_cast(*right); } bool Hs(CBotVar* left, CBotVar* right) override { - return left->GetValFloat() >= right->GetValFloat(); + return static_cast(*left) >= static_cast(*right); } }; -} +/** + * \brief An integer variable (byte, short, char, int, long) + */ +template +class CBotVarInteger : public CBotVarNumber +{ +public: + CBotVarInteger(const CBotToken &name) : CBotVarNumber(name) {} + CBotError Modulo(CBotVar* left, CBotVar* right) override + { + T r = static_cast(*right); + if ( r == static_cast(0) ) return CBotErrZeroDiv; + this->SetValue(static_cast(*left) % r); + return CBotNoErr; + } + + void XOr(CBotVar* left, CBotVar* right) override + { + this->SetValue(static_cast(*left) ^ static_cast(*right)); + } + void And(CBotVar* left, CBotVar* right) override + { + this->SetValue(static_cast(*left) & static_cast(*right)); + } + void Or(CBotVar* left, CBotVar* right) override + { + this->SetValue(static_cast(*left) | static_cast(*right)); + } + + void SL(CBotVar* left, CBotVar* right) override + { + this->SetValue(static_cast(*left) << right->GetValInt()); + } + void ASR(CBotVar* left, CBotVar* right) override + { + this->SetValue(static_cast(*left) >> right->GetValInt()); + } + + void Not() override + { + this->m_val = ~(this->m_val); + } +}; + +} // namespace CBot diff --git a/test/unit/CBot/CBot_test.cpp b/test/unit/CBot/CBot_test.cpp index f16637bd..6f2201b9 100644 --- a/test/unit/CBot/CBot_test.cpp +++ b/test/unit/CBot/CBot_test.cpp @@ -605,6 +605,20 @@ TEST_F(CBotUT, VarImplicitCast) ); } +TEST_F(CBotUT, IntegerMathNearLimits_Issue993) +{ + ExecuteTest( + "extern void Test_Issue993() {\n" + " ASSERT(-2147483600 * 1 == -2147483600);\n" + " ASSERT( 2147483600 * 1 == 2147483600);\n" + " ASSERT( 2147483646 * 1 == 2147483646);\n" + " ASSERT( 2147483646 * -1 == -2147483646);\n" + " ASSERT( 2147483000 * -1 == -2147483000);\n" + " ASSERT( 2147483000 * 1 == 2147483000);\n" + "}\n" + ); +} + TEST_F(CBotUT, ToString) { ExecuteTest( From c0cdd84e856e1a69a3eaddcd3f790f4e03115775 Mon Sep 17 00:00:00 2001 From: melex750 Date: Thu, 11 Apr 2019 04:19:29 -0400 Subject: [PATCH 096/109] Add missing primitive data types in CBOT --- src/CBot/CBotDefParam.cpp | 20 ++++ src/CBot/CBotEnums.h | 15 ++- src/CBot/CBotFileUtils.cpp | 10 ++ src/CBot/CBotFileUtils.h | 16 +++ src/CBot/CBotInstr/CBotCase.cpp | 2 +- src/CBot/CBotInstr/CBotDefFloat.cpp | 23 ++-- src/CBot/CBotInstr/CBotDefFloat.h | 2 +- src/CBot/CBotInstr/CBotDefInt.cpp | 26 +++-- src/CBot/CBotInstr/CBotDefInt.h | 2 +- src/CBot/CBotInstr/CBotExprLitNum.cpp | 102 +++++++++++------ src/CBot/CBotInstr/CBotExprLitNum.h | 21 ++-- src/CBot/CBotInstr/CBotInstr.cpp | 5 + src/CBot/CBotInstr/CBotParExpr.cpp | 2 +- src/CBot/CBotInstr/CBotTwoOpExpr.cpp | 5 +- src/CBot/CBotStack.cpp | 32 +++++- src/CBot/CBotToken.cpp | 5 + src/CBot/CBotTypResult.cpp | 5 + src/CBot/CBotUtils.cpp | 19 +++- src/CBot/CBotUtils.h | 2 +- src/CBot/CBotVar/CBotVar.cpp | 155 ++++++++++++++++++++++++-- src/CBot/CBotVar/CBotVar.h | 30 +++++ src/CBot/CBotVar/CBotVarByte.h | 46 ++++++++ src/CBot/CBotVar/CBotVarChar.h | 59 ++++++++++ src/CBot/CBotVar/CBotVarDouble.h | 41 +++++++ src/CBot/CBotVar/CBotVarLong.h | 46 ++++++++ src/CBot/CBotVar/CBotVarShort.h | 46 ++++++++ src/CBot/CBotVar/CBotVarValue.h | 49 ++++++++ src/CBot/CMakeLists.txt | 5 + src/script/cbottoken.cpp | 10 ++ 29 files changed, 717 insertions(+), 84 deletions(-) create mode 100644 src/CBot/CBotVar/CBotVarByte.h create mode 100644 src/CBot/CBotVar/CBotVarChar.h create mode 100644 src/CBot/CBotVar/CBotVarDouble.h create mode 100644 src/CBot/CBotVar/CBotVarLong.h create mode 100644 src/CBot/CBotVar/CBotVarShort.h diff --git a/src/CBot/CBotDefParam.cpp b/src/CBot/CBotDefParam.cpp index af4fb6ec..fe4a37b6 100644 --- a/src/CBot/CBotDefParam.cpp +++ b/src/CBot/CBotDefParam.cpp @@ -173,14 +173,34 @@ bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj) { switch (p->m_type.GetType()) { + case CBotTypByte: + newvar->SetValByte(pVar->GetValByte()); + newvar->SetInit(pVar->GetInit()); // copy nan + break; + case CBotTypShort: + newvar->SetValShort(pVar->GetValShort()); + newvar->SetInit(pVar->GetInit()); // copy nan + break; + case CBotTypChar: + newvar->SetValChar(pVar->GetValChar()); + newvar->SetInit(pVar->GetInit()); // copy nan + break; case CBotTypInt: newvar->SetValInt(pVar->GetValInt()); newvar->SetInit(pVar->GetInit()); // copy nan break; + case CBotTypLong: + newvar->SetValLong(pVar->GetValLong()); + newvar->SetInit(pVar->GetInit()); // copy nan + break; case CBotTypFloat: newvar->SetValFloat(pVar->GetValFloat()); newvar->SetInit(pVar->GetInit()); // copy nan break; + case CBotTypDouble: + newvar->SetValDouble(pVar->GetValDouble()); + newvar->SetInit(pVar->GetInit()); // copy nan + break; case CBotTypString: newvar->SetValString(pVar->GetValString()); break; diff --git a/src/CBot/CBotEnums.h b/src/CBot/CBotEnums.h index 0b33bfdc..3dff66eb 100644 --- a/src/CBot/CBotEnums.h +++ b/src/CBot/CBotEnums.h @@ -35,13 +35,13 @@ namespace CBot enum CBotType { CBotTypVoid = 0, //!< void - CBotTypByte = 1, //!< byte (NOT IMPLEMENTED) - CBotTypShort = 2, //!< short (NOT IMPLEMENTED) - CBotTypChar = 3, //!< char (NOT IMPLEMENTED) + CBotTypByte = 1, //!< byte + CBotTypShort = 2, //!< short + CBotTypChar = 3, //!< char CBotTypInt = 4, //!< int - CBotTypLong = 5, //!< long (NOT IMPLEMENTED) + CBotTypLong = 5, //!< long CBotTypFloat = 6, //!< float - CBotTypDouble = 7, //!< double (NOT IMPLEMENTED) + CBotTypDouble = 7, //!< double CBotTypBoolean = 8, //!< bool CBotTypString = 9, //!< string @@ -106,6 +106,11 @@ enum TokenId ID_STRING, ID_VOID, ID_BOOL, + ID_BYTE, + ID_SHORT, + ID_CHAR, + ID_LONG, + ID_DOUBLE, TokenKeyVal = 2200, //!< keywords that represent values (true, false, null, nan) ID_TRUE = 2200, diff --git a/src/CBot/CBotFileUtils.cpp b/src/CBot/CBotFileUtils.cpp index ccde313c..b2a19cb1 100644 --- a/src/CBot/CBotFileUtils.cpp +++ b/src/CBot/CBotFileUtils.cpp @@ -151,6 +151,16 @@ bool ReadShort(std::istream &istr, short &s) return ReadSignedBinary(istr, s); } +bool WriteUInt32(std::ostream &ostr, uint32_t i) +{ + return WriteBinary(ostr, i); +} + +bool ReadUInt32(std::istream &istr, uint32_t &i) +{ + return ReadBinary(istr, i); +} + bool WriteInt(std::ostream &ostr, int i) { return WriteSignedBinary(ostr, i); diff --git a/src/CBot/CBotFileUtils.h b/src/CBot/CBotFileUtils.h index 8f739cb4..900dd81d 100644 --- a/src/CBot/CBotFileUtils.h +++ b/src/CBot/CBotFileUtils.h @@ -84,6 +84,22 @@ bool WriteShort(std::ostream &ostr, short s); */ bool ReadShort(std::istream &istr, short &s); +/*! + * \brief WriteUInt32 + * \param ostr Output stream + * \param i + * \return true on success + */ +bool WriteUInt32(std::ostream &ostr, uint32_t i); + +/*! + * \brief ReadUInt32 + * \param istr Input stream + * \param[out] i + * \return true on success + */ +bool ReadUInt32(std::istream &istr, uint32_t &i); + /*! * \brief WriteInt * \param ostr Output stream diff --git a/src/CBot/CBotInstr/CBotCase.cpp b/src/CBot/CBotInstr/CBotCase.cpp index 35e17d3d..15c8d4f7 100644 --- a/src/CBot/CBotInstr/CBotCase.cpp +++ b/src/CBot/CBotInstr/CBotCase.cpp @@ -51,7 +51,7 @@ CBotInstr* CBotCase::Compile(CBotToken* &p, CBotCStack* pStack) if ( pp->GetType() == ID_CASE ) { pp = p; - inst->m_value = CBotExprLitNum::Compile(p, pStack); + inst->m_value = CBot::CompileExprLitNum(p, pStack); if (inst->m_value == nullptr ) { pStack->SetError( CBotErrBadNum, pp ); diff --git a/src/CBot/CBotInstr/CBotDefFloat.cpp b/src/CBot/CBotInstr/CBotDefFloat.cpp index 65449b02..0bb6f5f8 100644 --- a/src/CBot/CBotInstr/CBotDefFloat.cpp +++ b/src/CBot/CBotInstr/CBotDefFloat.cpp @@ -46,13 +46,22 @@ CBotDefFloat::~CBotDefFloat() } //////////////////////////////////////////////////////////////////////////////// -CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip) +CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip, CBotTypResult vartype) { CBotToken* pp = cont ? nullptr : p; - if (!cont && !IsOfType(p, ID_FLOAT)) return nullptr; + if (!cont) + { + switch (p->GetType()) + { + case ID_FLOAT: vartype.SetType(CBotTypFloat ); break; + case ID_DOUBLE: vartype.SetType(CBotTypDouble); break; + default: return nullptr; + } + p = p->GetNext(); + } - CBotDefFloat* inst = static_cast(CompileArray(p, pStack, CBotTypFloat)); + CBotDefFloat* inst = static_cast(CompileArray(p, pStack, vartype)); if (inst != nullptr || !pStack->IsOk()) return inst; CBotCStack* pStk = pStack->TokenStack(pp); @@ -67,7 +76,7 @@ CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, b if (nullptr != (inst->m_var = CBotLeftExprVar::Compile( p, pStk ))) { - (static_cast(inst->m_var))->m_typevar = CBotTypFloat; + (static_cast(inst->m_var))->m_typevar = vartype; if (pStk->CheckVarLocal(vartoken)) // redefinition of a variable { pStk->SetStartError(vartoken->GetStart()); @@ -79,7 +88,7 @@ CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, b { delete inst; p = vartoken; - inst = static_cast(CBotDefArray::Compile(p, pStk, CBotTypFloat)); + inst = static_cast(CBotDefArray::Compile(p, pStk, vartype)); goto suite; // no assignment, variable already created } @@ -103,7 +112,7 @@ CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, b } } - var = CBotVar::Create(*vartoken, CBotTypFloat); + var = CBotVar::Create(*vartoken, vartype); var->SetInit(inst->m_expr != nullptr ? CBotVar::InitType::DEF : CBotVar::InitType::UNDEF); var->SetUniqNum( (static_cast(inst->m_var))->m_nIdent = CBotVar::NextUniqNum()); @@ -111,7 +120,7 @@ CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, b suite: if (pStk->IsOk() && IsOfType(p, ID_COMMA)) { - if (nullptr != ( inst->m_next2b = CBotDefFloat::Compile(p, pStk, true, noskip))) + if (nullptr != ( inst->m_next2b = CBotDefFloat::Compile(p, pStk, true, noskip, vartype))) { return pStack->Return(inst, pStk); } diff --git a/src/CBot/CBotInstr/CBotDefFloat.h b/src/CBot/CBotInstr/CBotDefFloat.h index a8060b41..8c3fa44d 100644 --- a/src/CBot/CBotInstr/CBotDefFloat.h +++ b/src/CBot/CBotInstr/CBotDefFloat.h @@ -41,7 +41,7 @@ public: * \param noskip * \return */ - static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip=false); + static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip=false, CBotTypResult vartype = CBotTypFloat); /*! * \brief Execute Executes the definition of a real variable. diff --git a/src/CBot/CBotInstr/CBotDefInt.cpp b/src/CBot/CBotInstr/CBotDefInt.cpp index 6cfb30e6..6835f901 100644 --- a/src/CBot/CBotInstr/CBotDefInt.cpp +++ b/src/CBot/CBotInstr/CBotDefInt.cpp @@ -47,13 +47,25 @@ CBotDefInt::~CBotDefInt() } //////////////////////////////////////////////////////////////////////////////// -CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip) +CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, bool noskip, CBotTypResult vartype) { CBotToken* pp = cont ? nullptr : p; // no repetition of the token "int" - if (!cont && !IsOfType(p, ID_INT)) return nullptr; + if (!cont) + { + switch (p->GetType()) + { + case ID_BYTE: vartype.SetType(CBotTypByte ); break; + case ID_SHORT: vartype.SetType(CBotTypShort); break; + case ID_CHAR: vartype.SetType(CBotTypChar ); break; + case ID_INT: vartype.SetType(CBotTypInt ); break; + case ID_LONG: vartype.SetType(CBotTypLong ); break; + default: return nullptr; + } + p = p->GetNext(); + } - CBotDefInt* inst = static_cast(CompileArray(p, pStack, CBotTypInt)); + CBotDefInt* inst = static_cast(CompileArray(p, pStack, vartype)); if (inst != nullptr || !pStack->IsOk()) return inst; CBotCStack* pStk = pStack->TokenStack(pp); @@ -68,7 +80,7 @@ CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, boo // determines the expression is valid for the item on the left side if (nullptr != (inst->m_var = CBotLeftExprVar::Compile( p, pStk ))) { - (static_cast(inst->m_var))->m_typevar = CBotTypInt; + (static_cast(inst->m_var))->m_typevar = vartype; if (pStk->CheckVarLocal(vartoken)) // redefinition of the variable { pStk->SetError(CBotErrRedefVar, vartoken); @@ -82,7 +94,7 @@ CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, boo // compiles an array declaration - CBotInstr* inst2 = CBotDefArray::Compile(p, pStk, CBotTypInt); + CBotInstr* inst2 = CBotDefArray::Compile(p, pStk, vartype); inst = static_cast(inst2); goto suite; // no assignment, variable already created @@ -108,7 +120,7 @@ CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, boo } { - CBotVar* var = CBotVar::Create(*vartoken, CBotTypInt);// create the variable (evaluated after the assignment) + CBotVar* var = CBotVar::Create(*vartoken, vartype); // create the variable (evaluated after the assignment) var->SetInit(inst->m_expr != nullptr ? CBotVar::InitType::DEF : CBotVar::InitType::UNDEF); // if initialized with assignment var->SetUniqNum( //set it with a unique number (static_cast(inst->m_var))->m_nIdent = CBotVar::NextUniqNum()); @@ -117,7 +129,7 @@ CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, boo suite: if (pStk->IsOk() && IsOfType(p, ID_COMMA)) // chained several definitions { - if (nullptr != ( inst->m_next2b = CBotDefInt::Compile(p, pStk, true, noskip))) // compile next one + if (nullptr != ( inst->m_next2b = CBotDefInt::Compile(p, pStk, true, noskip, vartype))) // compile next one { return pStack->Return(inst, pStk); } diff --git a/src/CBot/CBotInstr/CBotDefInt.h b/src/CBot/CBotInstr/CBotDefInt.h index 2962eab3..867ab4dd 100644 --- a/src/CBot/CBotInstr/CBotDefInt.h +++ b/src/CBot/CBotInstr/CBotDefInt.h @@ -41,7 +41,7 @@ public: * \param noskip * \return */ - static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip = false); + static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool cont = false, bool noskip = false, CBotTypResult vartype = CBotTypInt); /*! * \brief Execute Execute the definition of the integer variable. diff --git a/src/CBot/CBotInstr/CBotExprLitNum.cpp b/src/CBot/CBotInstr/CBotExprLitNum.cpp index 9273e8ee..9842cf57 100644 --- a/src/CBot/CBotInstr/CBotExprLitNum.cpp +++ b/src/CBot/CBotInstr/CBotExprLitNum.cpp @@ -25,52 +25,87 @@ #include "CBot/CBotUtils.h" +#include #include namespace CBot { -//////////////////////////////////////////////////////////////////////////////// -CBotExprLitNum::CBotExprLitNum() +template <> +CBotExprLitNum::CBotExprLitNum(int val) : m_numtype(CBotTypInt), m_value(val) { } -//////////////////////////////////////////////////////////////////////////////// -CBotExprLitNum::~CBotExprLitNum() +template <> +CBotExprLitNum::CBotExprLitNum(long val) : m_numtype(CBotTypLong), m_value(val) { } -//////////////////////////////////////////////////////////////////////////////// -CBotInstr* CBotExprLitNum::Compile(CBotToken* &p, CBotCStack* pStack) +template <> +CBotExprLitNum::CBotExprLitNum(float val) : m_numtype(CBotTypFloat), m_value(val) +{ +} + +template <> +CBotExprLitNum::CBotExprLitNum(double val) : m_numtype(CBotTypDouble), m_value(val) +{ +} + +template +CBotExprLitNum::~CBotExprLitNum() +{ +} + +CBotInstr* CompileExprLitNum(CBotToken* &p, CBotCStack* pStack) { CBotCStack* pStk = pStack->TokenStack(); - CBotExprLitNum* inst = new CBotExprLitNum(); + const auto& s = p->GetString(); - inst->SetToken(p); - std::string s = p->GetString(); + CBotInstr* inst = nullptr; + CBotType numtype = CBotTypInt; - inst->m_numtype = CBotTypInt; if (p->GetType() == TokenTypDef) { - inst->m_valint = p->GetKeywordId(); + inst = new CBotExprLitNum(static_cast(p->GetKeywordId())); } else { if (s.find('.') != std::string::npos || ( s.find('x') == std::string::npos && ( s.find_first_of("eE") != std::string::npos ) )) { - inst->m_numtype = CBotTypFloat; - inst->m_valfloat = GetNumFloat(s); + double val = GetNumFloat(s); + if (val < static_cast(std::numeric_limits::min()) && + val > static_cast(std::numeric_limits::max()) ) + { + numtype = CBotTypDouble; + inst = new CBotExprLitNum(val); + } + else + { + numtype = CBotTypFloat; + inst = new CBotExprLitNum(static_cast(val)); + } } else { - inst->m_valint = GetNumInt(s); + long val = GetNumInt(s); + if (val < std::numeric_limits::min() && + val > std::numeric_limits::max() ) + { + numtype = CBotTypLong; + inst = new CBotExprLitNum(val); + } + else + { + inst = new CBotExprLitNum(static_cast(val)); + } } } + inst->SetToken(p); if (pStk->NextToken(p)) { - CBotVar* var = CBotVar::Create("", inst->m_numtype); + CBotVar* var = CBotVar::Create("", numtype); pStk->SetVar(var); return pStack->Return(inst, pStk); @@ -79,8 +114,8 @@ CBotInstr* CBotExprLitNum::Compile(CBotToken* &p, CBotCStack* pStack) return pStack->Return(nullptr, pStk); } -//////////////////////////////////////////////////////////////////////////////// -bool CBotExprLitNum::Execute(CBotStack* &pj) +template +bool CBotExprLitNum::Execute(CBotStack* &pj) { CBotStack* pile = pj->AddStack(this); @@ -88,39 +123,38 @@ bool CBotExprLitNum::Execute(CBotStack* &pj) CBotVar* var = CBotVar::Create("", m_numtype); - std::string nombre ; if (m_token.GetType() == TokenTypDef) { - nombre = m_token.GetString(); + var->SetValInt(m_value, m_token.GetString()); } - - switch (m_numtype) + else { - case CBotTypShort: - case CBotTypInt: - var->SetValInt(m_valint, nombre); - break; - case CBotTypFloat: - var->SetValFloat(m_valfloat); - break; - default: - assert(false); + *var = m_value; } pile->SetVar(var); // place on the stack return pj->Return(pile); // it's ok } -//////////////////////////////////////////////////////////////////////////////// -void CBotExprLitNum::RestoreState(CBotStack* &pj, bool bMain) +template +void CBotExprLitNum::RestoreState(CBotStack* &pj, bool bMain) { if (bMain) pj->RestoreStack(this); } -std::string CBotExprLitNum::GetDebugData() +template +std::string CBotExprLitNum::GetDebugData() { std::stringstream ss; - ss << "(" << (m_numtype == CBotTypFloat ? "float" : "int") << ") " << (m_numtype == CBotTypFloat ? m_valfloat : m_valint); + switch (m_numtype) + { + case CBotTypInt : ss << "(int) "; break; + case CBotTypLong : ss << "(long) "; break; + case CBotTypFloat : ss << "(float) "; break; + case CBotTypDouble: ss << "(double) "; break; + default: assert(false); + } + ss << m_value; return ss.str(); } diff --git a/src/CBot/CBotInstr/CBotExprLitNum.h b/src/CBot/CBotInstr/CBotExprLitNum.h index 414f2d8e..92cd302d 100644 --- a/src/CBot/CBotInstr/CBotExprLitNum.h +++ b/src/CBot/CBotInstr/CBotExprLitNum.h @@ -24,26 +24,21 @@ namespace CBot { +CBotInstr* CompileExprLitNum(CBotToken* &p, CBotCStack* pStack); + /** * \brief A number literal - 5, 1, 2.5, 3.75, etc. or a predefined numerical constant (see CBotToken::DefineNum()) * - * Can be of type ::CBotTypInt or ::CBotTypFloat + * Can be of type ::CBotTypInt, ::CBotTypLong, ::CBotTypFloat, or ::CBotTypDouble */ +template class CBotExprLitNum : public CBotInstr { public: - CBotExprLitNum(); + CBotExprLitNum(T val); ~CBotExprLitNum(); - /*! - * \brief Compile - * \param p - * \param pStack - * \return - */ - static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack); - /*! * \brief Execute Execute, returns the corresponding number. * \param pj @@ -65,10 +60,8 @@ protected: private: //! The type of number. CBotType m_numtype; - //! Value for an int. - long m_valint; - //! Value for a float. - float m_valfloat; + //! Value + T m_value; }; diff --git a/src/CBot/CBotInstr/CBotInstr.cpp b/src/CBot/CBotInstr/CBotInstr.cpp index f69785f6..04b13204 100644 --- a/src/CBot/CBotInstr/CBotInstr.cpp +++ b/src/CBot/CBotInstr/CBotInstr.cpp @@ -208,10 +208,15 @@ CBotInstr* CBotInstr::Compile(CBotToken* &p, CBotCStack* pStack) case ID_THROW: return CBotThrow::Compile(p, pStack); + case ID_BYTE: + case ID_SHORT: + case ID_CHAR: case ID_INT: + case ID_LONG: return CBotDefInt::Compile(p, pStack); case ID_FLOAT: + case ID_DOUBLE: return CBotDefFloat::Compile(p, pStack); case ID_STRING: diff --git a/src/CBot/CBotInstr/CBotParExpr.cpp b/src/CBot/CBotInstr/CBotParExpr.cpp index b879ebec..24bdaafe 100644 --- a/src/CBot/CBotInstr/CBotParExpr.cpp +++ b/src/CBot/CBotInstr/CBotParExpr.cpp @@ -151,7 +151,7 @@ CBotInstr* CBotParExpr::CompileLitExpr(CBotToken* &p, CBotCStack* pStack) if (p->GetType() == TokenTypNum || p->GetType() == TokenTypDef ) { - CBotInstr* inst = CBotExprLitNum::Compile(p, pStk); + CBotInstr* inst = CBot::CompileExprLitNum(p, pStk); return pStack->Return(inst, pStk); } diff --git a/src/CBot/CBotInstr/CBotTwoOpExpr.cpp b/src/CBot/CBotInstr/CBotTwoOpExpr.cpp index 3d5fc6a4..ab8b0da9 100644 --- a/src/CBot/CBotInstr/CBotTwoOpExpr.cpp +++ b/src/CBot/CBotInstr/CBotTwoOpExpr.cpp @@ -399,7 +399,10 @@ bool CBotTwoOpExpr::Execute(CBotStack* &pStack) TypeRes = CBotTypBoolean; break; case ID_DIV: - TypeRes = std::max(TypeRes, static_cast(CBotTypFloat)); + if (TypeRes == CBotTypFloat) + { + if (type1.Eq(CBotTypLong) || type2.Eq(CBotTypLong)) TypeRes = CBotTypDouble; + } } // creates a variable for the result diff --git a/src/CBot/CBotStack.cpp b/src/CBot/CBotStack.cpp index 7f3c0b9a..5101bbf2 100644 --- a/src/CBot/CBotStack.cpp +++ b/src/CBot/CBotStack.cpp @@ -833,10 +833,28 @@ bool CBotVar::RestoreState(std::istream &istr, CBotVar* &pVar) switch (w) { case CBotTypBoolean: + char valBool; + if (!ReadByte(istr, valBool)) return false; + pNew = CBotVar::Create(token, w); // creates a variable + pNew->SetValInt(valBool); + break; + case CBotTypByte: char valByte; if (!ReadByte(istr, valByte)) return false; pNew = CBotVar::Create(token, w); // creates a variable - pNew->SetValInt(valByte); + pNew->SetValByte(valByte); + break; + case CBotTypShort: + short valShort; + if (!ReadShort(istr, valShort)) return false; + pNew = CBotVar::Create(token, w); // creates a variable + pNew->SetValShort(valShort); + break; + case CBotTypChar: + uint32_t valChar; + if (!ReadUInt32(istr, valChar)) return false; + pNew = CBotVar::Create(token, w); // creates a variable + pNew->SetValChar(valChar); break; case CBotTypInt: int valInt; @@ -844,12 +862,24 @@ bool CBotVar::RestoreState(std::istream &istr, CBotVar* &pVar) pNew = CBotVar::Create(token, w); // creates a variable pNew->SetValInt(valInt, defnum); break; + case CBotTypLong: + long valLong; + if (!ReadLong(istr, valLong)) return false; + pNew = CBotVar::Create(token, w); // creates a variable + pNew->SetValInt(valLong); + break; case CBotTypFloat: float valFloat; if (!ReadFloat(istr, valFloat)) return false; pNew = CBotVar::Create(token, w); // creates a variable pNew->SetValFloat(valFloat); break; + case CBotTypDouble: + double valDouble; + if (!ReadDouble(istr, valDouble)) return false; + pNew = CBotVar::Create(token, w); // creates a variable + pNew->SetValDouble(valDouble); + break; case CBotTypString: { std::string valString; diff --git a/src/CBot/CBotToken.cpp b/src/CBot/CBotToken.cpp index b3a5a461..d5afe1fe 100644 --- a/src/CBot/CBotToken.cpp +++ b/src/CBot/CBotToken.cpp @@ -71,6 +71,11 @@ static const boost::bimap KEYWORDS = makeBimapToString() + "[]"; diff --git a/src/CBot/CBotUtils.cpp b/src/CBot/CBotUtils.cpp index a87e2943..4d663bea 100644 --- a/src/CBot/CBotUtils.cpp +++ b/src/CBot/CBotUtils.cpp @@ -62,12 +62,27 @@ CBotTypResult TypeParam(CBotToken* &p, CBotCStack* pile) switch (p->GetType()) { + case ID_BYTE: + p = p->GetNext(); + return ArrayType(p, pile, CBotTypResult( CBotTypByte )); + case ID_SHORT: + p = p->GetNext(); + return ArrayType(p, pile, CBotTypResult( CBotTypShort )); + case ID_CHAR: + p = p->GetNext(); + return ArrayType(p, pile, CBotTypResult( CBotTypChar )); case ID_INT: p = p->GetNext(); return ArrayType(p, pile, CBotTypResult( CBotTypInt )); + case ID_LONG: + p = p->GetNext(); + return ArrayType(p, pile, CBotTypResult( CBotTypLong )); case ID_FLOAT: p = p->GetNext(); return ArrayType(p, pile, CBotTypResult( CBotTypFloat )); + case ID_DOUBLE: + p = p->GetNext(); + return ArrayType(p, pile, CBotTypResult( CBotTypDouble )); case ID_BOOLEAN: case ID_BOOL: p = p->GetNext(); @@ -144,7 +159,7 @@ long GetNumInt(const std::string& str) } //////////////////////////////////////////////////////////////////////////////// -float GetNumFloat(const std::string& str) +double GetNumFloat(const std::string& str) { const char* p = str.c_str(); double num = 0; @@ -201,7 +216,7 @@ float GetNumFloat(const std::string& str) } if (bNeg) num = -num; - return static_cast(num); + return num; } bool CharInList(const char c, const char* list) diff --git a/src/CBot/CBotUtils.h b/src/CBot/CBotUtils.h index 5b58535c..5bc4fe33 100644 --- a/src/CBot/CBotUtils.h +++ b/src/CBot/CBotUtils.h @@ -71,7 +71,7 @@ long GetNumInt(const std::string& str); * \param str * \return */ -float GetNumFloat(const std::string& str); +double GetNumFloat(const std::string& str); /*! * \brief Search a null-terminated string for a char value. diff --git a/src/CBot/CBotVar/CBotVar.cpp b/src/CBot/CBotVar/CBotVar.cpp index d9947e5b..83438745 100644 --- a/src/CBot/CBotVar/CBotVar.cpp +++ b/src/CBot/CBotVar/CBotVar.cpp @@ -24,12 +24,17 @@ #include "CBot/CBotInstr/CBotInstr.h" #include "CBot/CBotVar/CBotVarArray.h" -#include "CBot/CBotVar/CBotVarPointer.h" -#include "CBot/CBotVar/CBotVarClass.h" #include "CBot/CBotVar/CBotVarBoolean.h" -#include "CBot/CBotVar/CBotVarString.h" +#include "CBot/CBotVar/CBotVarByte.h" +#include "CBot/CBotVar/CBotVarChar.h" +#include "CBot/CBotVar/CBotVarClass.h" +#include "CBot/CBotVar/CBotVarDouble.h" #include "CBot/CBotVar/CBotVarFloat.h" #include "CBot/CBotVar/CBotVarInt.h" +#include "CBot/CBotVar/CBotVarLong.h" +#include "CBot/CBotVar/CBotVarPointer.h" +#include "CBot/CBotVar/CBotVarShort.h" +#include "CBot/CBotVar/CBotVarString.h" #include "CBot/CBotClass.h" #include "CBot/CBotToken.h" @@ -160,11 +165,20 @@ CBotVar* CBotVar::Create(const CBotToken& name, CBotTypResult type) { switch (type.GetType()) { + case CBotTypByte: + return new CBotVarByte(name); case CBotTypShort: + return new CBotVarShort(name); + case CBotTypChar: + return new CBotVarChar(name); case CBotTypInt: return new CBotVarInt(name); + case CBotTypLong: + return new CBotVarLong(name); case CBotTypFloat: return new CBotVarFloat(name); + case CBotTypDouble: + return new CBotVarDouble(name); case CBotTypBoolean: return new CBotVarBoolean(name); case CBotTypString: @@ -223,11 +237,20 @@ CBotVar* CBotVar::Create(const std::string& n, CBotTypResult type) switch (type.GetType()) { + case CBotTypByte: + return new CBotVarByte(name); case CBotTypShort: + return new CBotVarShort(name); + case CBotTypChar: + return new CBotVarChar(name); case CBotTypInt: return new CBotVarInt(name); + case CBotTypLong: + return new CBotVarLong(name); case CBotTypFloat: return new CBotVarFloat(name); + case CBotTypDouble: + return new CBotVarDouble(name); case CBotTypBoolean: return new CBotVarBoolean(name); case CBotTypString: @@ -472,12 +495,27 @@ void CBotVar::SetVal(CBotVar* var) case CBotTypBoolean: SetValInt(var->GetValInt()); break; + case CBotTypByte: + SetValByte(var->GetValByte()); + break; + case CBotTypShort: + SetValShort(var->GetValShort()); + break; + case CBotTypChar: + SetValChar(var->GetValChar()); + break; case CBotTypInt: SetValInt(var->GetValInt(), (static_cast(var))->m_defnum); break; + case CBotTypLong: + SetValLong(var->GetValLong()); + break; case CBotTypFloat: SetValFloat(var->GetValFloat()); break; + case CBotTypDouble: + SetValDouble(var->GetValDouble()); + break; case CBotTypString: SetValString(var->GetValString()); break; @@ -545,33 +583,84 @@ CBotVarClass* CBotVar::GetPointer() // All these functions must be defined in the subclasses // derived from class CBotVar -//////////////////////////////////////////////////////////////////////////////// + +signed char CBotVar::GetValByte() +{ + assert(0); + return 0; +} + +short CBotVar::GetValShort() +{ + assert(0); + return 0; +} + +uint32_t CBotVar::GetValChar() +{ + assert(0); + return 0; +} + int CBotVar::GetValInt() { assert(0); return 0; } -//////////////////////////////////////////////////////////////////////////////// +long CBotVar::GetValLong() +{ + assert(0); + return 0; +} + float CBotVar::GetValFloat() { assert(0); return 0; } -//////////////////////////////////////////////////////////////////////////////// +double CBotVar::GetValDouble() +{ + assert(0); + return 0; +} + +void CBotVar::SetValByte(signed char val) +{ + assert(false); +} + +void CBotVar::SetValShort(short val) +{ + assert(false); +} + +void CBotVar::SetValChar(uint32_t val) +{ + assert(false); +} + void CBotVar::SetValInt(int c, const std::string& s) { assert(0); } -//////////////////////////////////////////////////////////////////////////////// +void CBotVar::SetValLong(long val) +{ + assert(false); +} + void CBotVar::SetValFloat(float c) { assert(0); } -//////////////////////////////////////////////////////////////////////////////// +void CBotVar::SetValDouble(double val) +{ + assert(false); +} + void CBotVar::Mul(CBotVar* left, CBotVar* right) { assert(0); @@ -757,16 +846,41 @@ CBotVar::operator bool() return static_cast(GetValInt()); } +CBotVar::operator signed char() +{ + return GetValByte(); +} + +CBotVar::operator short() +{ + return GetValShort(); +} + +CBotVar::operator uint32_t() +{ + return GetValChar(); +} + CBotVar::operator int() { return GetValInt(); } +CBotVar::operator long() +{ + return GetValLong(); +} + CBotVar::operator float() { return GetValFloat(); } +CBotVar::operator double() +{ + return GetValDouble(); +} + CBotVar::operator std::string() { return GetValString(); @@ -777,16 +891,41 @@ void CBotVar::operator=(const CBotVar &var) SetVal(const_cast(&var)); } +void CBotVar::operator=(signed char x) +{ + SetValByte(x); +} + +void CBotVar::operator=(short x) +{ + SetValShort(x); +} + +void CBotVar::operator=(uint32_t x) +{ + SetValChar(x); +} + void CBotVar::operator=(int x) { SetValInt(x); } +void CBotVar::operator=(long x) +{ + SetValLong(x); +} + void CBotVar::operator=(float x) { SetValFloat(x); } +void CBotVar::operator=(double x) +{ + SetValDouble(x); +} + void CBotVar::operator=(const std::string &x) { SetValString(x); diff --git a/src/CBot/CBotVar/CBotVar.h b/src/CBot/CBotVar/CBotVar.h index 1a9c1498..ef86f40f 100644 --- a/src/CBot/CBotVar/CBotVar.h +++ b/src/CBot/CBotVar/CBotVar.h @@ -445,12 +445,22 @@ public: //@{ operator bool(); + operator signed char(); + operator short(); + operator uint32_t(); operator int(); + operator long(); operator float(); + operator double(); operator std::string(); void operator=(const CBotVar& var); + void operator=(signed char x); + void operator=(short x); + void operator=(uint32_t x); void operator=(int x); + void operator=(long x); void operator=(float x); + void operator=(double x); void operator=(const std::string &x); /** @@ -466,6 +476,12 @@ public: */ virtual void Copy(CBotVar* pSrc, bool bName = true); + virtual void SetValByte(signed char val); + + virtual void SetValShort(short val); + + virtual void SetValChar(uint32_t val); + /** * \brief Set value as an integer * @@ -476,30 +492,44 @@ public: */ virtual void SetValInt(int val, const std::string& name = ""); + virtual void SetValLong(long val); + /** * \brief Set value as float * \param val New value */ virtual void SetValFloat(float val); + virtual void SetValDouble(double val); + /** * \brief Set value as string * \param val New value */ virtual void SetValString(const std::string& val); + virtual signed char GetValByte(); + + virtual short GetValShort(); + + virtual uint32_t GetValChar(); + /** * \brief Get value as integer * \return Current value */ virtual int GetValInt(); + virtual long GetValLong(); + /** * \brief Get value as float * \return Current value */ virtual float GetValFloat(); + virtual double GetValDouble(); + /** * \brief Get value as string * diff --git a/src/CBot/CBotVar/CBotVarByte.h b/src/CBot/CBotVar/CBotVarByte.h new file mode 100644 index 00000000..68c9088e --- /dev/null +++ b/src/CBot/CBotVar/CBotVarByte.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * 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 http://gnu.org/licenses + */ + +#pragma once + +#include "CBot/CBotVar/CBotVarValue.h" + +namespace CBot +{ + +/** + * \brief CBotVar subclass for managing 1-byte integer values (::CBotTypByte) + */ +class CBotVarByte : public CBotVarInteger +{ +public: + CBotVarByte(const CBotToken &name) : CBotVarInteger(name) {} + + void SR(CBotVar* left, CBotVar* right) override + { + SetValByte(static_cast(left->GetValByte()) >> right->GetValInt()); + } + + bool Save1State(std::ostream &ostr) override + { + return WriteByte(ostr, m_val); + } +}; + +} // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarChar.h b/src/CBot/CBotVar/CBotVarChar.h new file mode 100644 index 00000000..07f51358 --- /dev/null +++ b/src/CBot/CBotVar/CBotVarChar.h @@ -0,0 +1,59 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * 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 http://gnu.org/licenses + */ + +#pragma once + +#include "CBot/CBotVar/CBotVarValue.h" + +namespace CBot +{ + +/** + * \brief CBotVar subclass for managing 32-bit Unicode values (::CBotTypChar) + */ +class CBotVarChar : public CBotVarInteger +{ +public: + CBotVarChar(const CBotToken &name) : CBotVarInteger(name) {} + + std::string GetValString() override + { + if (m_binit == CBotVar::InitType::UNDEF) + return LoadString(TX_UNDEF); + if (m_binit == CBotVar::InitType::IS_NAN) + return LoadString(TX_NAN); + + if (0x10FFFF < m_val || (0xD7FF < m_val && m_val < 0xE000)) + return "\xEF\xBF\xBD"; // replacement character U+FFFD + + return CodePointToUTF8(m_val); + } + + void SR(CBotVar* left, CBotVar* right) override + { + SetValChar(left->GetValChar() >> right->GetValInt()); + } + + bool Save1State(std::ostream &ostr) override + { + return WriteUInt32(ostr, m_val); + } +}; + +} // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarDouble.h b/src/CBot/CBotVar/CBotVarDouble.h new file mode 100644 index 00000000..1df79cfb --- /dev/null +++ b/src/CBot/CBotVar/CBotVarDouble.h @@ -0,0 +1,41 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * 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 http://gnu.org/licenses + */ + +#pragma once + +#include "CBot/CBotVar/CBotVarValue.h" + +namespace CBot +{ + +/** + * \brief CBotVar subclass for managing double values (::CBotTypDouble) + */ +class CBotVarDouble : public CBotVarNumber +{ +public: + CBotVarDouble(const CBotToken &name) : CBotVarNumber(name) {} + + bool Save1State(std::ostream &ostr) override + { + return WriteDouble(ostr, m_val); + } +}; + +} // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarLong.h b/src/CBot/CBotVar/CBotVarLong.h new file mode 100644 index 00000000..84164c41 --- /dev/null +++ b/src/CBot/CBotVar/CBotVarLong.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * 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 http://gnu.org/licenses + */ + +#pragma once + +#include "CBot/CBotVar/CBotVarValue.h" + +namespace CBot +{ + +/** + * \brief CBotVar subclass for managing long integer values (::CBotTypLong) + */ +class CBotVarLong : public CBotVarInteger +{ +public: + CBotVarLong(const CBotToken &name) : CBotVarInteger(name) {} + + void SR(CBotVar* left, CBotVar* right) override + { + SetValLong(static_cast(left->GetValLong()) >> right->GetValInt()); + } + + bool Save1State(std::ostream &ostr) override + { + return WriteLong(ostr, m_val); + } +}; + +} // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarShort.h b/src/CBot/CBotVar/CBotVarShort.h new file mode 100644 index 00000000..3f0723e3 --- /dev/null +++ b/src/CBot/CBotVar/CBotVarShort.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * 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 http://gnu.org/licenses + */ + +#pragma once + +#include "CBot/CBotVar/CBotVarValue.h" + +namespace CBot +{ + +/** + * \brief CBotVar subclass for managing short integer values (::CBotTypShort) + */ +class CBotVarShort : public CBotVarInteger +{ +public: + CBotVarShort(const CBotToken &name) : CBotVarInteger(name) {} + + void SR(CBotVar* left, CBotVar* right) override + { + SetValShort(static_cast(left->GetValShort()) >> right->GetValInt()); + } + + bool Save1State(std::ostream &ostr) override + { + return WriteShort(ostr, m_val); + } +}; + +} // namespace CBot diff --git a/src/CBot/CBotVar/CBotVarValue.h b/src/CBot/CBotVar/CBotVarValue.h index 9c0b0361..035d7930 100644 --- a/src/CBot/CBotVar/CBotVarValue.h +++ b/src/CBot/CBotVar/CBotVarValue.h @@ -98,26 +98,75 @@ public: this->m_val = static_cast(0); } + void SetValByte(signed char val) override + { + this->SetValue(static_cast(val)); + } + + void SetValShort(short val) override + { + this->SetValue(static_cast(val)); + } + + void SetValChar(uint32_t val) override + { + this->SetValue(static_cast(val)); + } + void SetValInt(int val, const std::string &s = "") override { this->SetValue(static_cast(val)); } + void SetValLong(long val) override + { + this->SetValue(static_cast(val)); + } + void SetValFloat(float val) override { this->SetValue(static_cast(val)); } + void SetValDouble(double val) override + { + this->SetValue(static_cast(val)); + } + + signed char GetValByte() override + { + return static_cast(this->m_val); + } + + short GetValShort() override + { + return static_cast(this->m_val); + } + + uint32_t GetValChar() override + { + return static_cast(this->m_val); + } + int GetValInt() override { return static_cast(this->m_val); } + long GetValLong() override + { + return static_cast(this->m_val); + } + float GetValFloat() override { return static_cast(this->m_val); } + double GetValDouble() override + { + return static_cast(this->m_val); + } bool Eq(CBotVar* left, CBotVar* right) override { diff --git a/src/CBot/CMakeLists.txt b/src/CBot/CMakeLists.txt index a9a83e2e..4be97841 100644 --- a/src/CBot/CMakeLists.txt +++ b/src/CBot/CMakeLists.txt @@ -127,14 +127,19 @@ set(SOURCES CBotVar/CBotVarArray.h CBotVar/CBotVarBoolean.cpp CBotVar/CBotVarBoolean.h + CBotVar/CBotVarByte.h + CBotVar/CBotVarChar.h CBotVar/CBotVarClass.cpp CBotVar/CBotVarClass.h + CBotVar/CBotVarDouble.h CBotVar/CBotVarFloat.cpp CBotVar/CBotVarFloat.h CBotVar/CBotVarInt.cpp CBotVar/CBotVarInt.h + CBotVar/CBotVarLong.h CBotVar/CBotVarPointer.cpp CBotVar/CBotVarPointer.h + CBotVar/CBotVarShort.h CBotVar/CBotVarString.cpp CBotVar/CBotVarString.h stdlib/Compilation.cpp diff --git a/src/script/cbottoken.cpp b/src/script/cbottoken.cpp index 24b60a09..02bc4525 100644 --- a/src/script/cbottoken.cpp +++ b/src/script/cbottoken.cpp @@ -236,8 +236,13 @@ std::string GetHelpFilename(const char *token) if ( strcmp(token, "continue" ) == 0 ) helpfile = "cbot/continue"; if ( strcmp(token, "return" ) == 0 ) helpfile = "cbot/return"; if ( strcmp(token, "sizeof" ) == 0 ) helpfile = "cbot/sizeof"; + if ( strcmp(token, "byte" ) == 0 ) helpfile = "cbot/byte"; + if ( strcmp(token, "short" ) == 0 ) helpfile = "cbot/short"; + if ( strcmp(token, "char" ) == 0 ) helpfile = "cbot/char"; if ( strcmp(token, "int" ) == 0 ) helpfile = "cbot/int"; + if ( strcmp(token, "long" ) == 0 ) helpfile = "cbot/long"; if ( strcmp(token, "float" ) == 0 ) helpfile = "cbot/float"; + if ( strcmp(token, "double" ) == 0 ) helpfile = "cbot/double"; if ( strcmp(token, "bool" ) == 0 ) helpfile = "cbot/bool"; if ( strcmp(token, "string" ) == 0 ) helpfile = "cbot/string"; if ( strcmp(token, "point" ) == 0 ) helpfile = "cbot/point"; @@ -388,8 +393,13 @@ std::string GetHelpFilename(const char *token) bool IsType(const char *token) { if ( strcmp(token, "void" ) == 0 ) return true; + if ( strcmp(token, "byte" ) == 0 ) return true; + if ( strcmp(token, "short" ) == 0 ) return true; + if ( strcmp(token, "char" ) == 0 ) return true; if ( strcmp(token, "int" ) == 0 ) return true; + if ( strcmp(token, "long" ) == 0 ) return true; if ( strcmp(token, "float" ) == 0 ) return true; + if ( strcmp(token, "double" ) == 0 ) return true; if ( strcmp(token, "bool" ) == 0 ) return true; if ( strcmp(token, "string" ) == 0 ) return true; if ( strcmp(token, "point" ) == 0 ) return true; From bc572aa52f89619cb75ffb45c3abff7ed27f2121 Mon Sep 17 00:00:00 2001 From: melex750 Date: Thu, 11 Apr 2019 04:21:22 -0400 Subject: [PATCH 097/109] Add sizeof() operator for numeric data types --- src/CBot/CBotInstr/CBotExprLitNum.cpp | 40 +++++++++++++++++++++++++++ src/CBot/CBotInstr/CBotExprLitNum.h | 2 ++ src/CBot/CBotInstr/CBotParExpr.cpp | 14 ++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/CBot/CBotInstr/CBotExprLitNum.cpp b/src/CBot/CBotInstr/CBotExprLitNum.cpp index 9842cf57..61978bf0 100644 --- a/src/CBot/CBotInstr/CBotExprLitNum.cpp +++ b/src/CBot/CBotInstr/CBotExprLitNum.cpp @@ -114,6 +114,46 @@ CBotInstr* CompileExprLitNum(CBotToken* &p, CBotCStack* pStack) return pStack->Return(nullptr, pStk); } +CBotInstr* CompileSizeOf(CBotToken* &p, CBotCStack* pStack) +{ + CBotToken* pp = p; + + if (!IsOfType(p, TokenTypVar)) return nullptr; + if (pp->GetString() == "sizeof" && IsOfType(p, ID_OPENPAR)) + { + CBotCStack* pStk = pStack->TokenStack(); + + int value; + + if (IsOfType(p, ID_BYTE)) value = sizeof(signed char); + else if (IsOfType(p, ID_SHORT)) value = sizeof(short); + else if (IsOfType(p, ID_CHAR)) value = sizeof(uint32_t); + else if (IsOfType(p, ID_INT)) value = sizeof(int); + else if (IsOfType(p, ID_LONG)) value = sizeof(long); + else if (IsOfType(p, ID_FLOAT)) value = sizeof(float); + else if (IsOfType(p, ID_DOUBLE)) value = sizeof(double); + else + { + p = pp; + return pStack->Return(nullptr, pStk); + } + + if (IsOfType(p, ID_CLOSEPAR)) + { + auto inst = new CBotExprLitNum(value); + inst->SetToken(pp); + + CBotVar* var = CBotVar::Create("", CBotTypInt); + pStk->SetVar(var); + return pStack->Return(inst, pStk); + } + pStk->SetError(CBotErrClosePar, p->GetStart()); + return pStack->Return(nullptr, pStk); + } + p = pp; + return nullptr; +} + template bool CBotExprLitNum::Execute(CBotStack* &pj) { diff --git a/src/CBot/CBotInstr/CBotExprLitNum.h b/src/CBot/CBotInstr/CBotExprLitNum.h index 92cd302d..8d7edcc1 100644 --- a/src/CBot/CBotInstr/CBotExprLitNum.h +++ b/src/CBot/CBotInstr/CBotExprLitNum.h @@ -26,6 +26,8 @@ namespace CBot CBotInstr* CompileExprLitNum(CBotToken* &p, CBotCStack* pStack); +CBotInstr* CompileSizeOf(CBotToken* &p, CBotCStack* pStack); + /** * \brief A number literal - 5, 1, 2.5, 3.75, etc. or a predefined numerical constant (see CBotToken::DefineNum()) * diff --git a/src/CBot/CBotInstr/CBotParExpr.cpp b/src/CBot/CBotInstr/CBotParExpr.cpp index 24bdaafe..9572ff5e 100644 --- a/src/CBot/CBotInstr/CBotParExpr.cpp +++ b/src/CBot/CBotInstr/CBotParExpr.cpp @@ -68,6 +68,13 @@ CBotInstr* CBotParExpr::Compile(CBotToken* &p, CBotCStack* pStack) if (inst != nullptr || !pStk->IsOk()) return pStack->Return(inst, pStk); + // is it sizeof operator ? + inst = CBot::CompileSizeOf(p, pStk); + if (inst != nullptr || !pStk->IsOk()) + { + return pStack->Return(inst, pStk); + } + // is it a variable name? if (p->GetType() == TokenTypVar) { @@ -155,6 +162,13 @@ CBotInstr* CBotParExpr::CompileLitExpr(CBotToken* &p, CBotCStack* pStack) return pStack->Return(inst, pStk); } + // is it sizeof operator ? + inst = CBot::CompileSizeOf(p, pStk); + if (inst != nullptr || !pStk->IsOk()) + { + return pStack->Return(inst, pStk); + } + // is this a chaine? if (p->GetType() == TokenTypString) { From 1058a326adad910b11f40b861d932993b64db468 Mon Sep 17 00:00:00 2001 From: melex750 Date: Thu, 11 Apr 2019 05:14:11 -0400 Subject: [PATCH 098/109] Add binary and character literals in CBOT --- po/colobot.pot | 3 + po/cs.po | 3 + po/de.po | 3 + po/fr.po | 3 + po/pl.po | 3 + po/pt.po | 3 + po/ru.po | 3 + src/CBot/CBotEnums.h | 4 +- src/CBot/CBotInstr/CBotExprLitChar.cpp | 151 +++++++++++++++++++++++ src/CBot/CBotInstr/CBotExprLitChar.h | 60 +++++++++ src/CBot/CBotInstr/CBotExprLitString.cpp | 5 +- src/CBot/CBotInstr/CBotParExpr.cpp | 8 ++ src/CBot/CBotToken.cpp | 48 +++++++ src/CBot/CBotUtils.cpp | 12 ++ src/CBot/CMakeLists.txt | 2 + src/common/restext.cpp | 1 + src/script/script.cpp | 9 +- test/unit/CBot/CBot_test.cpp | 122 ++++++++++++++++++ 18 files changed, 436 insertions(+), 7 deletions(-) create mode 100644 src/CBot/CBotInstr/CBotExprLitChar.cpp create mode 100644 src/CBot/CBotInstr/CBotExprLitChar.h diff --git a/po/colobot.pot b/po/colobot.pot index b91aba04..266d13b1 100644 --- a/po/colobot.pot +++ b/po/colobot.pot @@ -1795,6 +1795,9 @@ msgstr "" msgid "Invalid universal character name" msgstr "" +msgid "Empty character constant" +msgstr "" + msgid "Dividing by zero" msgstr "" diff --git a/po/cs.po b/po/cs.po index b5c41e3a..7f1b50d4 100644 --- a/po/cs.po +++ b/po/cs.po @@ -507,6 +507,9 @@ msgstr "Upravit vybraný program" msgid "Egg" msgstr "Vejce" +msgid "Empty character constant" +msgstr "" + msgid "End of block missing" msgstr "Chybí konec bloku" diff --git a/po/de.po b/po/de.po index 66d9918a..61f72697 100644 --- a/po/de.po +++ b/po/de.po @@ -508,6 +508,9 @@ msgstr "Gewähltes Programm bearbeiten" msgid "Egg" msgstr "Ei" +msgid "Empty character constant" +msgstr "" + msgid "End of block missing" msgstr "Es fehlt eine geschlossene geschweifte Klammer \"}\" (Ende des Blocks)" diff --git a/po/fr.po b/po/fr.po index c8d48217..f0229e72 100644 --- a/po/fr.po +++ b/po/fr.po @@ -510,6 +510,9 @@ msgstr "Éditer le programme sélectionné" msgid "Egg" msgstr "Oeuf" +msgid "Empty character constant" +msgstr "" + msgid "End of block missing" msgstr "Il manque la fin du bloc" diff --git a/po/pl.po b/po/pl.po index 073c7b58..5b9bab87 100644 --- a/po/pl.po +++ b/po/pl.po @@ -506,6 +506,9 @@ msgstr "Edytuj zaznaczony program" msgid "Egg" msgstr "Jajo" +msgid "Empty character constant" +msgstr "" + msgid "End of block missing" msgstr "Brak końca bloku" diff --git a/po/pt.po b/po/pt.po index f99a9cbf..53bdd07c 100644 --- a/po/pt.po +++ b/po/pt.po @@ -505,6 +505,9 @@ msgstr "Alterar o programa selecionado" msgid "Egg" msgstr "Ovo" +msgid "Empty character constant" +msgstr "" + msgid "End of block missing" msgstr "Fim do bloco ausente" diff --git a/po/ru.po b/po/ru.po index ca44c0c5..df68516f 100644 --- a/po/ru.po +++ b/po/ru.po @@ -514,6 +514,9 @@ msgstr "Изменить выбранную программу" msgid "Egg" msgstr "Яйцо" +msgid "Empty character constant" +msgstr "" + msgid "End of block missing" msgstr "Отсутствует конец блока" diff --git a/src/CBot/CBotEnums.h b/src/CBot/CBotEnums.h index 3dff66eb..35775295 100644 --- a/src/CBot/CBotEnums.h +++ b/src/CBot/CBotEnums.h @@ -182,7 +182,8 @@ enum TokenType TokenTypNum = 2, //!< number TokenTypString = 3, //!< string TokenTypVar = 4, //!< a variable name - TokenTypDef = 5 //!< value according DefineNum + TokenTypDef = 5, //!< value according DefineNum + TokenTypChar = 6, //!< character literal }; /** @@ -252,6 +253,7 @@ enum CBotError : int CBotErrHexDigits = 5052, //!< missing hex digits after escape sequence CBotErrHexRange = 5053, //!< hex value out of range CBotErrUnicodeName = 5054, //!< invalid universal character name + CBotErrCharEmpty = 5055, //!< empty character constant // Runtime errors CBotErrZeroDiv = 6000, //!< division by zero diff --git a/src/CBot/CBotInstr/CBotExprLitChar.cpp b/src/CBot/CBotInstr/CBotExprLitChar.cpp new file mode 100644 index 00000000..dc7de906 --- /dev/null +++ b/src/CBot/CBotInstr/CBotExprLitChar.cpp @@ -0,0 +1,151 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * 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 http://gnu.org/licenses + */ + +#include "CBot/CBotInstr/CBotExprLitChar.h" + +#include "CBot/CBotStack.h" +#include "CBot/CBotCStack.h" + +#include "CBot/CBotVar/CBotVar.h" + +namespace CBot +{ + +CBotExprLitChar::CBotExprLitChar() +{ +} + +CBotExprLitChar::~CBotExprLitChar() +{ +} + +CBotInstr* CBotExprLitChar::Compile(CBotToken* &p, CBotCStack* pStack) +{ + CBotCStack* pStk = pStack->TokenStack(); + + const auto& s = p->GetString(); + + auto it = s.cbegin(); + if (++it != s.cend()) + { + if (*it != '\'') // not empty quotes ? + { + uint32_t valchar = 0; + int pos = p->GetStart() + 1; + + if (*it != '\\') valchar = *(it++); // not escape sequence ? + else if (++it != s.cend()) + { + pStk->SetStartError(pos++); + unsigned char c = *(it++); + if (c == '\"' || c == '\'' || c == '\\') valchar = c; + else if (c == 'a') valchar = '\a'; // alert bell + else if (c == 'b') valchar = '\b'; // backspace + else if (c == 'f') valchar = '\f'; // form feed + else if (c == 'n') valchar = '\n'; // new line + else if (c == 'r') valchar = '\r'; // carriage return + else if (c == 't') valchar = '\t'; // horizontal tab + else if (c == 'v') valchar = '\v'; // vertical tab + else if (c == 'u' || c == 'U') // unicode escape + { + if (it != s.cend()) + { + std::string hex = ""; + size_t maxlen = (c == 'u') ? 4 : 8; + + for (size_t i = 0; i < maxlen; i++) + { + if (!CharInList(*it, "0123456789ABCDEFabcdef")) break; + ++pos; + hex += *it; + if (++it == s.cend()) break; + } + + if (maxlen == hex.length()) // unicode character + { + try + { + valchar = std::stoi(hex, nullptr, 16); + if (0x10FFFF < valchar || (0xD7FF < valchar && valchar < 0xE000)) + pStk->SetError(CBotErrUnicodeName, pos + 1); + } + catch (const std::out_of_range& e) + { + pStk->SetError(CBotErrHexRange, pos + 1); + } + } + else + pStk->SetError(CBotErrHexDigits, pos + 1); + } + else + pStk->SetError(CBotErrHexDigits, pos + 1); + } + else + pStk->SetError(CBotErrBadEscape, pos + 1); + } + + if (it == s.cend() || *it != '\'') + pStk->SetError(CBotErrEndQuote, p); + + if (pStk->IsOk()) + { + CBotExprLitChar* inst = new CBotExprLitChar(); + inst->m_valchar = valchar; + inst->SetToken(p); + p = p->GetNext(); + + CBotVar* var = CBotVar::Create("", CBotTypChar); + pStk->SetVar(var); + + return pStack->Return(inst, pStk); + } + } + pStk->SetError(CBotErrCharEmpty, p); + } + + pStk->SetError(CBotErrEndQuote, p); + return pStack->Return(nullptr, pStk); +} + +bool CBotExprLitChar::Execute(CBotStack* &pj) +{ + CBotStack* pile = pj->AddStack(this); + + if (pile->IfStep()) return false; + + CBotVar* var = CBotVar::Create("", CBotTypChar); + + var->SetValChar(m_valchar); + + pile->SetVar(var); + + return pj->Return(pile); +} + +void CBotExprLitChar::RestoreState(CBotStack* &pj, bool bMain) +{ + if (bMain) pj->RestoreStack(this); +} + +std::string CBotExprLitChar::GetDebugData() +{ + return m_token.GetString(); +} + +} // namespace CBot diff --git a/src/CBot/CBotInstr/CBotExprLitChar.h b/src/CBot/CBotInstr/CBotExprLitChar.h new file mode 100644 index 00000000..1f31d6d2 --- /dev/null +++ b/src/CBot/CBotInstr/CBotExprLitChar.h @@ -0,0 +1,60 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2018, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * 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 http://gnu.org/licenses + */ + +#pragma once + +#include "CBot/CBotInstr/CBotInstr.h" + +namespace CBot +{ + +/** + * \brief A character literal + * \verbatim 'a', '\n', '\t', '\uFFFD', '\U0000FFFD', etc. \endverbatim + */ +class CBotExprLitChar : public CBotInstr +{ +public: + CBotExprLitChar(); + ~CBotExprLitChar(); + + /*! + * \brief Compile a character literal + */ + static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack); + + /*! + * \brief Execute, returns the corresponding char. + */ + bool Execute(CBotStack* &pj) override; + + /*! + * \brief RestoreState + */ + void RestoreState(CBotStack* &pj, bool bMain) override; + +protected: + virtual const std::string GetDebugName() override { return "CBotExprLitChar"; } + virtual std::string GetDebugData() override; + +private: + uint32_t m_valchar = 0; +}; + +} // namespace CBot diff --git a/src/CBot/CBotInstr/CBotExprLitString.cpp b/src/CBot/CBotInstr/CBotExprLitString.cpp index 72cca72b..fc254162 100644 --- a/src/CBot/CBotInstr/CBotExprLitString.cpp +++ b/src/CBot/CBotInstr/CBotExprLitString.cpp @@ -42,7 +42,7 @@ CBotInstr* CBotExprLitString::Compile(CBotToken* &p, CBotCStack* pStack) { CBotCStack* pStk = pStack->TokenStack(); - std::string s = p->GetString(); + const auto& s = p->GetString(); auto it = s.cbegin(); if (++it != s.cend()) @@ -51,7 +51,7 @@ CBotInstr* CBotExprLitString::Compile(CBotToken* &p, CBotCStack* pStack) std::string valstring = ""; while (it != s.cend() && *it != '\"') { - pStk->SetStartError(++pos); + ++pos; if (*it != '\\') // not escape sequence ? { valstring += *(it++); @@ -59,6 +59,7 @@ CBotInstr* CBotExprLitString::Compile(CBotToken* &p, CBotCStack* pStack) } if (++it == s.cend()) break; + pStk->SetStartError(pos); if (CharInList(*it, "01234567")) // octal { diff --git a/src/CBot/CBotInstr/CBotParExpr.cpp b/src/CBot/CBotInstr/CBotParExpr.cpp index 9572ff5e..fa455c27 100644 --- a/src/CBot/CBotInstr/CBotParExpr.cpp +++ b/src/CBot/CBotInstr/CBotParExpr.cpp @@ -21,6 +21,7 @@ #include "CBot/CBotInstr/CBotExpression.h" #include "CBot/CBotInstr/CBotExprLitBool.h" +#include "CBot/CBotInstr/CBotExprLitChar.h" #include "CBot/CBotInstr/CBotExprLitNan.h" #include "CBot/CBotInstr/CBotExprLitNull.h" #include "CBot/CBotInstr/CBotExprLitNum.h" @@ -169,6 +170,13 @@ CBotInstr* CBotParExpr::CompileLitExpr(CBotToken* &p, CBotCStack* pStack) return pStack->Return(inst, pStk); } + // is this a character? + if (p->GetType() == TokenTypChar) + { + CBotInstr* inst = CBotExprLitChar::Compile(p, pStk); + return pStack->Return(inst, pStk); + } + // is this a chaine? if (p->GetType() == TokenTypString) { diff --git a/src/CBot/CBotToken.cpp b/src/CBot/CBotToken.cpp index d5afe1fe..9764d237 100644 --- a/src/CBot/CBotToken.cpp +++ b/src/CBot/CBotToken.cpp @@ -304,12 +304,53 @@ CBotToken* CBotToken::NextToken(const char*& program, bool first) stop = true; } + // special case for characters + if (token[0] == '\'') + { + if (c == '\\') // escape sequence + { + token += c; + c = *(program++); + + if (c == 'u' || c == 'U') // unicode escape + { + int maxlen = (c == 'u') ? 4 : 8; + token += c; + c = *(program++); + for (int i = 0; i < maxlen; i++) + { + if (c == 0 || !CharInList(c, hexnum)) break; + token += c; + c = *(program++); + } + } + else if (c != 0 && !CharInList(c, nch)) // other escape char + { + token += c; + c = *(program++); + } + } + else if (c != 0 && c != '\'' && !CharInList(c, nch)) // single character + { + token += c; + c = *(program++); + } + + if (c == '\'') // close quote + { + token += c; + c = *(program++); + } + stop = true; + } + // special case for numbers if ( CharInList(token[0], num )) { bool bdot = false; // found a point? bool bexp = false; // found an exponent? + char bin[] = "01"; char* liste = num; if (token[0] == '0' && c == 'x') // hexadecimal value? { @@ -317,6 +358,12 @@ CBotToken* CBotToken::NextToken(const char*& program, bool first) c = *(program++); // next character liste = hexnum; } + else if (token[0] == '0' && c == 'b') // binary literal + { + liste = bin; + token += c; + c = *(program++); + } cw: while (c != 0 && CharInList(c, liste)) { @@ -399,6 +446,7 @@ bis: if (CharInList(token[0], num )) t->m_type = TokenTypNum; if (token[0] == '\"') t->m_type = TokenTypString; + if (token[0] == '\'') t->m_type = TokenTypChar; if (first) t->m_type = TokenTypNone; t->m_keywordId = GetKeyWord(token); diff --git a/src/CBot/CBotUtils.cpp b/src/CBot/CBotUtils.cpp index 4d663bea..afa05bbc 100644 --- a/src/CBot/CBotUtils.cpp +++ b/src/CBot/CBotUtils.cpp @@ -155,6 +155,18 @@ long GetNumInt(const std::string& str) break; } } + else if (*p == 'b') + { + while (*++p != 0) + { + if (*p == '0' || *p == '1') + { + num = (num << 1) + *p - '0'; + continue; + } + break; + } + } return num; } diff --git a/src/CBot/CMakeLists.txt b/src/CBot/CMakeLists.txt index 4be97841..45af8639 100644 --- a/src/CBot/CMakeLists.txt +++ b/src/CBot/CMakeLists.txt @@ -44,6 +44,8 @@ set(SOURCES CBotInstr/CBotEmpty.h CBotInstr/CBotExprLitBool.cpp CBotInstr/CBotExprLitBool.h + CBotInstr/CBotExprLitChar.cpp + CBotInstr/CBotExprLitChar.h CBotInstr/CBotExprLitNan.cpp CBotInstr/CBotExprLitNan.h CBotInstr/CBotExprLitNull.cpp diff --git a/src/common/restext.cpp b/src/common/restext.cpp index 4aa21564..065f6c92 100644 --- a/src/common/restext.cpp +++ b/src/common/restext.cpp @@ -742,6 +742,7 @@ void InitializeRestext() stringsCbot[CBot::CBotErrHexDigits] = TR("Missing hex digits after escape sequence"); stringsCbot[CBot::CBotErrHexRange] = TR("Hex value out of range"); stringsCbot[CBot::CBotErrUnicodeName] = TR("Invalid universal character name"); + stringsCbot[CBot::CBotErrCharEmpty] = TR("Empty character constant"); stringsCbot[CBot::CBotErrZeroDiv] = TR("Dividing by zero"); stringsCbot[CBot::CBotErrNotInit] = TR("Variable not initialized"); diff --git a/src/script/script.cpp b/src/script/script.cpp index 22ae1024..0b5828aa 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -589,16 +589,17 @@ void CScript::UpdateList(Ui::CList* list) list->SetState(Ui::STATE_ENABLE); } -// Colorize a string literal with escape sequences also colored +// Colorize a string or character literal with escape sequences also colored static void HighlightString(Ui::CEdit* edit, const std::string& s, int start) { edit->SetFormat(start, start + 1, Gfx::FONT_HIGHLIGHT_STRING); - auto it = s.cbegin() + 1; + auto it = s.cbegin(); + char endQuote = *(it++); ++start; - while (it != s.cend() && *it != '\"') + while (it != s.cend() && *it != endQuote) { if (*(it++) != '\\') // not escape sequence { @@ -697,7 +698,7 @@ void CScript::ColorizeScript(Ui::CEdit* edit, int rangeStart, int rangeEnd) { color = Gfx::FONT_HIGHLIGHT_STRING; } - else if (type == CBot::TokenTypString) // string literals + else if (type == CBot::TokenTypString || type == CBot::TokenTypChar) // string literals and character literals { HighlightString(edit, token, cursor1); bt = bt->GetNext(); diff --git a/test/unit/CBot/CBot_test.cpp b/test/unit/CBot/CBot_test.cpp index 6f2201b9..4c60b8fa 100644 --- a/test/unit/CBot/CBot_test.cpp +++ b/test/unit/CBot/CBot_test.cpp @@ -619,6 +619,27 @@ TEST_F(CBotUT, IntegerMathNearLimits_Issue993) ); } +TEST_F(CBotUT, BinaryLiterals) +{ + ExecuteTest( + "extern void TestBinaryLiterals() {\n" + " ASSERT( 8 == 0b00001000);\n" + " ASSERT( 12 == 0b00001100);\n" + " ASSERT( 16 == 0b00010000);\n" + " ASSERT( 24 == 0b00011000);\n" + " ASSERT( 32 == 0b00100000);\n" + " ASSERT( 48 == 0b00110000);\n" + " ASSERT( 64 == 0b01000000);\n" + " ASSERT( 96 == 0b01100000);\n" + " ASSERT(128 == 0b10000000);\n" + " ASSERT(192 == 0b11000000);\n" + " ASSERT(256 == 0b100000000);\n" + " ASSERT(384 == 0b110000000);\n" + " ASSERT(512 == 0b1000000000);\n" + "}\n" + ); +} + TEST_F(CBotUT, ToString) { ExecuteTest( @@ -1752,6 +1773,107 @@ TEST_F(CBotUT, StringFunctions) ); } +TEST_F(CBotUT, LiteralCharacters) +{ + ExecuteTest( + "extern void TestCharValue()\n" + "{\n" + " ASSERT('A' == 65);\n" + " ASSERT('B' == 66);\n" + " ASSERT('C' == 67);\n" + " ASSERT('\\a' == 0x07);\n" + " ASSERT('\\b' == 0x08);\n" + " ASSERT('\\t' == 0x09);\n" + " ASSERT('\\n' == 0x0A);\n" + " ASSERT('\\v' == 0x0B);\n" + " ASSERT('\\f' == 0x0C);\n" + " ASSERT('\\r' == 0x0D);\n" + " ASSERT('\\\"' == 0x22);\n" + " ASSERT('\\\'' == 0x27);\n" + " ASSERT('\\\\' == 0x5C);\n" + "}\n" + "extern void TestCharUnicodeEscape()\n" + "{\n" + " ASSERT('\\u0007' == '\\a');\n" + " ASSERT('\\u0008' == '\\b');\n" + " ASSERT('\\u0009' == '\\t');\n" + " ASSERT('\\u000A' == '\\n');\n" + " ASSERT('\\u000B' == '\\v');\n" + " ASSERT('\\u000C' == '\\f');\n" + " ASSERT('\\u000D' == '\\r');\n" + " ASSERT('\\u0022' == '\\\"');\n" + " ASSERT('\\u0027' == '\\\'');\n" + " ASSERT('\\u005C' == '\\\\');\n" + "}\n" + "extern void AssignCharToString_ToUTF_8()\n" + "{\n" + " string test = '\\u00A9';\n" + " test += '\\u00AE';\n" + " ASSERT(test == \"\\xC2\\xA9\\xC2\\xAE\");\n" + "}\n" + "extern void AddCharToString_ToUTF_8()\n" + "{\n" + " ASSERT(\"\" + 'A' + 'B' + 'C' == \"ABC\");\n" + " ASSERT(\"\" + '\\u00A9' == \"\\xC2\\xA9\");\n" + " ASSERT(\"\" + '\\u00AE' == \"\\xC2\\xAE\");\n" + " ASSERT(\"\" + '\\u262E' == \"\\xE2\\x98\\xAE\");\n" + " ASSERT(\"\" + '\\u262F' == \"\\xE2\\x98\\xAF\");\n" + " ASSERT(\"\" + '\\U0001F60E' == \"\\xF0\\x9F\\x98\\x8E\");\n" + " ASSERT(\"\" + '\\U0001F61C' == \"\\xF0\\x9F\\x98\\x9C\");\n" + " ASSERT(\"\" + '\\U0001F6E0' == \"\\xF0\\x9F\\x9B\\xA0\");\n" + " ASSERT(\"\" + '\\U0010FFFF' == \"\\xF4\\x8F\\xBF\\xBF\");\n" + "}\n" + ); + + ExecuteTest( + "extern void MissingEndQuote()\n" + "{\n" + " '\n" + "}\n", + CBotErrEndQuote + ); + + ExecuteTest( + "extern void MissingEndQuote()\n" + "{\n" + " 'a\n" + "}\n", + CBotErrEndQuote + ); + + ExecuteTest( + "extern void EmptyQuotes()\n" + "{\n" + " '';\n" + "}\n", + CBotErrCharEmpty + ); + + ExecuteTest( + "extern void UnknownEscapeSequence()\n" + "{\n" + " '\\p';\n" + "}\n", + CBotErrBadEscape + ); + + ExecuteTest( + "extern void MissingHexDigits()\n" + "{\n" + " '\\u';\n" + "}\n", + CBotErrHexDigits + ); + + ExecuteTest( + "extern void BadUnicodeCharacterName()\n" + "{\n" + " '\\U00110000';\n" + "}\n", + CBotErrUnicodeName + ); +} + TEST_F(CBotUT, TestNANParam_Issue642) { ExecuteTest( From 5f089f4a9bc2276ee2879e7fc77af222736c7595 Mon Sep 17 00:00:00 2001 From: melex750 Date: Thu, 11 Apr 2019 05:34:00 -0400 Subject: [PATCH 099/109] Fix and improve switch...case (#1008) --- po/colobot.pot | 3 + po/cs.po | 3 + po/de.po | 3 + po/fr.po | 3 + po/pl.po | 3 + po/pt.po | 3 + po/ru.po | 3 + src/CBot/CBotEnums.h | 1 + src/CBot/CBotInstr/CBotCase.cpp | 98 +++++++++++++++++++-------- src/CBot/CBotInstr/CBotCase.h | 19 ++---- src/CBot/CBotInstr/CBotExprUnaire.cpp | 9 +-- src/CBot/CBotInstr/CBotExprUnaire.h | 2 +- src/CBot/CBotInstr/CBotInstr.cpp | 7 -- src/CBot/CBotInstr/CBotInstr.h | 11 --- src/CBot/CBotInstr/CBotParExpr.cpp | 58 +++++++++++++++- src/CBot/CBotInstr/CBotParExpr.h | 4 +- src/CBot/CBotInstr/CBotSwitch.cpp | 76 ++++++++++----------- src/CBot/CBotInstr/CBotSwitch.h | 10 ++- src/CBot/CBotInstr/CBotTwoOpExpr.cpp | 13 ++-- src/CBot/CBotInstr/CBotTwoOpExpr.h | 2 +- src/common/restext.cpp | 1 + test/unit/CBot/CBot_test.cpp | 86 +++++++++++++++++++++++ 22 files changed, 298 insertions(+), 120 deletions(-) diff --git a/po/colobot.pot b/po/colobot.pot index 266d13b1..7cbb92d7 100644 --- a/po/colobot.pot +++ b/po/colobot.pot @@ -1798,6 +1798,9 @@ msgstr "" msgid "Empty character constant" msgstr "" +msgid "Duplicate label in switch" +msgstr "" + msgid "Dividing by zero" msgstr "" diff --git a/po/cs.po b/po/cs.po index 7f1b50d4..b14eb434 100644 --- a/po/cs.po +++ b/po/cs.po @@ -489,6 +489,9 @@ msgstr "Dolů (\\key gdown;)" msgid "Drawer bot" msgstr "Tužkobot" +msgid "Duplicate label in switch" +msgstr "" + msgid "Dust\\Dust and dirt on bots and buildings" msgstr "Prach\\Prach a špína na robotech a budovách" diff --git a/po/de.po b/po/de.po index 61f72697..f031a049 100644 --- a/po/de.po +++ b/po/de.po @@ -490,6 +490,9 @@ msgstr "Sinkt (\\key gdown;)" msgid "Drawer bot" msgstr "Zeichner" +msgid "Duplicate label in switch" +msgstr "" + msgid "Dust\\Dust and dirt on bots and buildings" msgstr "Schmutz\\Schmutz auf Robotern und Bauten" diff --git a/po/fr.po b/po/fr.po index f0229e72..5c904b95 100644 --- a/po/fr.po +++ b/po/fr.po @@ -492,6 +492,9 @@ msgstr "Descend (\\key gdown;)" msgid "Drawer bot" msgstr "Robot dessinateur" +msgid "Duplicate label in switch" +msgstr "" + msgid "Dust\\Dust and dirt on bots and buildings" msgstr "Salissures\\Salissures des robots et bâtiments" diff --git a/po/pl.po b/po/pl.po index 5b9bab87..35be67e1 100644 --- a/po/pl.po +++ b/po/pl.po @@ -488,6 +488,9 @@ msgstr "Dół (\\key gdown;)" msgid "Drawer bot" msgstr "Robot rysownik" +msgid "Duplicate label in switch" +msgstr "" + msgid "Dust\\Dust and dirt on bots and buildings" msgstr "Kurz\\Kurz i bród na robotach i budynkach" diff --git a/po/pt.po b/po/pt.po index 53bdd07c..06bb43e3 100644 --- a/po/pt.po +++ b/po/pt.po @@ -487,6 +487,9 @@ msgstr "Baixo (\\key gdown;)" msgid "Drawer bot" msgstr "Robô cartoonista" +msgid "Duplicate label in switch" +msgstr "" + msgid "Dust\\Dust and dirt on bots and buildings" msgstr "Poeira\\Poeira e sujeira nos robôs e prédios" diff --git a/po/ru.po b/po/ru.po index df68516f..37852277 100644 --- a/po/ru.po +++ b/po/ru.po @@ -496,6 +496,9 @@ msgstr "Вниз (\\key gdown;)" msgid "Drawer bot" msgstr "Рисовальщик" +msgid "Duplicate label in switch" +msgstr "" + msgid "Dust\\Dust and dirt on bots and buildings" msgstr "Пыль\\Пыль и грязь на ботах и зданиях" diff --git a/src/CBot/CBotEnums.h b/src/CBot/CBotEnums.h index 35775295..2f04707d 100644 --- a/src/CBot/CBotEnums.h +++ b/src/CBot/CBotEnums.h @@ -254,6 +254,7 @@ enum CBotError : int CBotErrHexRange = 5053, //!< hex value out of range CBotErrUnicodeName = 5054, //!< invalid universal character name CBotErrCharEmpty = 5055, //!< empty character constant + CBotErrRedefCase = 5056, //!< duplicate label in switch // Runtime errors CBotErrZeroDiv = 6000, //!< division by zero diff --git a/src/CBot/CBotInstr/CBotCase.cpp b/src/CBot/CBotInstr/CBotCase.cpp index 15c8d4f7..2e0cc7f0 100644 --- a/src/CBot/CBotInstr/CBotCase.cpp +++ b/src/CBot/CBotInstr/CBotCase.cpp @@ -19,7 +19,7 @@ #include "CBot/CBotInstr/CBotCase.h" -#include "CBot/CBotInstr/CBotExprLitNum.h" +#include "CBot/CBotInstr/CBotTwoOpExpr.h" #include "CBot/CBotStack.h" #include "CBot/CBotCStack.h" @@ -30,69 +30,107 @@ namespace CBot //////////////////////////////////////////////////////////////////////////////// CBotCase::CBotCase() { - m_value = nullptr; + m_instr = nullptr; } //////////////////////////////////////////////////////////////////////////////// CBotCase::~CBotCase() { - delete m_value; + delete m_instr; } -//////////////////////////////////////////////////////////////////////////////// -CBotInstr* CBotCase::Compile(CBotToken* &p, CBotCStack* pStack) +CBotInstr* CBotCase::Compile(CBotToken* &p, CBotCStack* pStack, std::unordered_map& labels) { - CBotCase* inst = new CBotCase(); // creates the object CBotToken* pp = p; // preserves at the ^ token (starting position) - inst->SetToken(p); if (!IsOfType(p, ID_CASE, ID_DEFAULT)) return nullptr; // should never happen + pStack->SetStartError(pp->GetStart()); - if ( pp->GetType() == ID_CASE ) + long labelValue = 0; + + if (pp->GetType() == ID_CASE) { - pp = p; - inst->m_value = CBot::CompileExprLitNum(p, pStack); - if (inst->m_value == nullptr ) + CBotInstr* i = nullptr; + if (nullptr != (i = CBotTwoOpExpr::Compile(p, pStack, nullptr, true))) { - pStack->SetError( CBotErrBadNum, pp ); - delete inst; - return nullptr; + if (pStack->GetType() <= CBotTypLong) + { + CBotStack* pile = CBotStack::AllocateStack(); + while ( !i->Execute(pile) ); + labelValue = pile->GetVar()->GetValLong(); + pile->Delete(); + + if (labels.count(labelValue) > 0) + { + pStack->SetError(CBotErrRedefCase, p->GetStart()); + } + } + else + pStack->SetError(CBotErrBadNum, p->GetStart()); + delete i; } - } - if ( !IsOfType( p, ID_DOTS )) - { - pStack->SetError( CBotErrNoDoubleDots, p->GetStart() ); - delete inst; - return nullptr; + else + pStack->SetError(CBotErrBadNum, p->GetStart()); } - return inst; + if (pStack->IsOk() && IsOfType(p, ID_DOTS)) + { + CBotCase* newCase = new CBotCase(); + newCase->SetToken(pp); + if (pp->GetType() == ID_CASE) + labels[labelValue] = newCase; + return newCase; + } + + pStack->SetError(CBotErrNoDoubleDots, p->GetStart()); + return nullptr; } //////////////////////////////////////////////////////////////////////////////// bool CBotCase::Execute(CBotStack* &pj) { - return true; // the "case" statement does nothing! + if (m_instr == nullptr) return true; + CBotStack* pile = pj->AddStack(this, CBotStack::BlockVisibilityType::BLOCK); + + int state = pile->GetState(); + CBotInstr* p = m_instr; + while (state-- > 0) p = p->GetNext(); + + while (p != nullptr) + { + if (!p->Execute(pile)) return false; + pile->IncState(); + p = p->GetNext(); + } + + pile->Delete(); + return pj->IsOk(); } //////////////////////////////////////////////////////////////////////////////// void CBotCase::RestoreState(CBotStack* &pj, bool bMain) { -} + if (!bMain) return; -//////////////////////////////////////////////////////////////////////////////// -bool CBotCase::CompCase(CBotStack* &pile, int val) -{ - if (m_value == nullptr ) return true; // "default" case + CBotStack* pile = pj->RestoreStack(this); + if (pile == nullptr) return; - while (!m_value->Execute(pile)); // puts the value on the correspondent stack (without interruption) - return (pile->GetVal() == val); // compared with the given value + CBotInstr* p = m_instr; + + int state = pile->GetState(); + while (p != nullptr && state-- > 0) + { + p->RestoreState(pile, bMain); + p = p->GetNext(); + } + + if (p != nullptr) p->RestoreState(pile, bMain); } std::map CBotCase::GetDebugLinks() { auto links = CBotInstr::GetDebugLinks(); - links["m_value"] = m_value; + links["m_instr"] = m_instr; return links; } diff --git a/src/CBot/CBotInstr/CBotCase.h b/src/CBot/CBotInstr/CBotCase.h index e2863cde..ccd031e8 100644 --- a/src/CBot/CBotInstr/CBotCase.h +++ b/src/CBot/CBotInstr/CBotCase.h @@ -21,6 +21,8 @@ #include "CBot/CBotInstr/CBotInstr.h" +#include + namespace CBot { @@ -42,7 +44,7 @@ public: * \param pStack * \return */ - static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack); + static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, std::unordered_map& labels); /*! * \brief Execute Execution of instruction "case". @@ -58,22 +60,15 @@ public: */ void RestoreState(CBotStack* &pj, bool bMain) override; - /*! - * \brief CompCase Routine to find the entry point of "case" corresponding - * to the value seen. - * \param pj - * \param val - * \return - */ - bool CompCase(CBotStack* &pj, int val) override; - protected: virtual const std::string GetDebugName() override { return "CBotCase"; } virtual std::map GetDebugLinks() override; private: - //! Value to compare. - CBotInstr* m_value; + //! List of instructions after case label + CBotInstr* m_instr; + + friend class CBotSwitch; }; } // namespace CBot diff --git a/src/CBot/CBotInstr/CBotExprUnaire.cpp b/src/CBot/CBotInstr/CBotExprUnaire.cpp index c39fd89e..d9a6c4d4 100644 --- a/src/CBot/CBotInstr/CBotExprUnaire.cpp +++ b/src/CBot/CBotInstr/CBotExprUnaire.cpp @@ -40,8 +40,7 @@ CBotExprUnaire::~CBotExprUnaire() delete m_expr; } -//////////////////////////////////////////////////////////////////////////////// -CBotInstr* CBotExprUnaire::Compile(CBotToken* &p, CBotCStack* pStack, bool bLiteral) +CBotInstr* CBotExprUnaire::Compile(CBotToken* &p, CBotCStack* pStack, bool bLiteral, bool bConstExpr) { int op = p->GetType(); CBotToken* pp = p; @@ -52,8 +51,10 @@ CBotInstr* CBotExprUnaire::Compile(CBotToken* &p, CBotCStack* pStack, bool bLite CBotExprUnaire* inst = new CBotExprUnaire(); inst->SetToken(pp); - if (!bLiteral) inst->m_expr = CBotParExpr::Compile(p, pStk); - else inst->m_expr = CBotParExpr::CompileLitExpr(p, pStk); + if (bConstExpr || !bLiteral) + inst->m_expr = CBotParExpr::Compile(p, pStk, bConstExpr); + else + inst->m_expr = CBotParExpr::CompileLitExpr(p, pStk); if (inst->m_expr != nullptr) { diff --git a/src/CBot/CBotInstr/CBotExprUnaire.h b/src/CBot/CBotInstr/CBotExprUnaire.h index 8a743a81..82d124a5 100644 --- a/src/CBot/CBotInstr/CBotExprUnaire.h +++ b/src/CBot/CBotInstr/CBotExprUnaire.h @@ -40,7 +40,7 @@ public: * \param bLiteral If true, compiles only literal expressions Ex: ~11, -4.0, !false, not true * \return The compiled instruction or nullptr */ - static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool bLiteral = false); + static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool bLiteral = false, bool bConstExpr = false); /*! * \brief Execute diff --git a/src/CBot/CBotInstr/CBotInstr.cpp b/src/CBot/CBotInstr/CBotInstr.cpp index 04b13204..54d9cee9 100644 --- a/src/CBot/CBotInstr/CBotInstr.cpp +++ b/src/CBot/CBotInstr/CBotInstr.cpp @@ -317,13 +317,6 @@ void CBotInstr::RestoreStateVar(CBotStack* &pile, bool bMain) assert(0); // dad do not know, see the girls } -//////////////////////////////////////////////////////////////////////////////// -bool CBotInstr::CompCase(CBotStack* &pj, int val) -{ - return false; -} - -//////////////////////////////////////////////////////////////////////////////// CBotInstr* CBotInstr::CompileArray(CBotToken* &p, CBotCStack* pStack, CBotTypResult type, bool first) { if (IsOfType(p, ID_OPBRK)) diff --git a/src/CBot/CBotInstr/CBotInstr.h b/src/CBot/CBotInstr/CBotInstr.h index 712b379d..2c4d5884 100644 --- a/src/CBot/CBotInstr/CBotInstr.h +++ b/src/CBot/CBotInstr/CBotInstr.h @@ -191,17 +191,6 @@ public: virtual void RestoreStateVar(CBotStack* &pile, bool bMain); - /** - * \brief CompCase This routine is defined only for the subclass CBotCase - * this allows to make the call on all instructions CompCase to see if it's - * a case to the desired value.. - * \param pj - * \param val - * \return - */ - virtual bool CompCase(CBotStack* &pj, - int val); - /** * \brief SetToken Set the token corresponding to the instruction. * \param p diff --git a/src/CBot/CBotInstr/CBotParExpr.cpp b/src/CBot/CBotInstr/CBotParExpr.cpp index fa455c27..9dd784bc 100644 --- a/src/CBot/CBotInstr/CBotParExpr.cpp +++ b/src/CBot/CBotInstr/CBotParExpr.cpp @@ -32,6 +32,7 @@ #include "CBot/CBotInstr/CBotNew.h" #include "CBot/CBotInstr/CBotPostIncExpr.h" #include "CBot/CBotInstr/CBotPreIncExpr.h" +#include "CBot/CBotInstr/CBotTwoOpExpr.h" #include "CBot/CBotVar/CBotVar.h" @@ -40,13 +41,15 @@ namespace CBot { -//////////////////////////////////////////////////////////////////////////////// -CBotInstr* CBotParExpr::Compile(CBotToken* &p, CBotCStack* pStack) +CBotInstr* CBotParExpr::Compile(CBotToken* &p, CBotCStack* pStack, bool bConstExpr) { CBotCStack* pStk = pStack->TokenStack(); pStk->SetStartError(p->GetStart()); + if (bConstExpr) + return CBotParExpr::CompileConstExpr(p, pStack); + // is it an expression in parentheses? if (IsOfType(p, ID_OPENPAR)) { @@ -224,4 +227,55 @@ CBotInstr* CBotParExpr::CompileLitExpr(CBotToken* &p, CBotCStack* pStack) return pStack->Return(nullptr, pStk); } +CBotInstr* CBotParExpr::CompileConstExpr(CBotToken* &p, CBotCStack* pStack) +{ + CBotCStack* pStk = pStack->TokenStack(); + + // is it an expression in parentheses? + if (IsOfType(p, ID_OPENPAR)) + { + CBotInstr* inst = CBotTwoOpExpr::Compile(p, pStk, nullptr, true); + + if (nullptr != inst) + { + if (IsOfType(p, ID_CLOSEPAR)) + { + return pStack->Return(inst, pStk); + } + pStk->SetError(CBotErrClosePar, p->GetStart()); + } + delete inst; + return pStack->Return(nullptr, pStk); + } + + // is this a unary operation? + CBotInstr* inst = CBotExprUnaire::Compile(p, pStk, true, true); + if (inst != nullptr || !pStk->IsOk()) + return pStack->Return(inst, pStk); + + // is it a number or DefineNum? + if (p->GetType() == TokenTypNum || + p->GetType() == TokenTypDef ) + { + CBotInstr* inst = CBot::CompileExprLitNum(p, pStk); + return pStack->Return(inst, pStk); + } + + // is this a character? + if (p->GetType() == TokenTypChar) + { + CBotInstr* inst = CBotExprLitChar::Compile(p, pStk); + return pStack->Return(inst, pStk); + } + + // is it sizeof operator ? + inst = CBot::CompileSizeOf(p, pStk); + if (inst != nullptr || !pStk->IsOk()) + { + return pStack->Return(inst, pStk); + } + + return pStack->Return(nullptr, pStk); +} + } // namespace CBot diff --git a/src/CBot/CBotInstr/CBotParExpr.h b/src/CBot/CBotInstr/CBotParExpr.h index 235dab11..826b1cd1 100644 --- a/src/CBot/CBotInstr/CBotParExpr.h +++ b/src/CBot/CBotInstr/CBotParExpr.h @@ -52,7 +52,7 @@ public: * \param pStack * \return */ - static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack); + static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool bConstExpr = false); /*! * \brief Compile a literal expression ("string", number, true, false, null, nan, new) @@ -62,6 +62,8 @@ public: */ static CBotInstr* CompileLitExpr(CBotToken* &p, CBotCStack* pStack); + static CBotInstr* CompileConstExpr(CBotToken* &p, CBotCStack* pStack); + private: CBotParExpr() = delete; CBotParExpr(const CBotParExpr&) = delete; diff --git a/src/CBot/CBotInstr/CBotSwitch.cpp b/src/CBot/CBotInstr/CBotSwitch.cpp index e8d1b24d..a889348b 100644 --- a/src/CBot/CBotInstr/CBotSwitch.cpp +++ b/src/CBot/CBotInstr/CBotSwitch.cpp @@ -57,7 +57,7 @@ CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack) { if ( nullptr != (inst->m_value = CBotExpression::Compile(p, pStk )) ) { - if ( pStk->GetType() < CBotTypLong ) + if ( pStk->GetType() <= CBotTypLong ) { if ( IsOfType(p, ID_CLOSEPAR ) ) { @@ -65,21 +65,35 @@ CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack) { IncLvl(); + CBotCase* caseInst = nullptr; + CBotCStack* pStk2 = nullptr; while( !IsOfType( p, ID_CLBLK ) ) { if ( p->GetType() == ID_CASE || p->GetType() == ID_DEFAULT) { - CBotCStack* pStk2 = pStk->TokenStack(p); // un petit bout de pile svp + delete pStk2; + pStk2 = pStk->TokenStack(p, true); // un petit bout de pile svp - CBotInstr* i = CBotCase::Compile( p, pStk2 ); - if (i == nullptr) + caseInst = static_cast(CBotCase::Compile(p, pStk2, inst->m_labels)); + if (caseInst == nullptr) { delete inst; return pStack->Return(nullptr, pStk2); } - delete pStk2; - if (inst->m_block == nullptr ) inst->m_block = i; - else inst->m_block->AddNext(i); + + if (inst->m_block == nullptr ) inst->m_block = caseInst; + else inst->m_block->AddNext(caseInst); + + if (ID_DEFAULT == caseInst->GetTokenType()) + { + if (inst->m_default != nullptr) + { + pStk->SetError(CBotErrRedefCase, caseInst->GetToken()); + delete inst; + return pStack->Return(nullptr, pStk); + } + inst->m_default = caseInst; + } continue; } @@ -90,13 +104,14 @@ CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack) return pStack->Return(nullptr, pStk); } - CBotInstr* i = CBotBlock::CompileBlkOrInst( p, pStk, true ); - if ( !pStk->IsOk() ) + CBotInstr* i = CBotBlock::CompileBlkOrInst(p, pStk2); + if ( !pStk2->IsOk() ) { delete inst; - return pStack->Return(nullptr, pStk); + return pStack->Return(nullptr, pStk2); } - inst->m_block->AddNext(i); + if (caseInst->m_instr == nullptr ) caseInst->m_instr = i; + else caseInst->m_instr->AddNext(i); if ( p == nullptr ) { @@ -133,40 +148,21 @@ CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack) bool CBotSwitch :: Execute(CBotStack* &pj) { CBotStack* pile1 = pj->AddStack(this); // adds an item to the stack -// if ( pile1 == EOX ) return true; - - CBotInstr* p = m_block; // first expression int state = pile1->GetState(); if (state == 0) { if ( !m_value->Execute(pile1) ) return false; - pile1->SetState(state = -1); + pile1->SetState(state = 1); } if ( pile1->IfStep() ) return false; - if ( state == -1 ) - { - state = 0; - int val = pile1->GetVal(); // result of the value + auto it = m_labels.find(pile1->GetVar()->GetValLong()); - CBotStack* pile2 = pile1->AddStack(); - while ( p != nullptr ) // search for the corresponding case in a list - { - state++; - if ( p->CompCase( pile2, val ) ) break; // found the case - p = p->GetNext(); - } - pile2->Delete(); + CBotInstr* p = (it != m_labels.end()) ? it->second : m_default; - if ( p == nullptr ) return pj->Return(pile1); // completed if nothing - - if ( !pile1->SetState(state) ) return false; - } - - p = m_block; // returns to the beginning - while (state-->0) p = p->GetNext(); // advance in the list + while (--state > 0) p = p->GetNext(); while( p != nullptr ) { @@ -185,8 +181,6 @@ void CBotSwitch :: RestoreState(CBotStack* &pj, bool bMain) CBotStack* pile1 = pj->RestoreStack(this); // adds an item to the stack if ( pile1 == nullptr ) return; - CBotInstr* p = m_block; // first expression - int state = pile1->GetState(); if (state == 0) { @@ -194,13 +188,11 @@ void CBotSwitch :: RestoreState(CBotStack* &pj, bool bMain) return; } - if ( state == -1 ) - { - return; - } + auto it = m_labels.find(pile1->GetVar()->GetValLong()); -// p = m_block; // returns to the beginning - while ( p != nullptr && state-- > 0 ) + CBotInstr* p = (it != m_labels.end()) ? it->second : m_default; + + while (p != nullptr && --state > 0) { p->RestoreState(pile1, false); p = p->GetNext(); // advance in the list diff --git a/src/CBot/CBotInstr/CBotSwitch.h b/src/CBot/CBotInstr/CBotSwitch.h index ca6b2b20..0ebcddf0 100644 --- a/src/CBot/CBotInstr/CBotSwitch.h +++ b/src/CBot/CBotInstr/CBotSwitch.h @@ -21,6 +21,8 @@ #include "CBot/CBotInstr/CBotInstr.h" +#include + namespace CBot { @@ -64,8 +66,12 @@ protected: private: //! Value to seek CBotInstr* m_value; - //! Instructions - CBotInstr* m_block; + //! List of case instructions + CBotInstr* m_block = nullptr; + //! Pointer to default label + CBotInstr* m_default = nullptr; + //! Map of case labels + std::unordered_map m_labels; }; } // namespace CBot diff --git a/src/CBot/CBotInstr/CBotTwoOpExpr.cpp b/src/CBot/CBotInstr/CBotTwoOpExpr.cpp index ab8b0da9..c1b2d278 100644 --- a/src/CBot/CBotInstr/CBotTwoOpExpr.cpp +++ b/src/CBot/CBotInstr/CBotTwoOpExpr.cpp @@ -133,8 +133,7 @@ static bool TypeOk(int type, int test) } } -//////////////////////////////////////////////////////////////////////////////// -CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOperations) +CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOperations, bool bConstExpr) { int typeMask; @@ -146,8 +145,8 @@ CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOpera // search the intructions that may be suitable to the left of the operation CBotInstr* left = (*pOp == 0) ? - CBotParExpr::Compile( p, pStk ) : // expression (...) left - CBotTwoOpExpr::Compile( p, pStk, pOp ); // expression A * B left + CBotParExpr::Compile(p, pStk, bConstExpr) : // expression (...) left + CBotTwoOpExpr::Compile(p, pStk, pOp, bConstExpr); // expression A * B left if (left == nullptr) return pStack->Return(nullptr, pStk); // if error, transmit @@ -158,7 +157,7 @@ CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOpera CBotTypResult type1, type2; type1 = pStk->GetTypResult(); // what kind of the first operand? - if (typeOp == ID_LOGIC) // special case provided for: ? op1: op2; + if (!bConstExpr && typeOp == ID_LOGIC) // special case provided for: ? op1: op2; { if ( !type1.Eq(CBotTypBoolean) ) { @@ -207,7 +206,7 @@ CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOpera // looking statements that may be suitable for right - if ( nullptr != (inst->m_rightop = CBotTwoOpExpr::Compile( p, pStk, pOp )) ) + if ( nullptr != (inst->m_rightop = CBotTwoOpExpr::Compile(p, pStk, pOp, bConstExpr)) ) // expression (...) right { // there is an second operand acceptable @@ -264,7 +263,7 @@ CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOpera type1 = TypeRes; p = p->GetNext(); // advance after - i->m_rightop = CBotTwoOpExpr::Compile( p, pStk, pOp ); + i->m_rightop = CBotTwoOpExpr::Compile(p, pStk, pOp, bConstExpr); type2 = pStk->GetTypResult(); if ( !TypeCompatible (type1, type2, typeOp) ) // the results are compatible diff --git a/src/CBot/CBotInstr/CBotTwoOpExpr.h b/src/CBot/CBotInstr/CBotTwoOpExpr.h index c1110e13..baf70a14 100644 --- a/src/CBot/CBotInstr/CBotTwoOpExpr.h +++ b/src/CBot/CBotInstr/CBotTwoOpExpr.h @@ -65,7 +65,7 @@ public: * \param pOperations * \return */ - static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, int* pOperations = nullptr); + static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, int* pOperations = nullptr, bool bConstExpr = false); /*! * \brief Execute Performes the operation on two operands. diff --git a/src/common/restext.cpp b/src/common/restext.cpp index 065f6c92..a79f3f55 100644 --- a/src/common/restext.cpp +++ b/src/common/restext.cpp @@ -743,6 +743,7 @@ void InitializeRestext() stringsCbot[CBot::CBotErrHexRange] = TR("Hex value out of range"); stringsCbot[CBot::CBotErrUnicodeName] = TR("Invalid universal character name"); stringsCbot[CBot::CBotErrCharEmpty] = TR("Empty character constant"); + stringsCbot[CBot::CBotErrRedefCase] = TR("Duplicate label in switch"); stringsCbot[CBot::CBotErrZeroDiv] = TR("Dividing by zero"); stringsCbot[CBot::CBotErrNotInit] = TR("Variable not initialized"); diff --git a/test/unit/CBot/CBot_test.cpp b/test/unit/CBot/CBot_test.cpp index 4c60b8fa..78009ffc 100644 --- a/test/unit/CBot/CBot_test.cpp +++ b/test/unit/CBot/CBot_test.cpp @@ -640,6 +640,92 @@ TEST_F(CBotUT, BinaryLiterals) ); } +TEST_F(CBotUT, TestSwitchCase) +{ + ExecuteTest( + "extern void Test_Switch_Case() {\n" + " int n = 0, c = 0;\n" + " for (int i = -9; i < 11; ++i) {\n" + " switch (i) {\n" + " case -9: n = -9; ++c; break;\n" + " case -8: n = -8; ++c; break;\n" + " case -7: n = -7; ++c; break;\n" + " case -6: n = -6; ++c; break;\n" + " case -5: n = -5; ++c; break;\n" + " case -4: n = -4; ++c; break;\n" + " case -3: n = -3; ++c; break;\n" + " case -2: n = -2; ++c; break;\n" + " case -1: n = -1; ++c; break;\n" + " case 0: n = 0; ++c; break;\n" + " case 1: n = 1; ++c; break;\n" + " case 2: n = 2; ++c; break;\n" + " case 3: n = 3; ++c; break;\n" + " case 4: n = 4; ++c; break;\n" + " case 5: n = 5; ++c; break;\n" + " case 6: n = 6; ++c; break;\n" + " case 7: n = 7; ++c; break;\n" + " case 8: n = 8; ++c; break;\n" + " case 9: n = 9; ++c; break;\n" + " default: n = 10; ++c; break;\n" + " }\n" + " ASSERT(n == i);\n" + " }\n" + " ASSERT(n == 10);\n" + " ASSERT(c == 20);\n" + "}\n" + "extern void Test_Case_With_Math() {\n" + " int n = 0, c = 0;\n" + " for (int i = -9; i < 11; ++i) {\n" + " switch (i * 10) {\n" + " case -9*10: n = -90; ++c; break;\n" + " case -8*10: n = -80; ++c; break;\n" + " case -7*10: n = -70; ++c; break;\n" + " case -6*10: n = -60; ++c; break;\n" + " case -5*10: n = -50; ++c; break;\n" + " case -4*10: n = -40; ++c; break;\n" + " case -3*10: n = -30; ++c; break;\n" + " case -2*10: n = -20; ++c; break;\n" + " case -1*10: n = -10; ++c; break;\n" + " case 0*10: n = 0; ++c; break;\n" + " case 1*10: n = 10; ++c; break;\n" + " case 2*10: n = 20; ++c; break;\n" + " case 3*10: n = 30; ++c; break;\n" + " case 4*10: n = 40; ++c; break;\n" + " case 5*10: n = 50; ++c; break;\n" + " case 6*10: n = 60; ++c; break;\n" + " case 7*10: n = 70; ++c; break;\n" + " case 8*10: n = 80; ++c; break;\n" + " case 9*10: n = 90; ++c; break;\n" + " default: n = 100; ++c; break;\n" + " }\n" + " ASSERT(n == i * 10);\n" + " }\n" + " ASSERT(n == 100);\n" + " ASSERT(c == 20);\n" + "}\n" + ); + + ExecuteTest( + "extern void Duplicate_Case() {\n" + " switch(0) {\n" + " case 1000:\n" + " case 10*100:\n" + " }\n" + "}\n", + CBotErrRedefCase + ); + + ExecuteTest( + "extern void Duplicate_Default() {\n" + " switch(0) {\n" + " default:\n" + " default:\n" + " }\n" + "}\n", + CBotErrRedefCase + ); +} + TEST_F(CBotUT, ToString) { ExecuteTest( From 17d0d2abb14d7ec9a73e0b15b30d60f2a2f9838d Mon Sep 17 00:00:00 2001 From: melex750 Date: Sun, 12 May 2019 08:33:53 -0400 Subject: [PATCH 100/109] Fix compiling literal numbers --- src/CBot/CBotInstr/CBotExprLitNum.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/CBot/CBotInstr/CBotExprLitNum.cpp b/src/CBot/CBotInstr/CBotExprLitNum.cpp index 61978bf0..0e0f8f88 100644 --- a/src/CBot/CBotInstr/CBotExprLitNum.cpp +++ b/src/CBot/CBotInstr/CBotExprLitNum.cpp @@ -74,8 +74,7 @@ CBotInstr* CompileExprLitNum(CBotToken* &p, CBotCStack* pStack) if (s.find('.') != std::string::npos || ( s.find('x') == std::string::npos && ( s.find_first_of("eE") != std::string::npos ) )) { double val = GetNumFloat(s); - if (val < static_cast(std::numeric_limits::min()) && - val > static_cast(std::numeric_limits::max()) ) + if (val > static_cast(std::numeric_limits::max())) { numtype = CBotTypDouble; inst = new CBotExprLitNum(val); @@ -89,8 +88,7 @@ CBotInstr* CompileExprLitNum(CBotToken* &p, CBotCStack* pStack) else { long val = GetNumInt(s); - if (val < std::numeric_limits::min() && - val > std::numeric_limits::max() ) + if (val > std::numeric_limits::max()) { numtype = CBotTypLong; inst = new CBotExprLitNum(val); From 17d85eb434835e8544ac8dcecbb86c80ac6542a2 Mon Sep 17 00:00:00 2001 From: B-CE Date: Fri, 8 Mar 2019 12:45:41 +0100 Subject: [PATCH 101/109] Translate french comments + correct typo --- src/CBot/CBotInstr/CBotDefClass.cpp | 2 +- src/CBot/CBotInstr/CBotDo.cpp | 2 +- src/CBot/CBotInstr/CBotFor.cpp | 2 +- src/CBot/CBotInstr/CBotFunction.cpp | 6 +++--- src/CBot/CBotInstr/CBotParExpr.cpp | 2 +- src/CBot/CBotInstr/CBotSwitch.cpp | 4 ++-- src/CBot/CBotInstr/CBotTry.cpp | 12 +++++------- src/CBot/CBotInstr/CBotTwoOpExpr.cpp | 2 +- src/CBot/CBotInstr/CBotWhile.cpp | 3 +-- src/CBot/CBotVar/CBotVar.cpp | 4 ++-- src/CBot/CBotVar/CBotVarArray.cpp | 2 +- src/CBot/CBotVar/CBotVarClass.cpp | 2 +- src/CBot/stdlib/FileFunctions.cpp | 2 +- src/app/main.cpp | 2 +- src/graphics/engine/particle.cpp | 6 +++--- src/object/auto/autoportico.cpp | 4 ++-- src/object/auto/autopowerstation.cpp | 4 +--- src/object/auto/autoresearch.cpp | 2 +- src/object/task/taskmanip.cpp | 2 +- src/object/task/tasktake.cpp | 2 +- src/physics/physics.cpp | 2 +- src/ui/controls/color.cpp | 4 +--- src/ui/controls/interface.cpp | 3 +-- src/ui/studio.cpp | 2 +- 24 files changed, 35 insertions(+), 43 deletions(-) diff --git a/src/CBot/CBotInstr/CBotDefClass.cpp b/src/CBot/CBotInstr/CBotDefClass.cpp index 174b973f..3245ab05 100644 --- a/src/CBot/CBotInstr/CBotDefClass.cpp +++ b/src/CBot/CBotInstr/CBotDefClass.cpp @@ -140,7 +140,7 @@ CBotInstr* CBotDefClass::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* p if (typ == CBotErrUndefCall) { - // si le constructeur n'existe pas + // if the ctor don't exist if (inst->m_parameters != nullptr) // with parameters { pStk->SetError(CBotErrNoConstruct, vartoken); diff --git a/src/CBot/CBotInstr/CBotDo.cpp b/src/CBot/CBotInstr/CBotDo.cpp index caf10920..c5b1debc 100644 --- a/src/CBot/CBotInstr/CBotDo.cpp +++ b/src/CBot/CBotInstr/CBotDo.cpp @@ -57,7 +57,7 @@ CBotInstr* CBotDo::Compile(CBotToken* &p, CBotCStack* pStack) inst->SetToken(p); if (!IsOfType(p, ID_DO)) return nullptr; // should never happen - CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp + CBotCStack* pStk = pStack->TokenStack(pp); // some space for a stack, plz // looking for a statement block after the do diff --git a/src/CBot/CBotInstr/CBotFor.cpp b/src/CBot/CBotInstr/CBotFor.cpp index 92aafa0b..91013e43 100644 --- a/src/CBot/CBotInstr/CBotFor.cpp +++ b/src/CBot/CBotInstr/CBotFor.cpp @@ -67,7 +67,7 @@ CBotInstr* CBotFor::Compile(CBotToken* &p, CBotCStack* pStack) return nullptr; } - CBotCStack* pStk = pStack->TokenStack(pp, true); // un petit bout de pile svp + CBotCStack* pStk = pStack->TokenStack(pp, true); // some size for a stack, plz // compiles instructions for initialization inst->m_init = CBotListExpression::Compile(p, pStk ); diff --git a/src/CBot/CBotInstr/CBotFunction.cpp b/src/CBot/CBotInstr/CBotFunction.cpp index b4473cd8..4916d870 100644 --- a/src/CBot/CBotInstr/CBotFunction.cpp +++ b/src/CBot/CBotInstr/CBotFunction.cpp @@ -169,7 +169,7 @@ CBotFunction* CBotFunction::Compile(CBotToken* &p, CBotCStack* pStack, CBotFunct func->m_token = d; } - // un nom de fonction est-il là ? + // is there a function name here ? if (IsOfType(p, TokenTypVar)) { if ( IsOfType( p, ID_DBLDOTS ) ) // method for a class @@ -284,7 +284,7 @@ CBotFunction* CBotFunction::Compile1(CBotToken* &p, CBotCStack* pStack, CBotClas func->m_token = d; } - // un nom de fonction est-il là ? + // is there a function name here ? if (IsOfType(p, TokenTypVar)) { if ( IsOfType( p, ID_DBLDOTS ) ) // method for a class @@ -584,7 +584,7 @@ CBotFunction* CBotFunction::FindLocalOrPublic(const std::list& lo { int i = 0; int alpha = 0; // signature of parameters - // parameters sont-ils compatibles ? + // are parameters compatible ? CBotDefParam* pv = pt->m_param; // list of expected parameters CBotVar* pw = ppVars[i++]; // list of provided parameters while ( pv != nullptr && (pw != nullptr || pv->HasDefault()) ) diff --git a/src/CBot/CBotInstr/CBotParExpr.cpp b/src/CBot/CBotInstr/CBotParExpr.cpp index b879ebec..1df0e83c 100644 --- a/src/CBot/CBotInstr/CBotParExpr.cpp +++ b/src/CBot/CBotInstr/CBotParExpr.cpp @@ -83,7 +83,7 @@ CBotInstr* CBotParExpr::Compile(CBotToken* &p, CBotCStack* pStack) CBotToken* pvar = p; - // no, it an "ordinaty" variable + // no, it's an "ordinaty" variable inst = CBotExprVar::Compile(p, pStk); CBotToken* pp = p; diff --git a/src/CBot/CBotInstr/CBotSwitch.cpp b/src/CBot/CBotInstr/CBotSwitch.cpp index e8d1b24d..740e5d8a 100644 --- a/src/CBot/CBotInstr/CBotSwitch.cpp +++ b/src/CBot/CBotInstr/CBotSwitch.cpp @@ -51,7 +51,7 @@ CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack) inst->SetToken(p); if (!IsOfType(p, ID_SWITCH)) return nullptr; // should never happen - CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp + CBotCStack* pStk = pStack->TokenStack(pp); // some space for a stack, plz if ( IsOfType(p, ID_OPENPAR ) ) { @@ -69,7 +69,7 @@ CBotInstr* CBotSwitch::Compile(CBotToken* &p, CBotCStack* pStack) { if ( p->GetType() == ID_CASE || p->GetType() == ID_DEFAULT) { - CBotCStack* pStk2 = pStk->TokenStack(p); // un petit bout de pile svp + CBotCStack* pStk2 = pStk->TokenStack(p); // some space for a stack, plz CBotInstr* i = CBotCase::Compile( p, pStk2 ); if (i == nullptr) diff --git a/src/CBot/CBotInstr/CBotTry.cpp b/src/CBot/CBotInstr/CBotTry.cpp index 1a881c99..ed099033 100644 --- a/src/CBot/CBotInstr/CBotTry.cpp +++ b/src/CBot/CBotInstr/CBotTry.cpp @@ -52,7 +52,7 @@ CBotInstr* CBotTry::Compile(CBotToken* &p, CBotCStack* pStack) inst->SetToken(p); if (!IsOfType(p, ID_TRY)) return nullptr; // should never happen - CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp + CBotCStack* pStk = pStack->TokenStack(pp); // some space for a stack, plz inst->m_block = CBotBlock::CompileBlkOrInst(p, pStk ); CBotCatch** pn = &inst->m_catchList; @@ -102,11 +102,11 @@ bool CBotTry::Execute(CBotStack* &pj) val = pile1->GetError(); if ( val == CBotNoErr && pile1->GetTimer() == 0 ) // mode step? - return false; // does not make the catch + return false; // don't jump to the catch pile1->IncState(); pile2->SetState(val); // stores the error number - pile1->SetError(CBotNoErr); // for now there is are more errors! + pile1->SetError(CBotNoErr); // for now there are more errors! if ( val == CBotNoErr && pile1->GetTimer() < 0 ) // mode step? return false; // does not make the catch @@ -124,8 +124,7 @@ bool CBotTry::Execute(CBotStack* &pj) { if ( --state <= 0 ) { - // request to the catch block if they feel concerned - // demande au bloc catch s'il se sent concerné + // ask to the catch block if it feels concerned if ( !pc->TestCatch(pile2, val) ) return false; // suspend ! pile1->IncState(); } @@ -200,8 +199,7 @@ void CBotTry::RestoreState(CBotStack* &pj, bool bMain) { if ( --state <= 0 ) { - // request to the catch block if they feel concerned - // demande au bloc catch s'il se sent concerné + // ask to the catch block if it feels concerned pc->RestoreCondState(pile2, bMain); // suspend ! return; } diff --git a/src/CBot/CBotInstr/CBotTwoOpExpr.cpp b/src/CBot/CBotInstr/CBotTwoOpExpr.cpp index 3d5fc6a4..9a25a1e1 100644 --- a/src/CBot/CBotInstr/CBotTwoOpExpr.cpp +++ b/src/CBot/CBotInstr/CBotTwoOpExpr.cpp @@ -359,7 +359,7 @@ bool CBotTwoOpExpr::Execute(CBotStack* &pStack) CBotStack* pStk2 = pStk1->AddStack(); // adds an item to the stack // or return in case of recovery - // 2e état, évalue l'opérande de droite + // 2nd state, evalute right operand if ( pStk2->GetState() == 0 ) { if ( !m_rightop->Execute(pStk2) ) return false; // interrupted here? diff --git a/src/CBot/CBotInstr/CBotWhile.cpp b/src/CBot/CBotInstr/CBotWhile.cpp index 9254ad02..8f55aa1c 100644 --- a/src/CBot/CBotInstr/CBotWhile.cpp +++ b/src/CBot/CBotInstr/CBotWhile.cpp @@ -56,8 +56,7 @@ CBotInstr* CBotWhile::Compile(CBotToken* &p, CBotCStack* pStack) inst->SetToken(p); if (!IsOfType(p, ID_WHILE)) return nullptr; // should never happen - CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp - // a bit of battery please (??) + CBotCStack* pStk = pStack->TokenStack(pp); // some space for a stack, plz if ( nullptr != (inst->m_condition = CBotCondition::Compile(p, pStk )) ) { diff --git a/src/CBot/CBotVar/CBotVar.cpp b/src/CBot/CBotVar/CBotVar.cpp index 62ba41f4..f71016a3 100644 --- a/src/CBot/CBotVar/CBotVar.cpp +++ b/src/CBot/CBotVar/CBotVar.cpp @@ -359,7 +359,7 @@ CBotVar::InitType CBotVar::GetInit() const void CBotVar::SetInit(CBotVar::InitType initType) { m_binit = initType; - if (initType == CBotVar::InitType::IS_POINTER ) m_binit = CBotVar::InitType::DEF; // cas spécial + if (initType == CBotVar::InitType::IS_POINTER ) m_binit = CBotVar::InitType::DEF; // special case if ( m_type.Eq(CBotTypPointer) && initType == CBotVar::InitType::IS_POINTER ) { @@ -497,7 +497,7 @@ void CBotVar::SetVal(CBotVar* var) assert(0); } - m_binit = var->m_binit; // copie l'état nan s'il y a + m_binit = var->m_binit; // copy the nan status if it has } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/CBot/CBotVar/CBotVarArray.cpp b/src/CBot/CBotVar/CBotVarArray.cpp index 6462d119..14ca7201 100644 --- a/src/CBot/CBotVar/CBotVarArray.cpp +++ b/src/CBot/CBotVar/CBotVarArray.cpp @@ -94,7 +94,7 @@ void CBotVarArray::SetPointer(CBotVar* pVarClass) !pVarClass->m_type.Eq(CBotTypArrayBody)) assert(0); - (static_cast(pVarClass))->IncrementUse(); // incement the reference + (static_cast(pVarClass))->IncrementUse(); // increment the reference } if ( m_pInstance != nullptr ) m_pInstance->DecrementUse(); diff --git a/src/CBot/CBotVar/CBotVarClass.cpp b/src/CBot/CBotVar/CBotVarClass.cpp index 36952d18..f86d5993 100644 --- a/src/CBot/CBotVar/CBotVarClass.cpp +++ b/src/CBot/CBotVar/CBotVarClass.cpp @@ -53,7 +53,7 @@ CBotVarClass::CBotVarClass(const CBotToken& name, const CBotTypResult& type) : C m_type = type; if ( type.Eq(CBotTypArrayPointer) ) m_type.SetType( CBotTypArrayBody ); else if ( !type.Eq(CBotTypArrayBody) ) m_type.SetType( CBotTypClass ); - // officel type for this object + // official type for this object m_pClass = nullptr; m_pParent = nullptr; diff --git a/src/CBot/stdlib/FileFunctions.cpp b/src/CBot/stdlib/FileFunctions.cpp index b185ac13..381a7b6d 100644 --- a/src/CBot/stdlib/FileFunctions.cpp +++ b/src/CBot/stdlib/FileFunctions.cpp @@ -181,7 +181,7 @@ CBotTypResult cfopen (CBotVar* pThis, CBotVar* &pVar) // process FILE :: close -// execeution +// execution bool rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) { // it shouldn't be any parameters diff --git a/src/app/main.cpp b/src/app/main.cpp index 9fdb89a3..46b0b88f 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -61,7 +61,7 @@ object-oriented language, CBOT, which can be used to program the robots availabl The original version of the game was developed by [Epsitec](http://www.epsitec.ch/) and released in 2001. Later, in 2005 another version named Ceebot was released. In March 2012, through attempts by Polish Colobot fans, Epsitec agreeed to release the source code of the game on GPLv3 license. -The license was given specfifically to our community, TerranovaTeam, +The license was given specifically to our community, TerranovaTeam, part of International Colobot Community (ICC) (previously known as Polish Portal of Colobot (PPC); Polish: Polski Portal Colobota) with our website at http://colobot.info/. diff --git a/src/graphics/engine/particle.cpp b/src/graphics/engine/particle.cpp index 5c6d169f..effbaff5 100644 --- a/src/graphics/engine/particle.cpp +++ b/src/graphics/engine/particle.cpp @@ -877,7 +877,7 @@ void CParticle::FrameParticle(float rTime) m_track[r].drawParticle = (progress < 1.0f); } - if (m_particle[i].type == PARTITRACK1) // explosion technique? + if (m_particle[i].type == PARTITRACK1) // technical explosion? { m_particle[i].zoom = 1.0f-(m_particle[i].time-m_particle[i].duration); @@ -2407,7 +2407,7 @@ void CParticle::FrameParticle(float rTime) ti.y = ts.y+0.125f; } - if (m_particle[i].type == PARTIRAY1) // rayon tour ? + if (m_particle[i].type == PARTIRAY1) // tower ray ? { if (progress >= 1.0f) { @@ -2517,7 +2517,7 @@ void CParticle::TrackDraw(int i, ParticleType type) Math::Point texInf, texSup; - if (type == PARTITRACK1) // explosion technique? + if (type == PARTITRACK1) // technical explosion? { texInf.x = 64.5f/256.0f; texInf.y = 21.0f/256.0f; diff --git a/src/object/auto/autoportico.cpp b/src/object/auto/autoportico.cpp index 2a8bf372..5ef25c78 100644 --- a/src/object/auto/autoportico.cpp +++ b/src/object/auto/autoportico.cpp @@ -47,8 +47,8 @@ const float PORTICO_TIME_OPEN = 12.0f; -// Si progress=0, return a. -// Si progress=1, return b. +// if progress=0, return a. +// if progress=1, return b. static float Progress(float a, float b, float progress) { diff --git a/src/object/auto/autopowerstation.cpp b/src/object/auto/autopowerstation.cpp index 5b90b6fa..667c8324 100644 --- a/src/object/auto/autopowerstation.cpp +++ b/src/object/auto/autopowerstation.cpp @@ -302,9 +302,7 @@ Error CAutoPowerStation::GetError() return ERR_OK; } - -// Crée toute l'interface lorsque l'objet est sélectionné . - +// Create the all interface when the object is selected. bool CAutoPowerStation::CreateInterface(bool bSelect) { Ui::CWindow* pw; diff --git a/src/object/auto/autoresearch.cpp b/src/object/auto/autoresearch.cpp index ccc24c85..a1c98b69 100644 --- a/src/object/auto/autoresearch.cpp +++ b/src/object/auto/autoresearch.cpp @@ -502,7 +502,7 @@ void CAutoResearch::FireStopUpdate(float progress, bool bLightOn) 4.7f, -8.2f, }; - if ( !bLightOn ) // �teint ? + if ( !bLightOn ) // light-off ? { for ( i=0 ; i<6 ; i++ ) { diff --git a/src/object/task/taskmanip.cpp b/src/object/task/taskmanip.cpp index 16615ebd..0f38171c 100644 --- a/src/object/task/taskmanip.cpp +++ b/src/object/task/taskmanip.cpp @@ -259,7 +259,7 @@ void CTaskManip::InitAngle() float energy = GetObjectEnergy(m_object); if ( energy == 0.0f ) { - m_speed *= 0.7f; // slower if more energy! + m_speed *= 0.7f; // slower if no more energy! } } diff --git a/src/object/task/tasktake.cpp b/src/object/task/tasktake.cpp index c67a7e56..e8a27021 100644 --- a/src/object/task/tasktake.cpp +++ b/src/object/task/tasktake.cpp @@ -419,7 +419,7 @@ bool CTaskTake::TransporterTakeObject() //? cargo = SearchTakeObject(angle, 1.5f, Math::PI*0.04f); float angle = 0.0f; CObject* cargo = SearchTakeObject(angle, 1.5f, Math::PI*0.15f); //OK 1.9 - if (cargo == nullptr) return false; // rien � prendre ? + if (cargo == nullptr) return false; // nothing to take ? assert(cargo->Implements(ObjectInterfaceType::Transportable)); m_cargoType = cargo->GetType(); diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index b97742c5..7e30a8e4 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -1196,7 +1196,7 @@ void CPhysics::EffectUpdate(float aTime, float rTime) type == OBJECT_MOBILEfc || type == OBJECT_MOBILEfi || type == OBJECT_MOBILEfs || - type == OBJECT_MOBILEft ) // fliyng? + type == OBJECT_MOBILEft ) // flying? { if ( m_bLand ) // on the ground? { diff --git a/src/ui/controls/color.cpp b/src/ui/controls/color.cpp index faecb435..86a6dd45 100644 --- a/src/ui/controls/color.cpp +++ b/src/ui/controls/color.cpp @@ -121,9 +121,7 @@ bool CColor::EventProcess(const Event &event) return true; } - -// Dessine le bouton. - +// Draw the button. void CColor::Draw() { Gfx::CDevice* device; diff --git a/src/ui/controls/interface.cpp b/src/ui/controls/interface.cpp index 050ce193..cabe38f1 100644 --- a/src/ui/controls/interface.cpp +++ b/src/ui/controls/interface.cpp @@ -194,8 +194,7 @@ CEdit* CInterface::CreateEdit(Math::Point pos, Math::Point dim, int icon, EventT return CreateControl(pos, dim, icon, eventMsg); } -// Creates a new pave editable. - +// Creates a new editable area. CEditValue* CInterface::CreateEditValue(Math::Point pos, Math::Point dim, int icon, EventType eventMsg) { CEditValue* ev = CreateControl(pos, dim, icon, eventMsg); diff --git a/src/ui/studio.cpp b/src/ui/studio.cpp index 3602aeac..a7fc690d 100644 --- a/src/ui/studio.cpp +++ b/src/ui/studio.cpp @@ -133,7 +133,7 @@ bool CStudio::EventProcess(const Event &event) m_event->AddEvent(Event(EVENT_STUDIO_OK)); } - if ( event.type == EVENT_STUDIO_EDIT ) // text modifief? + if ( event.type == EVENT_STUDIO_EDIT ) // text modified? { ColorizeScript(edit); } From 0517115557084619873c873fe5bf9d34ffe7e6c3 Mon Sep 17 00:00:00 2001 From: B-CE Date: Wed, 15 May 2019 00:40:55 +0200 Subject: [PATCH 102/109] Upd i18n fr : complete + uniformize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bots Déménageur -> Préhenseur shooter -> tireur phazer -> hachoir ... Buildings Fabrique de robots -> Usine de robots convertisseur -> raffinerie borne d'information -> station relais ... Objects batterie (standard) pile nucléaire ... --- desktop/po/fr.po | 42 +++++++-------- po/fr.po | 136 +++++++++++++++++++++++------------------------ 2 files changed, 88 insertions(+), 90 deletions(-) diff --git a/desktop/po/fr.po b/desktop/po/fr.po index 1da026a4..784113ba 100644 --- a/desktop/po/fr.po +++ b/desktop/po/fr.po @@ -3,18 +3,20 @@ # This file is distributed under the same license as the Colobot package. # # Didier Raboud , 2012, 2016. +# B-CE <.>, 2019. msgid "" msgstr "" -"Project-Id-Version: colobot 0.1.7\n" +"Project-Id-Version: colobot 0.1.12\n" "POT-Creation-Date: 2016-03-30 13:45+0200\n" -"PO-Revision-Date: 2016-03-30 13:49+0100\n" -"Last-Translator: Didier Raboud \n" +"PO-Revision-Date: 2019-06-01 09:43+0200\n" +"Last-Translator: BCE <.>\n" +"Language-Team: French \n" "Language: fr\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" -"X-Generator: Lokalize 2.0\n" +"X-Generator: Lokalize 18.12.3\n" #. type: Name= #: colobot.ini:1 @@ -32,13 +34,13 @@ msgstr "Apprentissage de la programmation par le jeu" #: colobot.ini:3 #, no-wrap msgid "Colonize with bots" -msgstr "Colonise avec des roBots" +msgstr "COlonise avec des roBOTs" #. type: Keywords= #: colobot.ini:4 #, no-wrap msgid "robots;3d;space;astronaut;java;c++;" -msgstr "robots;3d;espace;astronaute;cosmonaute;java;c++;" +msgstr "robots;3d;espace;astronaute;cosmonaute;java;c++;programmation;jeux" #. type: =head1 #: colobot.pod:3 @@ -74,12 +76,12 @@ msgid "" "real-time graphics and a C++ and Java-like, object-oriented language, CBOT, " "which can be used to program the robots available in the game." msgstr "" -"Colobot (Colonise avec des roBots) est un jeu éducatif visant à " -"l'enseignement de la programmation par le jeu. Vous jouez un astronaute en " +"Colobot (Colonise avec des roBots) est un jeu éducatif visant " +"à l'enseignement de la programmation par le jeu. Vous jouez un astronaute en " "voyage avec des robots à la recherche d'une planète à coloniser. Son " -"interface est en trois-dimensions et en temps réel; le language utilisé " -"(CBOT) ressemble au C++ et à Java et peut être utilisé pour programmer les " -"robots disponibles dans le jeu." +"interface est en trois-dimensions et en temps réel. Le langage utilisé " +"(CBOT), orienté objet , ressemble au C++ et à Java. Il peut être utilisé " +"pour programmer les robots disponibles dans le jeu." #. type: =head1 #: colobot.pod:19 @@ -208,9 +210,9 @@ msgid "" "Enable debug mode (more info printed in logs). Possible values are as " "follows, as well as any comma-separated combination" msgstr "" -"Active le mode de I (plus d'informations dans les logs). Les valeurs" -" possibles sont les suivantes, ainsi que toute combinaison séparée par des" -" virgules" +"Active le mode de I (plus d'informations dans les logs). " +"Les valeurs possibles sont les suivantes, " +"ainsi que toute combinaison séparée par des virgules" #. type: =item #: colobot.pod:81 @@ -260,7 +262,7 @@ msgstr "models" #. type: textblock #: colobot.pod:99 msgid "Models-related debugging" -msgstr "Debug pour les modèles" +msgstr "Débug pour les modèles" #. type: =item #: colobot.pod:101 @@ -270,7 +272,7 @@ msgstr "all" #. type: textblock #: colobot.pod:103 msgid "All above debugging statements" -msgstr "Tout les messages de debug ci-dessus" +msgstr "Tous les messages de debug ci-dessus" #. type: =item #: colobot.pod:107 @@ -280,9 +282,7 @@ msgstr "B<-headless>" #. type: textblock #: colobot.pod:109 msgid "Run in headless mode - disables graphics, sound and user interaction" -msgstr "" -"Lance en mode I - désactive les graphiques, sons et interactions" -" utilisateurs" +msgstr "Lance en mode I - désactive les graphiques, sons et interactions utilisateurs" #. type: =item #: colobot.pod:111 @@ -292,7 +292,7 @@ msgstr "B<-runscene> I" #. type: textblock #: colobot.pod:113 msgid "Run given scene on start (skip menus)" -msgstr "Lance une scène donnée au lancement (saute les menus)" +msgstr "Démarre directement une scène (saute les menus)" #. type: =item #: colobot.pod:115 @@ -317,7 +317,7 @@ msgstr "LC_MESSAGES" #. type: textblock #: colobot.pod:127 msgid "Used to determine the runtime language." -msgstr "Utilisé pour déterminer la langue au lancement" +msgstr "Utilisé pour déterminer la langue au lancement." #. type: =head1 #: colobot.pod:131 diff --git a/po/fr.po b/po/fr.po index c8d48217..707b147c 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1,21 +1,21 @@ # Didier Raboud , 2012, 2015, 2016. -# Martin Quinson , 2016 -# B-CE, 2018 -# Pascal Audoux , 2018 +# Martin Quinson , 2016. +# B-CE <.>, 2018, 2019. +# Pascal Audoux , 2018. msgid "" msgstr "" -"Project-Id-Version: Colobot 0.1.11\n" +"Project-Id-Version: Colobot 0.1.12\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: DATE\n" -"PO-Revision-Date: 2019-01-09 23:07+0100\n" -"Last-Translator: B-CE\n" -"Language-Team: \n" +"PO-Revision-Date: 2019-06-13 01:31+0200\n" +"Last-Translator: BCE <.>\n" +"Language-Team: French <>\n" "Language: fr\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" -"X-Generator: Poedit 2.0.6\n" +"X-Generator: Lokalize 18.12.3\n" "X-Language: fr_FR\n" "X-Source-Language: en_US\n" @@ -39,7 +39,7 @@ msgid "..in front" msgstr "..devant" msgid "..power cell" -msgstr "..pile" +msgstr "..batterie" msgid "1) First click on the key you want to redefine." msgstr "1) Cliquez d'abord sur la touche à redéfinir." @@ -141,10 +141,10 @@ msgid "Automatic indent\\When program editing" msgstr "Indentation automatique\\Pendant l'édition d'un programme" msgid "Autosave interval\\How often your game will autosave" -msgstr "Interval d'auto-sauvegarde\\À quels intervals les parties vont-t-elles êtres sauvegardées automatiquement" +msgstr "Interval auto-sauvegarde\\À quels intervals les parties vont-t-elles êtres sauvegardées automatiquement" msgid "Autosave slots\\How many autosave slots you'll have" -msgstr "Nombre d'auto-sauvegardes\\Combien d'auto-sauvegarde seront conservées" +msgstr "Nb auto-sauvegardes\\Combien d'auto-sauvegarde seront conservées" msgid "Autosave\\Enables autosave" msgstr "Auto-sauvegarde\\Activer l'auto-sauvegarde" @@ -186,13 +186,13 @@ msgid "Bot destroyed" msgstr "Robot détruit" msgid "Bot factory" -msgstr "Fabrique de robots" +msgstr "Usine de robots" msgid "Build a bot factory" -msgstr "Construire une fabrique de robots" +msgstr "Construire une usine de robots" msgid "Build a converter" -msgstr "Construire un convertisseur" +msgstr "Construire une raffinerie" msgid "Build a defense tower" msgstr "Construire une tour" @@ -204,10 +204,10 @@ msgid "Build a destroyer" msgstr "Construire un destructeur" msgid "Build a exchange post" -msgstr "Construire une borne d'information" +msgstr "Construire une station relais" msgid "Build a legged grabber" -msgstr "Fabriquer un déménageur à pattes" +msgstr "Fabriquer un préhenseur à pattes" msgid "Build a legged orga shooter" msgstr "Fabriquer un tireur organique à pattes" @@ -225,10 +225,10 @@ msgid "Build a nuclear power plant" msgstr "Construire une centrale nucléaire" msgid "Build a phazer shooter" -msgstr "Fabriquer un robot canon à phases" +msgstr "Fabriquer un robot canon hachoir" msgid "Build a power cell factory" -msgstr "Construire une fabrique de piles" +msgstr "Construire une fabrique de batteries" msgid "Build a power station" msgstr "Construire une station de recharge" @@ -255,7 +255,7 @@ msgid "Build a thumper" msgstr "Fabriquer un robot secoueur" msgid "Build a tracked grabber" -msgstr "Fabriquer un déménageur à chenilles" +msgstr "Fabriquer un préhenseur à chenilles" msgid "Build a tracked orga shooter" msgstr "Fabriquer un tireur organique à chenilles" @@ -267,7 +267,7 @@ msgid "Build a tracked sniffer" msgstr "Fabriquer un renifleur à chenilles" msgid "Build a wheeled grabber" -msgstr "Fabriquer un déménageur à roues" +msgstr "Fabriquer un préhenseur à roues" msgid "Build a wheeled orga shooter" msgstr "Fabriquer un tireur organique à roues" @@ -279,7 +279,7 @@ msgid "Build a wheeled sniffer" msgstr "Fabriquer un renifleur à roues" msgid "Build a winged grabber" -msgstr "Fabriquer un déménageur volant" +msgstr "Fabriquer un préhenseur volant" msgid "Build a winged orga shooter" msgstr "Fabriquer un tireur organique volant" @@ -315,19 +315,19 @@ msgid "Camera border scrolling\\Scrolling when the mouse touches right or left b msgstr "Défilement dans les bords\\Défilement lorsque la souris touche les bords gauche ou droite" msgid "Camera closer\\Moves the camera forward" -msgstr "Caméra plus proche\\Avance la caméra" +msgstr "Plus proche\\Avance la caméra" msgid "Camera down\\Turns the camera down" -msgstr "Baisser caméra\\Baisse la caméra" +msgstr "Plus bas\\Tourne la caméra vers le bas" msgid "Camera left\\Turns the camera left" -msgstr "Caméra à gauche\\Tourne la caméra vers la gauche" +msgstr "À gauche\\Tourne la caméra vers la gauche" msgid "Camera right\\Turns the camera right" -msgstr "Caméra à droite\\Tourne la caméra vers la droite" +msgstr "À droite\\Tourne la caméra vers la droite" msgid "Camera up\\Turns the camera up" -msgstr "Lever caméra\\Monte la caméra" +msgstr "Plus haut\\Tourne la caméra vers le haut" msgid "Can not produce not researched object" msgstr "Impossible de créer un objet n'ayant pas été recherché" @@ -366,7 +366,7 @@ msgid "Cheat console\\Show cheat console" msgstr "Console de triche\\Montre la console de triche" msgid "Checkpoint" -msgstr "Indicateur" +msgstr "Point de passage" msgid "Class name expected" msgstr "Nom de classe attendu" @@ -420,7 +420,7 @@ msgid "Controls\\Keyboard, joystick and mouse settings" msgstr "Commandes\\Touches du clavier" msgid "Converts ore to titanium" -msgstr "Conversion de minerai en titane" +msgstr "Raffinage de minerai en titane" msgid "Copy" msgstr "Copier" @@ -514,7 +514,7 @@ msgid "End of block missing" msgstr "Il manque la fin du bloc" msgid "Energy deposit (site for power station)" -msgstr "Emplacement pour une station de recharge ou une fabrique de pile" +msgstr "Sous sol énergétique (Emplacement pour une station de recharge ou une fabrique de batteries)" msgid "Energy level" msgstr "Niveau d'énergie" @@ -569,7 +569,7 @@ msgstr "But/Objectif" # OBJECT_END : GoalArea msgid "Fixed mine" -msgstr "Mine fixe" +msgstr "Mine anti-personnel" msgid "Flat ground not large enough" msgstr "Sol plat pas assez grand" @@ -600,7 +600,7 @@ msgid "Found a site for a derrick" msgstr "Emplacement pour un derrick trouvé" msgid "Found a site for power station" -msgstr "Emplacement pour station de recharge ou fabrique de pile trouvé" +msgstr "Emplacement pour station de recharge ou fabrique de batteries trouvé" msgid "Found key A (site for derrick)" msgstr "Emplacement pour un derrick (clé A)" @@ -720,7 +720,7 @@ msgid "Inappropriate bot" msgstr "Robot inadapté" msgid "Inappropriate cell type" -msgstr "Pas le bon type de pile" +msgstr "Source d'énergie non adapté" msgid "Inappropriate object" msgstr "Pas le bon objet" @@ -732,7 +732,7 @@ msgid "Infected by a virus; temporarily out of order" msgstr "Infecté par un virus; ne fonctionne plus temporairement" msgid "Information exchange post" -msgstr "Borne d'information" +msgstr "Station relais" msgid "Instruction \"break\" outside a loop" msgstr "Instruction \"break\" en dehors d'une boucle" @@ -795,7 +795,7 @@ msgid "LOADING" msgstr "CHARGEMENT" msgid "Legged grabber" -msgstr "Robot déménageur à pattes" +msgstr "Robot préhenseur à pattes" msgid "Legged orga shooter" msgstr "Robot tireur organique à pattes" @@ -866,7 +866,7 @@ msgid "Lunar Roving Vehicle" msgstr "Véhicule d'exploration lunaire" msgid "MSAA\\Multisample anti-aliasing" -msgstr "ACME\\Anticrénelage multiéchantillon" +msgstr "ACME\\Anticrénelage multiéchantillon (MSAA: Multisample anti-aliasing)" msgid "Maximize" msgstr "Taille maximale" @@ -953,7 +953,7 @@ msgid "No function with this name accepts this number of parameters" msgstr "Aucune fonction de ce nom n'accepte ce nombre de paramètres" msgid "No information exchange post within range" -msgstr "Pas de borne d'information accessible" +msgstr "Pas de station relais accessible" msgid "No more energy" msgstr "Plus d'énergie" @@ -962,7 +962,7 @@ msgid "No ore in the subsoil" msgstr "Pas de minerai en sous-sol" msgid "No power cell" -msgstr "Pas de pile" +msgstr "Pas de source d'énergie" msgid "No titanium" msgstr "Pas de titane" @@ -971,7 +971,7 @@ msgid "No titanium around" msgstr "Pas de titane accessible" msgid "No titanium ore to convert" -msgstr "Pas de minerai de titane à convertir" +msgstr "Pas de minerai de titane à raffiner" msgid "No titanium to transform" msgstr "Pas de titane à transformer" @@ -1016,10 +1016,10 @@ msgid "Nothing to recycle" msgstr "Rien à recycler" msgid "Nuclear power cell" -msgstr "Pile nucléaire" +msgstr "Pile atomique" msgid "Nuclear power cell available" -msgstr "Pile nucléaire disponible" +msgstr "Pile atomique disponible" msgid "Nuclear power station" msgstr "Centrale nucléaire" @@ -1040,7 +1040,7 @@ msgid "OK\\Choose the selected player" msgstr "D'accord\\Choisir le joueur" msgid "OK\\Close program editor and return to game" -msgstr "D'accord\\Compiler le programme" +msgstr "D'accord\\Compiler le programme et fermer la fenêtre d'édition" msgid "Object too close" msgstr "Objet trop proche" @@ -1103,7 +1103,7 @@ msgid "Pause\\Pause the game without opening menu" msgstr "Pause\\Mettre le jeu en pause sans ouvrir le menu" msgid "Phazer shooter" -msgstr "Robot canon à phases" +msgstr "Robot canon hachoir" msgid "Photography" msgstr "Vue de la mission" @@ -1121,7 +1121,7 @@ msgid "Plans for nuclear power plant available" msgstr "Construction d'une centrale nucléaire possible" msgid "Plans for phazer shooter available" -msgstr "Fabrication des robots canon à phases possible" +msgstr "Fabrication des robots canon hachoir possible" msgid "Plans for shielder available" msgstr "Fabrication d'un robot bouclier possible" @@ -1151,13 +1151,13 @@ msgid "Player's name" msgstr "Nom du joueur" msgid "Power cell" -msgstr "Pile normale" +msgstr "Batterie standard" msgid "Power cell available" -msgstr "Pile disponible" +msgstr "Batterie disponible" msgid "Power cell factory" -msgstr "Fabrique de piles" +msgstr "Fabrique de batteries" msgid "Power station" msgstr "Station de recharge" @@ -1235,7 +1235,7 @@ msgid "Quit\\Quit Colobot: Gold Edition" msgstr "Quitter\\Quitter Colobot : Édition Gold" msgid "Quit\\Quit the current mission or exercise" -msgstr "Quitter la mission en cours\\Terminer un exercice ou une mssion" +msgstr "Quitter la mission en cours\\Terminer un exercice ou une mission" msgid "Radar station" msgstr "Radar" @@ -1320,34 +1320,34 @@ msgid "Ruin" msgstr "Bâtiment en ruine" msgid "Run research program for defense tower" -msgstr "Recherche la tour de défense" +msgstr "Lancer la recherche de la tour de défense" msgid "Run research program for legged bots" -msgstr "Recherche du fonctionnement des pattes" +msgstr "Lancer la recherche du fonctionnement des pattes" msgid "Run research program for nuclear power" -msgstr "Recherche du programme nucléaire" +msgstr "Lancer la recherche du programme nucléaire" msgid "Run research program for orga shooter" -msgstr "Recherche le canon organique" +msgstr "Lancer la recherche du canon organique" msgid "Run research program for phazer shooter" -msgstr "Recherche le canon à phases" +msgstr "Lancer la recherche du canon hachoir" msgid "Run research program for shielder" -msgstr "Recherche le bouclier" +msgstr "Lancer la recherche du bouclier" msgid "Run research program for shooter" -msgstr "Recherche le canon de tir" +msgstr "Lancer la recherche du canon de tir" msgid "Run research program for thumper" -msgstr "Recherche le secoueur" +msgstr "Lancer la recherche du secoueur" msgid "Run research program for tracked bots" -msgstr "Recherche du fonctionnement des chenilles" +msgstr "Lancer la recherche du fonctionnement des chenilles" msgid "Run research program for winged bots" -msgstr "Recherche du fonctionnement du jet" +msgstr "Lancer la recherche du fonctionnement du jet" msgid "SatCom" msgstr "SatCom" @@ -1440,7 +1440,7 @@ msgid "Spaceship" msgstr "Vaisseau spatial" msgid "Spaceship ruin" -msgstr "Epave de vaisseau spatial" +msgstr "Épave de vaisseau spatial" msgid "Spider" msgstr "Araignée" @@ -1497,7 +1497,7 @@ msgid "Switch bots <-> buildings" msgstr "Permute robots <-> bâtiments" msgid "Take off to finish the mission" -msgstr "Décolle pour terminer la mission" +msgstr "Décollage pour terminer la mission" msgid "Target" msgstr "Cible" @@ -1560,7 +1560,7 @@ msgid "This program is read-only, clone it to edit" msgstr "Ce programme est en lecture-seule, le dupliquer pour pouvoir le modifier" msgid "Thump (\\key action;)" -msgstr "Secoue (\\key action;)" +msgstr "Secouer (\\key action;)" msgid "Thumper" msgstr "Robot secoueur" @@ -1603,7 +1603,7 @@ msgid "Too many parameters" msgstr "Trop de paramètres" msgid "Tracked grabber" -msgstr "Robot déménageur à chenilles" +msgstr "Robot préhenseur à chenilles" msgid "Tracked orga shooter" msgstr "Robot tireur organique à chenilles" @@ -1684,7 +1684,7 @@ msgid "Vault" msgstr "Coffre-fort" msgid "Vertical Synchronization\\Limits the number of frames per second to display frequency" -msgstr "" +msgstr "Synchronisation verticale :\\Réduit la fréquence d'images par seconde à afficher." msgid "Violet flag" msgstr "Drapeau violet" @@ -1702,7 +1702,7 @@ msgid "Waste" msgstr "Déchet" msgid "Wheeled grabber" -msgstr "Robot déménageur à roues" +msgstr "Robot préhenseur à roues" msgid "Wheeled orga shooter" msgstr "Robot tireur organique à roues" @@ -1714,7 +1714,7 @@ msgid "Wheeled sniffer" msgstr "Robot renifleur à roues" msgid "Winged grabber" -msgstr "Robot déménageur volant" +msgstr "Robot préhenseur volant" msgid "Winged orga shooter" msgstr "Robot tireur organique volant" @@ -1735,7 +1735,7 @@ msgid "Worm fatally wounded" msgstr "Ver mortellement touché" msgid "Wreckage" -msgstr "Epave de robot" +msgstr "Épave de robot" msgid "Write error" msgstr "Erreur lors de l'écriture" @@ -1820,7 +1820,7 @@ msgid "\\New player name" msgstr "\\Nom du joueur à créer" msgid "\\No eyeglasses" -msgstr "\\Pas de lunettes" +msgstr "\\Pas de lunette" msgid "\\Raise the pencil" msgstr "\\Relève le crayon" @@ -1882,9 +1882,6 @@ msgstr "colobot.info" msgid "epsitec.com" msgstr "epsitec.com" -#~ msgid " " -#~ msgstr " " - #~ msgid " Drivers:" #~ msgstr " Pilotes :" @@ -2052,3 +2049,4 @@ msgstr "epsitec.com" #~ msgid "\\c; (none)\\n;\n" #~ msgstr "\\c; (aucun)\\n;\n" + From 4f9d9d0609a11dbf706a7a1b95c20ab4925ffcef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Tue, 24 Sep 2019 16:30:50 +0200 Subject: [PATCH 103/109] Fix manpage build rules to work with Ninja generator Specify outputs for po4a command explicitly rather than via implicit target, in order to clearly establish the dependency chain between manpages and input files generated by po4a. This is necessary to make it possible to use Ninja generator. Otherwise, the implicit dependencies cause the following error: ninja: error: '../desktop/lang/fr/colobot.pod', needed by 'desktop/fr/colobot.6', missing and no known rule to make it --- desktop/CMakeLists.txt | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/desktop/CMakeLists.txt b/desktop/CMakeLists.txt index af704932..2ee308cc 100644 --- a/desktop/CMakeLists.txt +++ b/desktop/CMakeLists.txt @@ -82,20 +82,6 @@ if(PLATFORM_GNU) DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps/ ) - # Translate translatable material - find_program(PO4A po4a) - if(NOT PO4A) - message(WARNING "po4a not found; desktop and manpage files will not be translated") - endif() - - if(PO4A) - add_custom_target(desktop_po4a - COMMAND ${PO4A} po4a.cfg - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - ) - add_dependencies(desktopfile desktop_po4a) - endif() - # Create manpage from pod-formatted file find_program(POD2MAN pod2man) if(NOT POD2MAN) @@ -133,11 +119,30 @@ if(PLATFORM_GNU) # Create the english manpage podman(PODFILE colobot.pod) + # Translate translatable material + find_program(PO4A po4a) + if(NOT PO4A) + message(WARNING "po4a not found; desktop and manpage files will not be translated") + endif() + if(PO4A) # Translate the manpage to other languages - add_dependencies(man desktop_po4a) file(GLOB LINGUAS_PO RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/po/ ${CMAKE_CURRENT_SOURCE_DIR}/po/*.po) string(REGEX REPLACE ".po$" "" LINGUAS ${LINGUAS_PO}) + + set(PO4A_OUTPUTS) + foreach(LOCALE ${LINGUAS}) + list(APPEND PO4A_OUTPUTS ${CMAKE_CURRENT_SOURCE_DIR}/lang/${LOCALE}/colobot.pod) + endforeach() + add_custom_command( + OUTPUT ${PO4A_OUTPUTS} + COMMAND ${PO4A} po4a.cfg + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) + add_custom_target(desktop_po4a DEPENDS ${PO4A_OUTPUTS}) + add_dependencies(man desktop_po4a) + add_dependencies(desktopfile desktop_po4a) + foreach(LOCALE ${LINGUAS}) podman(PODFILE lang/${LOCALE}/colobot.pod LOCALE ${LOCALE}) add_dependencies(man${PM_LOCALE} desktop_po4a) From 68ddaf550b16007487e35f7ee774f38f5c53cb06 Mon Sep 17 00:00:00 2001 From: suve Date: Mon, 7 Oct 2019 14:39:51 +0200 Subject: [PATCH 104/109] Add some missing strings to the Polish translation --- po/pl.po | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/po/pl.po b/po/pl.po index 073c7b58..964a4299 100644 --- a/po/pl.po +++ b/po/pl.po @@ -365,7 +365,7 @@ msgid "Checkpoint" msgstr "Punkt kontrolny" msgid "Class name expected" -msgstr "" +msgstr "Oczekiwano nazwy klasy" msgid "Climb\\Increases the power of the jet" msgstr "W górę\\Zwiększa moc silnika" @@ -628,7 +628,7 @@ msgid "Function name missing" msgstr "Brakująca nazwa funkcji" msgid "Function needs return type \"void\"" -msgstr "" +msgstr "Funkcja potrzebuje typu zwracanego \"void\"" msgid "Game speed" msgstr "Prędkość gry" @@ -679,7 +679,7 @@ msgid "Help balloons\\Explain the function of the buttons" msgstr "Dymki pomocy\\Wyjaśnia funkcje przycisków" msgid "Hex value out of range" -msgstr "" +msgstr "Wartość heksadecymalna poza zakresem" msgid "Higher speed\\Doubles speed" msgstr "Zwiększ prędkość\\Podwaja prędkość" @@ -859,10 +859,10 @@ msgid "Mipmap level\\Mipmap level" msgstr "Poziom mipmap\\Poziom mipmap" msgid "Missing end quote" -msgstr "" +msgstr "Brak cudzysłowu zamykającego" msgid "Missing hex digits after escape sequence" -msgstr "" +msgstr "Brak cyfr heksadecymalnych po znaku ucieczki" msgid "Mission name" msgstr "Nazwa misji" @@ -964,7 +964,7 @@ msgid "No userlevels installed!" msgstr "Brak zainstalowanych poziomów użytkownika!" msgid "Non-void function needs \"return;\"" -msgstr "" +msgstr "Funkcja zwracająca typ inny, niż \"void\", wymaga \"return;\"" msgid "Normal size" msgstr "Normalna wielkość" @@ -1027,7 +1027,7 @@ msgid "Object too close" msgstr "Obiekt za blisko" msgid "Octal value out of range" -msgstr "" +msgstr "Wartość ósemkowa poza zakresem" msgid "One step" msgstr "Jeden krok" @@ -1072,7 +1072,7 @@ msgid "Paste (Ctrl+V)" msgstr "Wklej (Ctrl+V)" msgid "Pause blur\\Blur the background on the pause screen" -msgstr "" +msgstr "Rozmyta pauza\\Rozmyj tło na ekranie pauzy" msgid "Pause in background\\Pause the game when the window is unfocused" msgstr "Wstrzymaj w tle\\Wstrzymaj grę gdy okno stanie się nieaktywne" @@ -1534,7 +1534,7 @@ msgid "This object is not a member of a class" msgstr "Ten obiekt nie jest członkiem klasy" msgid "This parameter needs a default value" -msgstr "" +msgstr "Ten parametr wymaga podania domyślnej wartości" msgid "This program is read-only, clone it to edit" msgstr "Ten program jest tylko do odczytu, skopiuj go, aby edytować" From 1a771b0e72d44e6de2e6df74eb0fe71f7ee612d5 Mon Sep 17 00:00:00 2001 From: pkubaj Date: Fri, 18 Oct 2019 14:00:37 +0200 Subject: [PATCH 105/109] Fix build on ARM and PPC ARM and PPC use unsigned char by default. --- src/object/task/taskgoto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/object/task/taskgoto.h b/src/object/task/taskgoto.h index 296fec92..74de5e1c 100644 --- a/src/object/task/taskgoto.h +++ b/src/object/task/taskgoto.h @@ -147,7 +147,7 @@ protected: int m_bmTotal = 0; // number of points in m_bmPoints int m_bmIndex = 0; // index in m_bmPoints Math::Vector m_bmPoints[MAXPOINTS+2]; - char m_bmIter[MAXPOINTS+2] = {}; + signed char m_bmIter[MAXPOINTS+2] = {}; int m_bmIterCounter = 0; CObject* m_bmCargoObject = nullptr; float m_bmFinalMove = 0.0f; // final advance distance From b9ac5688e9f0a767ed56433d7835e3dd777223e2 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Sun, 28 Jul 2019 21:18:16 +0200 Subject: [PATCH 106/109] Fix package name in compilation instruction --- INSTALL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index 423166dc..fc69342c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -71,7 +71,7 @@ You will need: On Ubuntu (and probably any other Debian-based system), you can use the following command to install all required packages: ``` - $ apt-get install build-essential cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsndfile1-dev libvorbis-dev libogg-dev libpng12-dev libglew-dev libopenal-dev libboost-dev libboost-system-dev libboost-filesystem-dev libboost-regex-dev libphysfs-dev gettext git po4a vorbis-tools + $ apt-get install build-essential cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsndfile1-dev libvorbis-dev libogg-dev libpng-dev libglew-dev libopenal-dev libboost-dev libboost-system-dev libboost-filesystem-dev libboost-regex-dev libphysfs-dev gettext git po4a vorbis-tools ``` Make sure you install the packages along with header files (often distributed in separate *-dev packages). If you miss any requirements, From 4e4c3671c65cf91868f6235cd44b10b396c31596 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Sun, 29 Dec 2019 13:11:57 +0100 Subject: [PATCH 107/109] Fixed Jenkins builds --- Jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 95b567a8..90e0af2d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -81,6 +81,8 @@ pipeline { # Create AppImage NO_STRIP=1 ./squashfs-root/AppRun -e colobot --output appimage --appdir colobot.AppDir -d desktop/colobot.desktop -i ../../desktop/colobot.svg + #rename AppImage file to avoid "No such file or directory" errors + find . -maxdepth 1 -type f -name '*AppImage' -name 'Colobot*' -exec sh -c 'x="{}"; mv "$x" "Colobot-x86_64.AppImage"' \; chmod +x Colobot-x86_64.AppImage # Prepare folder for zip From f97da6482b5d797fe3e43987f2c43f3e34ef88a4 Mon Sep 17 00:00:00 2001 From: tomangelo2 Date: Sun, 29 Dec 2019 13:18:39 +0100 Subject: [PATCH 108/109] Fixed escape character --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 90e0af2d..47dbd3c2 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -82,7 +82,7 @@ pipeline { # Create AppImage NO_STRIP=1 ./squashfs-root/AppRun -e colobot --output appimage --appdir colobot.AppDir -d desktop/colobot.desktop -i ../../desktop/colobot.svg #rename AppImage file to avoid "No such file or directory" errors - find . -maxdepth 1 -type f -name '*AppImage' -name 'Colobot*' -exec sh -c 'x="{}"; mv "$x" "Colobot-x86_64.AppImage"' \; + find . -maxdepth 1 -type f -name '*AppImage' -name 'Colobot*' -exec sh -c 'x="{}"; mv "$x" "Colobot-x86_64.AppImage"' \\; chmod +x Colobot-x86_64.AppImage # Prepare folder for zip From fc2bd68876ac6302dbc8e91e8ffa33592db14b21 Mon Sep 17 00:00:00 2001 From: suve Date: Sun, 9 Feb 2020 00:36:05 +0100 Subject: [PATCH 109/109] Fix missing std includes --- src/CBot/CBotInstr/CBotExprLitString.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CBot/CBotInstr/CBotExprLitString.cpp b/src/CBot/CBotInstr/CBotExprLitString.cpp index fc254162..69e42d60 100644 --- a/src/CBot/CBotInstr/CBotExprLitString.cpp +++ b/src/CBot/CBotInstr/CBotExprLitString.cpp @@ -24,6 +24,8 @@ #include "CBot/CBotVar/CBotVar.h" +#include + namespace CBot {