From ce450d1c00e641f971e80040c326669393afb640 Mon Sep 17 00:00:00 2001 From: melex750 Date: Fri, 25 Jun 2021 18:47:25 -0400 Subject: [PATCH 1/5] Fix save/load programs for insects from AlienEgg fixes #1370 --- src/object/auto/autoegg.cpp | 5 ++++- src/object/old_object.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/object/auto/autoegg.cpp b/src/object/auto/autoegg.cpp index 6c0026d8..ad5d6e91 100644 --- a/src/object/auto/autoegg.cpp +++ b/src/object/auto/autoegg.cpp @@ -24,6 +24,7 @@ #include "graphics/engine/pyro_manager.h" +#include "level/parser/parser.h" #include "level/parser/parserline.h" #include "level/parser/parserparam.h" @@ -194,7 +195,9 @@ bool CAutoEgg::EventProcess(const Event &event) CProgramStorageObject* programStorage = dynamic_cast(alien); Program* program = programStorage->AddProgram(); - programStorage->ReadProgram(program, m_alienProgramName.c_str()); + programStorage->ReadProgram(program, InjectLevelPathsForCurrentLevel(m_alienProgramName, "ai")); + program->readOnly = true; + program->filename = m_alienProgramName; programmable->RunProgram(program); } Init(); diff --git a/src/object/old_object.cpp b/src/object/old_object.cpp index 7dedda8a..94cd7aa7 100644 --- a/src/object/old_object.cpp +++ b/src/object/old_object.cpp @@ -1226,7 +1226,7 @@ void COldObject::Read(CLevelParserLine* line) std::string op = "autoValue" + boost::lexical_cast(i+1); // autoValue1..autoValue5 m_auto->SetValue(i, line->GetParam(op)->AsFloat(0.0f)); } - m_auto->SetString(const_cast(line->GetParam("autoString")->AsPath("ai", "").c_str())); + m_auto->SetString(const_cast(line->GetParam("autoString")->AsString("").c_str())); int i = line->GetParam("run")->AsInt(-1); if (i != -1) From 55d6c431f2492e3a423fe03cc48260f65f82c5cf Mon Sep 17 00:00:00 2001 From: melex750 Date: Fri, 25 Jun 2021 18:50:15 -0400 Subject: [PATCH 2/5] Fix a bug in WriteStream and ReadStream Added a unit test to confirm reliability of I/O functions used by SaveState and RestoreState. --- src/CBot/CBotFileUtils.cpp | 8 +- test/unit/CBot/CBot_test.cpp | 195 +++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 2 deletions(-) diff --git a/src/CBot/CBotFileUtils.cpp b/src/CBot/CBotFileUtils.cpp index 7a614558..070e8cca 100644 --- a/src/CBot/CBotFileUtils.cpp +++ b/src/CBot/CBotFileUtils.cpp @@ -342,7 +342,11 @@ bool WriteStream(std::ostream &ostr, std::istream& istr) if (!WriteLong(ostr, size)) return false; if (!istr.seekg(0, istr.beg)) return false; - if (!(ostr << istr.rdbuf())) return false; + while (size > 0) + { + size -= 1; + if (!ostr.put(istr.get())) return false; + } return true; } @@ -355,7 +359,7 @@ bool ReadStream(std::istream& istr, std::ostream &ostr) while (length-- > 0) { - if (!(ostr << istr.get())) return false; + if (!ostr.put(istr.get())) return false; } return true; } diff --git a/test/unit/CBot/CBot_test.cpp b/test/unit/CBot/CBot_test.cpp index 4f4f37c7..cd7dda47 100644 --- a/test/unit/CBot/CBot_test.cpp +++ b/test/unit/CBot/CBot_test.cpp @@ -20,6 +20,7 @@ #include "CBot/CBot.h" #include +#include #include extern bool g_cbotTestSaveState; @@ -319,6 +320,200 @@ protected: } }; +TEST_F(CBotUT, TestSaveStateIOFunctions) +{ + std::stringstream sstr(""); + std::string teststring; + + for (char c = std::numeric_limits::min() ;; ++c) + { + teststring.push_back(c); + if ( c == std::numeric_limits::max() ) break; + } + + auto CallWriteFunctions = [&sstr, &teststring]() -> bool + { + if (!WriteWord(sstr, static_cast(0))) return false; + if (!WriteWord(sstr, std::numeric_limits::max() / 2)) return false; + if (!WriteWord(sstr, std::numeric_limits::max())) return false; + + if (!WriteByte(sstr, std::numeric_limits::min())) return false; + if (!WriteByte(sstr, std::numeric_limits::max())) return false; + + if (!WriteShort(sstr, std::numeric_limits::min())) return false; + if (!WriteShort(sstr, std::numeric_limits::min() / 2)) return false; + if (!WriteShort(sstr, -1)) return false; + if (!WriteShort(sstr, 0)) return false; + if (!WriteShort(sstr, std::numeric_limits::max() / 2)) return false; + if (!WriteShort(sstr, std::numeric_limits::max())) return false; + + if (!WriteUInt32(sstr, static_cast(0))) return false; + if (!WriteUInt32(sstr, std::numeric_limits::max() / 2)) return false; + if (!WriteUInt32(sstr, std::numeric_limits::max())) return false; + + if (!WriteInt(sstr, std::numeric_limits::min())) return false; + if (!WriteInt(sstr, std::numeric_limits::min() / 2)) return false; + if (!WriteInt(sstr, -1)) return false; + if (!WriteInt(sstr, 0)) return false; + if (!WriteInt(sstr, std::numeric_limits::max() / 2)) return false; + if (!WriteInt(sstr, std::numeric_limits::max())) return false; + + if (!WriteLong(sstr, std::numeric_limits::min())) return false; + if (!WriteLong(sstr, std::numeric_limits::min() / 2L)) return false; + if (!WriteLong(sstr, -1L)) return false; + if (!WriteLong(sstr, 0L)) return false; + if (!WriteLong(sstr, std::numeric_limits::max() / 2L)) return false; + if (!WriteLong(sstr, std::numeric_limits::max())) return false; + + // test with padding bytes (not currently used anywhere) + if (!WriteLong(sstr, 1234567890L, 10)) return false; + + if (!WriteFloat(sstr, std::numeric_limits::min())) return false; + if (!WriteFloat(sstr, 0.0f)) return false; + if (!WriteFloat(sstr, std::numeric_limits::max())) return false; + + if (!WriteDouble(sstr, std::numeric_limits::min())) return false; + if (!WriteDouble(sstr, 0.0)) return false; + if (!WriteDouble(sstr, std::numeric_limits::max())) return false; + + if (!WriteString(sstr, "")) return false; + if (!WriteString(sstr, teststring)) return false; + return true; + }; + + if ( !CallWriteFunctions() ) + { + ADD_FAILURE() << "failed in CallWriteFunctions()" << std::endl; + return; + } + + std::stringstream savestream(""); + + if ( !WriteStream(savestream, sstr) ) + { + ADD_FAILURE() << "CBot::WriteStream() failed" << std::endl; + return; + } + + std::stringstream newstream(""); + + if ( !ReadStream(savestream, newstream) ) + { + ADD_FAILURE() << "CBot:ReadStream() failed" << std::endl; + return; + } + + auto CallReadFunctions = [&teststring, &newstream]() -> bool + { + unsigned short w = 1; + if (!ReadWord(newstream, w)) return false; + if (w != static_cast(0)) return false; + if (!ReadWord(newstream, w)) return false; + if (w != std::numeric_limits::max() / 2) return false; + + if (!ReadWord(newstream, w)) return false; + if (w != std::numeric_limits::max()) return false; + + char c = 1; + if (!ReadByte(newstream, c)) return false; + if (c != std::numeric_limits::min()) return false; + if (!ReadByte(newstream, c)) return false; + if (c != std::numeric_limits::max()) return false; + + short s = 1; + if (!ReadShort(newstream, s)) return false; + if (s != std::numeric_limits::min()) return false; + if (!ReadShort(newstream, s)) return false; + if (s != std::numeric_limits::min() / 2) return false; + + if (!ReadShort(newstream, s)) return false; + if (s != -1) return false; + if (!ReadShort(newstream, s)) return false; + if (s != 0) return false; + + if (!ReadShort(newstream, s)) return false; + if (s != std::numeric_limits::max() / 2) return false; + if (!ReadShort(newstream, s)) return false; + if (s != std::numeric_limits::max()) return false; + + uint32_t u = 1; + if (!ReadUInt32(newstream, u)) return false; + if (u != static_cast(0)) return false; + if (!ReadUInt32(newstream, u)) return false; + if (u != std::numeric_limits::max() / 2) return false; + + if (!ReadUInt32(newstream, u)) return false; + if (u != std::numeric_limits::max()) return false; + + int i = 1; + if (!ReadInt(newstream, i)) return false; + if (i != std::numeric_limits::min()) return false; + if (!ReadInt(newstream, i)) return false; + if (i != std::numeric_limits::min() / 2) return false; + + if (!ReadInt(newstream, i)) return false; + if (i != -1) return false; + if (!ReadInt(newstream, i)) return false; + if (i != 0) return false; + + if (!ReadInt(newstream, i)) return false; + if (i != std::numeric_limits::max() / 2) return false; + if (!ReadInt(newstream, i)) return false; + if (i != std::numeric_limits::max()) return false; + + long l = 1L; + if (!ReadLong(newstream, l)) return false; + if (l != std::numeric_limits::min()) return false; + if (!ReadLong(newstream, l)) return false; + if (l != std::numeric_limits::min() / 2L) return false; + + if (!ReadLong(newstream, l)) return false; + if (l != -1L) return false; + if (!ReadLong(newstream, l)) return false; + if (l != 0L) return false; + + if (!ReadLong(newstream, l)) return false; + if (l != std::numeric_limits::max() / 2L) return false; + if (!ReadLong(newstream, l)) return false; + if (l != std::numeric_limits::max()) return false; + + if (!ReadLong(newstream, l)) return false; + if (l != 1234567890L) return false; + + float f = 1.0f; + if (!ReadFloat(newstream, f)) return false; + if (f != std::numeric_limits::min()) return false; + if (!ReadFloat(newstream, f)) return false; + if (f != 0.0f) return false; + + if (!ReadFloat(newstream, f)) return false; + if (f != std::numeric_limits::max()) return false; + + double d = 1.0; + if (!ReadDouble(newstream, d)) return false; + if (d != std::numeric_limits::min()) return false; + if (!ReadDouble(newstream, d)) return false; + if (d != 0.0) return false; + + if (!ReadDouble(newstream, d)) return false; + if (d != std::numeric_limits::max()) return false; + + std::string newstring = "should be empty string after next read"; + if (!ReadString(newstream, newstring)) return false; + if (newstring != "") return false; + + if (!ReadString(newstream, newstring)) return false; + if (newstring != teststring) return false; + return true; + }; + + if ( !CallReadFunctions() ) + { + ADD_FAILURE() << "failed in CallReadFunctions()" << std::endl; + return; + } +} + TEST_F(CBotUT, EmptyTest) { ExecuteTest( From 117c72ba72417ff558647307eb6b1430287b3001 Mon Sep 17 00:00:00 2001 From: nipsufn <17983323+nipsufn@users.noreply.github.com> Date: Wed, 29 Sep 2021 15:26:19 +0200 Subject: [PATCH 3/5] fix SatCom content offset on high resolution / small font size --- .gitignore | 2 ++ src/ui/controls/edit.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index e195dc2b..781f171c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ Makefile /src/libcolobotbase.a # Ignore the generated documentation +CMakeDoxyfile.in +CMakeDoxygenDefaults.cmake /doc /Doxyfile diff --git a/src/ui/controls/edit.cpp b/src/ui/controls/edit.cpp index 570bd518..cff76ccb 100644 --- a/src/ui/controls/edit.cpp +++ b/src/ui/controls/edit.cpp @@ -955,7 +955,7 @@ void CEdit::Draw() if ( i >= m_lineFirst+m_lineVisible ) break; - pos.x = m_pos.x+(7.5f/640.0f)*(m_fontSize/Gfx::FONT_SIZE_SMALL); + pos.x = m_pos.x+(7.5f/640.0f); if ( m_bAutoIndent ) { const char *s = "\t"; // line | dotted @@ -1117,7 +1117,7 @@ void CEdit::Draw() { if ( i == m_lineTotal-1 || m_cursor1 < m_lineOffset[i+1] ) { - pos.x = m_pos.x+(7.5f/640.0f)*(m_fontSize/Gfx::FONT_SIZE_SMALL); + pos.x = m_pos.x+(7.5f/640.0f); if ( m_bAutoIndent ) { pos.x += indentLength*m_lineIndent[i]; From 3aa7c3c2e05277ec9cf3736bd24a3ead723f0b87 Mon Sep 17 00:00:00 2001 From: tomangelo Date: Sun, 5 Dec 2021 11:51:28 +0100 Subject: [PATCH 4/5] Stop handling compilation warnings as errors (#1477) * Stop handling compilation warnings as errors * Restore mistakenly removed flag --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index feacc350..c4dd5808 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,7 +156,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") message(STATUS "Detected GCC version 4.7+") - set(NORMAL_CXX_FLAGS "-Wall -Werror -Wold-style-cast -pedantic-errors -Wmissing-declarations") + set(NORMAL_CXX_FLAGS "-Wall -Wold-style-cast -pedantic-errors -Wmissing-declarations") 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 if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) @@ -178,7 +178,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=bfd") endif() - set(NORMAL_CXX_FLAGS "-Wall -Werror -Wold-style-cast -pedantic-errors -Wmissing-prototypes") + set(NORMAL_CXX_FLAGS "-Wall -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") set(DEBUG_CXX_FLAGS "-g -O0") From 9fd935770a6a022756b91158c4338ebf90a57a4d Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Sun, 5 Dec 2021 12:12:00 +0100 Subject: [PATCH 5/5] Fix CBotUT.TestSaveStateIOFunctions Fail occurred due to wrong read of min double. `unsigned long` has been changed in Write/ReadDouble functions to `uint64_t`. `unsigned int` has been changed in Write/ReadFloat functions to `uint32_t`. According to the standard `int` is at least 16-bit so it might be too small for 32-bit `float`, `long` is at least 32-bit so it might be too small for 64-bit `double`, and `long long` is at least 64-bit. --- src/CBot/CBotFileUtils.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/CBot/CBotFileUtils.cpp b/src/CBot/CBotFileUtils.cpp index 050205e3..cdbc62af 100644 --- a/src/CBot/CBotFileUtils.cpp +++ b/src/CBot/CBotFileUtils.cpp @@ -186,7 +186,7 @@ bool WriteFloat(std::ostream &ostr, float f) union TypeConverter { float fValue; - unsigned int iValue; + uint32_t iValue; }; TypeConverter u; @@ -194,7 +194,7 @@ bool WriteFloat(std::ostream &ostr, float f) u.iValue = 0; u.fValue = f; - return WriteBinary(ostr, u.iValue); + return WriteBinary(ostr, u.iValue); } bool ReadFloat(std::istream &istr, float &f) @@ -202,14 +202,14 @@ bool ReadFloat(std::istream &istr, float &f) union TypeConverter { float fValue; - unsigned int iValue; + uint32_t iValue; }; TypeConverter u; u.fValue = 0.0f; u.iValue = 0; - if (!ReadBinary(istr, u.iValue)) return false; + if (!ReadBinary(istr, u.iValue)) return false; f = u.fValue; return true; } @@ -219,7 +219,7 @@ bool WriteDouble(std::ostream &ostr, double d) union TypeConverter { double dValue; - unsigned long iValue; + uint64_t iValue; }; TypeConverter u; @@ -227,7 +227,7 @@ bool WriteDouble(std::ostream &ostr, double d) u.iValue = 0; u.dValue = d; - return WriteBinary(ostr, u.iValue); + return WriteBinary(ostr, u.iValue); } bool ReadDouble(std::istream &istr, double &d) @@ -235,14 +235,14 @@ bool ReadDouble(std::istream &istr, double &d) union TypeConverter { double dValue; - unsigned long iValue; + uint64_t iValue; }; TypeConverter u; u.dValue = 0.0; u.iValue = 0; - if (!ReadBinary(istr, u.iValue)) return false; + if (!ReadBinary(istr, u.iValue)) return false; d = u.dValue; return true; }