aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2010-08-01 08:31:50 +0000
committerEugene Sandulenko2010-10-12 22:17:11 +0000
commit53a9d2d0a1dab1119dc1cc12886321fa72743061 (patch)
tree2ffff2a8919e6b30d67f129b5fde26ac3c305e0d /engines
parent2f86c7a45c7c092ee294c056a9b971d2bbf64114 (diff)
downloadscummvm-rg350-53a9d2d0a1dab1119dc1cc12886321fa72743061.tar.gz
scummvm-rg350-53a9d2d0a1dab1119dc1cc12886321fa72743061.tar.bz2
scummvm-rg350-53a9d2d0a1dab1119dc1cc12886321fa72743061.zip
SWORD25: Converted the math folder files
svn-id: r53197
Diffstat (limited to 'engines')
-rw-r--r--engines/sword25/kernel/inputpersistenceblock.cpp110
-rw-r--r--engines/sword25/kernel/inputpersistenceblock.h5
-rw-r--r--engines/sword25/kernel/kernel.h12
-rw-r--r--engines/sword25/math/geometry_script.cpp249
-rw-r--r--engines/sword25/math/line.h165
-rw-r--r--engines/sword25/math/polygon.cpp339
-rw-r--r--engines/sword25/math/polygon.h273
-rw-r--r--engines/sword25/math/rect.h303
-rw-r--r--engines/sword25/math/region.cpp194
-rw-r--r--engines/sword25/math/region.h229
-rw-r--r--engines/sword25/math/regionregistry.cpp46
-rw-r--r--engines/sword25/math/regionregistry.h29
-rw-r--r--engines/sword25/math/vertex.cpp26
-rw-r--r--engines/sword25/math/vertex.h107
-rw-r--r--engines/sword25/math/walkregion.cpp277
-rw-r--r--engines/sword25/math/walkregion.h84
-rw-r--r--engines/sword25/script/luascript.cpp2
17 files changed, 1018 insertions, 1432 deletions
diff --git a/engines/sword25/kernel/inputpersistenceblock.cpp b/engines/sword25/kernel/inputpersistenceblock.cpp
index 377b0bd994..6528d041ad 100644
--- a/engines/sword25/kernel/inputpersistenceblock.cpp
+++ b/engines/sword25/kernel/inputpersistenceblock.cpp
@@ -40,23 +40,21 @@
#include "sword25/kernel/inputpersistenceblock.h"
-using namespace std;
+namespace Sword25 {
// -----------------------------------------------------------------------------
-// Construction / Destruction
+// Constructor / Destructor
// -----------------------------------------------------------------------------
BS_InputPersistenceBlock::BS_InputPersistenceBlock(const void * Data, unsigned int DataLength) :
- m_Data(static_cast<const unsigned char *>(Data), static_cast<const unsigned char *>(Data) + DataLength),
- m_ErrorState(NONE)
-{
+ m_Data(static_cast<const unsigned char *>(Data), DataLength),
+ m_ErrorState(NONE) {
m_Iter = m_Data.begin();
}
// -----------------------------------------------------------------------------
-BS_InputPersistenceBlock::~BS_InputPersistenceBlock()
-{
+BS_InputPersistenceBlock::~BS_InputPersistenceBlock() {
if (m_Iter != m_Data.end()) BS_LOG_WARNINGLN("Persistence block was not read to the end.");
}
@@ -64,80 +62,69 @@ BS_InputPersistenceBlock::~BS_InputPersistenceBlock()
// Reading
// -----------------------------------------------------------------------------
-void BS_InputPersistenceBlock::Read(signed int & Value)
-{
- if (CheckMarker(SINT_MARKER))
- {
+void BS_InputPersistenceBlock::Read(int16 &Value) {
+ signed int v;
+ Read(v);
+ Value = static_cast<int16>(v);
+}
+
+// -----------------------------------------------------------------------------
+
+void BS_InputPersistenceBlock::Read(signed int &Value) {
+ if (CheckMarker(SINT_MARKER)) {
RawRead(&Value, sizeof(signed int));
Value = ConvertEndianessFromStorageToSystem(Value);
- }
- else
- {
+ } else {
Value = 0;
}
}
// -----------------------------------------------------------------------------
-void BS_InputPersistenceBlock::Read(unsigned int & Value)
-{
- if (CheckMarker(UINT_MARKER))
- {
+void BS_InputPersistenceBlock::Read(unsigned int &Value) {
+ if (CheckMarker(UINT_MARKER)) {
RawRead(&Value, sizeof(unsigned int));
Value = ConvertEndianessFromStorageToSystem(Value);
- }
- else
- {
+ } else {
Value = 0;
}
}
// -----------------------------------------------------------------------------
-void BS_InputPersistenceBlock::Read(float & Value)
-{
- if (CheckMarker(FLOAT_MARKER))
- {
+void BS_InputPersistenceBlock::Read(float &Value) {
+ if (CheckMarker(FLOAT_MARKER)) {
RawRead(&Value, sizeof(float));
Value = ConvertEndianessFromStorageToSystem(Value);
- }
- else
- {
+ } else {
Value = 0.0f;
}
}
// -----------------------------------------------------------------------------
-void BS_InputPersistenceBlock::Read(bool & Value)
-{
- if (CheckMarker(BOOL_MARKER))
- {
+void BS_InputPersistenceBlock::Read(bool &Value) {
+ if (CheckMarker(BOOL_MARKER)) {
unsigned int UIntBool;
RawRead(&UIntBool, sizeof(float));
UIntBool = ConvertEndianessFromStorageToSystem(UIntBool);
Value = UIntBool == 0 ? false : true;
- }
- else
- {
+ } else {
Value = 0.0f;
}
}
// -----------------------------------------------------------------------------
-void BS_InputPersistenceBlock::Read(std::string & Value)
-{
+void BS_InputPersistenceBlock::Read(Common::String &Value) {
Value = "";
- if (CheckMarker(STRING_MARKER))
- {
+ if (CheckMarker(STRING_MARKER)) {
unsigned int Size;
Read(Size);
- if (CheckBlockSize(Size))
- {
- Value = std::string(reinterpret_cast<const char *>(&*m_Iter), Size);
+ if (CheckBlockSize(Size)) {
+ Value = Common::String(reinterpret_cast<const char *>(&*m_Iter), Size);
m_Iter += Size;
}
}
@@ -145,16 +132,13 @@ void BS_InputPersistenceBlock::Read(std::string & Value)
// -----------------------------------------------------------------------------
-void BS_InputPersistenceBlock::Read(vector<unsigned char> & Value)
-{
- if (CheckMarker(BLOCK_MARKER))
- {
+void BS_InputPersistenceBlock::Read(Common::Array<unsigned char> &Value) {
+ if (CheckMarker(BLOCK_MARKER)) {
unsigned int Size;
Read(Size);
- if (CheckBlockSize(Size))
- {
- Value = vector<unsigned char>(m_Iter, m_Iter + Size);
+ if (CheckBlockSize(Size)) {
+ Value = Common::Array<unsigned char>(m_Iter, Size);
m_Iter += Size;
}
}
@@ -162,10 +146,8 @@ void BS_InputPersistenceBlock::Read(vector<unsigned char> & Value)
// -----------------------------------------------------------------------------
-void BS_InputPersistenceBlock::RawRead(void * DestPtr, size_t Size)
-{
- if (CheckBlockSize(Size))
- {
+void BS_InputPersistenceBlock::RawRead(void * DestPtr, size_t Size) {
+ if (CheckBlockSize(Size)) {
memcpy(DestPtr, &*m_Iter, Size);
m_Iter += Size;
}
@@ -173,14 +155,10 @@ void BS_InputPersistenceBlock::RawRead(void * DestPtr, size_t Size)
// -----------------------------------------------------------------------------
-bool BS_InputPersistenceBlock::CheckBlockSize(int Size)
-{
- if (m_Data.end() - m_Iter >= Size)
- {
+bool BS_InputPersistenceBlock::CheckBlockSize(int Size) {
+ if (m_Data.end() - m_Iter >= Size) {
return true;
- }
- else
- {
+ } else {
m_ErrorState = END_OF_DATA;
BS_LOG_ERRORLN("Unexpected end of persistence block.");
return false;
@@ -189,18 +167,16 @@ bool BS_InputPersistenceBlock::CheckBlockSize(int Size)
// -----------------------------------------------------------------------------
-bool BS_InputPersistenceBlock::CheckMarker(unsigned char Marker)
-{
+bool BS_InputPersistenceBlock::CheckMarker(unsigned char Marker) {
if (!IsGood() || !CheckBlockSize(1)) return false;
- if (*m_Iter++ == Marker)
- {
+ if (*m_Iter++ == Marker) {
return true;
- }
- else
- {
+ } else {
m_ErrorState = OUT_OF_SYNC;
BS_LOG_ERRORLN("Wrong type marker found in persistence block.");
return false;
}
}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/inputpersistenceblock.h b/engines/sword25/kernel/inputpersistenceblock.h
index 6e1ec39943..b30429771b 100644
--- a/engines/sword25/kernel/inputpersistenceblock.h
+++ b/engines/sword25/kernel/inputpersistenceblock.h
@@ -62,12 +62,13 @@ public:
BS_InputPersistenceBlock(const void *Data, unsigned int DataLength);
virtual ~BS_InputPersistenceBlock();
+ void Read(int16 &Value);
void Read(signed int &Value);
void Read(unsigned int &Value);
void Read(float &Value);
void Read(bool &Value);
- void Read(std::string &Value);
- void Read(std::vector<unsigned char> &Value);
+ void Read(Common::String &Value);
+ void Read(Common::Array<unsigned char> &Value);
bool IsGood() const { return m_ErrorState == NONE; }
ErrorState GetErrorState() const { return m_ErrorState; }
diff --git a/engines/sword25/kernel/kernel.h b/engines/sword25/kernel/kernel.h
index 692a4a215d..d09cf68ab6 100644
--- a/engines/sword25/kernel/kernel.h
+++ b/engines/sword25/kernel/kernel.h
@@ -339,6 +339,18 @@ public:
BS_Service* (*CreateMethod)(BS_Kernel *);
};
+template<class T>
+void ReverseArray(Common::Array<T> Arr) {
+ if (Arr.size() < 2)
+ return;
+
+ for (uint i = 0; i < (Arr.size() / 2 - 1); ++i) {
+ T temp = Arr[i];
+ Arr[i] = Arr[Arr.size() - i - 1];
+ Arr[Arr.size() - i - 1] = temp;
+ }
}
+} // End of namespace Sword25
+
#endif
diff --git a/engines/sword25/math/geometry_script.cpp b/engines/sword25/math/geometry_script.cpp
index 96606a7206..e656e5f548 100644
--- a/engines/sword25/math/geometry_script.cpp
+++ b/engines/sword25/math/geometry_script.cpp
@@ -36,11 +36,7 @@
// Includes
// -----------------------------------------------------------------------------
-#include "sword25/kernel/memlog_off.h"
-#include <memory>
-#include <vector>
-#include "sword25/kernel/memlog_on.h"
-
+#include "common/array.h"
#include "sword25/gfx/graphicengine.h"
#include "sword25/kernel/common.h"
#include "sword25/kernel/kernel.h"
@@ -55,21 +51,20 @@
// -----------------------------------------------------------------------------
-using namespace std;
+namespace Sword25 {
// -----------------------------------------------------------------------------
// Constants
// -----------------------------------------------------------------------------
-// Die Strings werden als #defines definiert um Stringkomposition zur Compilezeit zu ermöglichen.
+// These strings are defined as #defines to enable compile-time string composition
#define REGION_CLASS_NAME "Geo.Region"
#define WALKREGION_CLASS_NAME "Geo.WalkRegion"
// -----------------------------------------------------------------------------
-// Wie luaL_checkudata, nur ohne dass kein Fehler erzeugt wird.
-static void * my_checkudata (lua_State *L, int ud, const char *tname)
-{
+// How luaL_checkudata, only without that no error is generated.
+static void *my_checkudata(::lua_State *L, int ud, const char *tname) {
int top = lua_gettop(L);
void * p = lua_touserdata(L, ud);
@@ -79,8 +74,8 @@ static void * my_checkudata (lua_State *L, int ud, const char *tname)
{
// lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
BS_LuaBindhelper::GetMetatable(L, tname);
- if (lua_rawequal(L, -1, -2)) /* does it have the correct mt? */
- {
+ /* does it have the correct mt? */
+ if (lua_rawequal(L, -1, -2)) {
lua_settop(L, top);
return p;
}
@@ -93,50 +88,43 @@ static void * my_checkudata (lua_State *L, int ud, const char *tname)
// -----------------------------------------------------------------------------
-static void NewUintUserData(lua_State * L, unsigned int Value)
-{
+static void NewUintUserData(::lua_State *L, unsigned int Value) {
void * UserData = lua_newuserdata(L, sizeof(Value));
memcpy(UserData, &Value, sizeof(Value));
}
// -----------------------------------------------------------------------------
-static bool IsValidPolygonDefinition(lua_State * L)
-{
+static bool IsValidPolygonDefinition(::lua_State *L) {
#ifdef DEBUG
int __startStackDepth = lua_gettop(L);
#endif
- // Sicherstellen, dass wir wirklich eine Tabelle betrachten
- if (!lua_istable(L, -1))
- {
+ // Ensure that we actually consider a table
+ if (!lua_istable(L, -1)) {
luaL_error(L, "Invalid polygon definition. Unexpected type, \"table\" needed.");
return false;
}
int TableSize = luaL_getn(L, -1);
- // Sicherstellen, dass mindestens 3 Vertecies existieren.
- if (TableSize < 6)
- {
+ // Make sure that there are at least three Vertecies
+ if (TableSize < 6) {
luaL_error(L, "Invalid polygon definition. At least three vertecies needed.");
return false;
}
- // Sicherstellen, dass die Anzahl der Tabellenelemente durch zwei teilbar ist.
- // Da je zwei Elemente ein Vertex definieren, ist eine ungerade Anzahl an Elementen nicht zulässig.
- if ((TableSize % 2) != 0)
- {
+ // Make sure that the number of table elements is divisible by two.
+ // Since any two elements is a vertex, an odd number of elements is not allowed
+ if ((TableSize % 2) != 0) {
luaL_error(L, "Invalid polygon definition. Even number of table elements needed.");
return false;
}
- // Sicherstellen, dass alle Elemente der Tabelle vom Typ Number sind.
- for (int i = 1; i <= TableSize; i += 1)
- {
+ // Ensure that all elements in the table are of type Number
+ for (int i = 1; i <= TableSize; i += 1) {
lua_rawgeti(L, -1, i);
- if (!lua_isnumber(L, -1))
- {
+ if (!lua_isnumber(L, -1)) {
luaL_error(L, "Invalid polygon definition. All table elements have to be numbers.");
return false;
}
@@ -152,32 +140,31 @@ static bool IsValidPolygonDefinition(lua_State * L)
// -----------------------------------------------------------------------------
-static void TablePolygonToPolygon(lua_State * L, BS_Polygon & Polygon)
-{
+static void TablePolygonToPolygon(::lua_State *L, BS_Polygon &Polygon) {
#ifdef DEBUG
int __startStackDepth = lua_gettop(L);
#endif
- // Sicherstellen, dass eine gültige Polygon-Definition auf dem Stack liegt.
- // Es ist nicht notwendig den Rückgabewert abzufangen, da alle Fehler über luaL_error ausgegeben werden und somit die Ausführung des
- // Skriptes beenden.
+ // Ensure that a valid polygon definition is on the stack.
+ // It is not necessary to catch the return value, since all errors are reported on luaL_error
+ // End script.
IsValidPolygonDefinition(L);
int VertexCount = luaL_getn(L, -1) / 2;
- // Speicher für Vertecies reservieren
- vector<BS_Vertex> Vertecies;
+ // Memory is reserved for Vertecies
+ Common::Array<BS_Vertex> Vertecies;
Vertecies.reserve(VertexCount);
- // Vertecies erstellen
+ // Create Vertecies
for (int i = 0; i < VertexCount; i++)
{
- // X-Wert
+ // X Value
lua_rawgeti(L, -1, (i * 2) + 1);
int X = static_cast<int>(lua_tonumber(L, -1));
lua_pop(L, 1);
- // Y-Wert
+ // Y Value
lua_rawgeti(L, -1, (i * 2) + 2);
int Y = static_cast<int>(lua_tonumber(L, -1));
lua_pop(L, 1);
@@ -185,72 +172,63 @@ static void TablePolygonToPolygon(lua_State * L, BS_Polygon & Polygon)
// Vertex
Vertecies.push_back(BS_Vertex(X, Y));
}
- BS_ASSERT(Vertecies.size() == VertexCount);
+ BS_ASSERT((int)Vertecies.size() == VertexCount);
#ifdef DEBUG
BS_ASSERT(__startStackDepth == lua_gettop(L));
#endif
- // Polygon erstellen
+ // Create polygon
Polygon.Init(VertexCount, &Vertecies[0]);
}
// -----------------------------------------------------------------------------
-static unsigned int TableRegionToRegion(lua_State * L, const char * ClassName)
-{
+static unsigned int TableRegionToRegion(::lua_State *L, const char *ClassName) {
#ifdef DEBUG
int __startStackDepth = lua_gettop(L);
#endif
- // Man kann eine Region in Lua auf zwei Arten definieren:
- // 1. Eine Tabelle, die ein Polygon definiert (Polygon = Tabelle mit Zahlen, wobei je zwei aufeinander folgende Zahlen ein Vertex definieren)
- // Das eine Polygon definiert die Region vollständig (=> keine Löcher möglich)
- // 2. Eine Tabelle, die mehrere Polygondefinitionen (wiederum Tabellen (siehe 1.)) enthält.
- // Dann definiert das erste Polygon den Umriss der Region und die folgenden Löcher im ersten Polygon.
+ // You can define a region in Lua in two ways:
+ // 1. A table that defines a polygon (polgon = table with numbers, which define
+ // two consecutive numbers per vertex)
+ // 2. A table containing more polygon definitions
+ // Then the first polygon is the contour of the region, and the following are holes
+ // defined in the first polygon.
- // Es darf nur ein Parameter übergeben werden und dieser muss eine Tabelle sein.
- if (lua_gettop(L) != 1 || !lua_istable(L, -1))
- {
+ // It may be passed only one parameter, and this must be a table
+ if (lua_gettop(L) != 1 || !lua_istable(L, -1)) {
luaL_error(L, "First and only parameter has to be of type \"table\".");
return 0;
}
unsigned int RegionHandle;
- if (ClassName == REGION_CLASS_NAME)
- {
+ if (ClassName == REGION_CLASS_NAME) {
RegionHandle = BS_Region::Create(BS_Region::RT_REGION);
- }
- else if (ClassName == WALKREGION_CLASS_NAME)
- {
+ } else if (ClassName == WALKREGION_CLASS_NAME) {
RegionHandle = BS_WalkRegion::Create(BS_Region::RT_WALKREGION);
- }
- else
- {
+ } else {
BS_ASSERT(false);
}
BS_ASSERT(RegionHandle);
- // Wenn das erste Element des Parameters eine Zahl ist, wird der 1. Fall angenommen.
- // Wenn das erste Element des Parameters eine Tabelle ist, wird der 2. Fall angenommen.
- // Wenn das erste Element des Parameters einen anderen Typ hat, liegt ein Fehler vor.
+ // If the first element of the parameter is a number, then case 1 is accepted
+ // If the first element of the parameter is a table, then case 2 is accepted
+ // If the first element of the parameter has a different type, there is an error
lua_rawgeti(L, -1, 1);
int FirstElementType = lua_type(L, -1);
lua_pop(L, 1);
- switch(FirstElementType)
- {
- case LUA_TNUMBER:
- {
+ switch(FirstElementType) {
+ case LUA_TNUMBER: {
BS_Polygon Polygon;
TablePolygonToPolygon(L, Polygon);
BS_RegionRegistry::GetInstance().ResolveHandle(RegionHandle)->Init(Polygon);
}
break;
- case LUA_TTABLE:
- {
+ case LUA_TTABLE: {
lua_rawgeti(L, -1, 1);
BS_Polygon Polygon;
TablePolygonToPolygon(L, Polygon);
@@ -259,19 +237,17 @@ static unsigned int TableRegionToRegion(lua_State * L, const char * ClassName)
int PolygonCount = luaL_getn(L, -1);
if (PolygonCount == 1)
BS_RegionRegistry::GetInstance().ResolveHandle(RegionHandle)->Init(Polygon);
- else
- {
- vector<BS_Polygon> Holes;
+ else {
+ Common::Array<BS_Polygon> Holes;
Holes.reserve(PolygonCount - 1);
- for (int i = 2; i <= PolygonCount; i++)
- {
+ for (int i = 2; i <= PolygonCount; i++) {
lua_rawgeti(L, -1, i);
Holes.resize(Holes.size() + 1);
TablePolygonToPolygon(L, Holes.back());
lua_pop(L, 1);
}
- BS_ASSERT(Holes.size() == PolygonCount - 1);
+ BS_ASSERT((int)Holes.size() == PolygonCount - 1);
BS_RegionRegistry::GetInstance().ResolveHandle(RegionHandle)->Init(Polygon, &Holes);
}
@@ -292,10 +268,10 @@ static unsigned int TableRegionToRegion(lua_State * L, const char * ClassName)
// -----------------------------------------------------------------------------
-static void NewUserdataRegion(lua_State * L, const char * ClassName)
+static void NewUserdataRegion(::lua_State *L, const char *ClassName)
{
- // Region aufgrund des Lua-Codes erstellen.
- // Fehler treten nicht auf, sondern werden von der Funktion über luaL_error abgefangen.
+ // Region due to the Lua code to create
+ // Any errors that occur will be intercepted to the luaL_error
unsigned int RegionHandle = TableRegionToRegion(L, ClassName);
BS_ASSERT(RegionHandle);
@@ -308,26 +284,23 @@ static void NewUserdataRegion(lua_State * L, const char * ClassName)
// -----------------------------------------------------------------------------
-static int NewRegion(lua_State * L)
-{
+static int NewRegion(::lua_State *L) {
NewUserdataRegion(L, REGION_CLASS_NAME);
return 1;
}
// -----------------------------------------------------------------------------
-static int NewWalkRegion(lua_State * L)
-{
+static int NewWalkRegion(::lua_State *L) {
NewUserdataRegion(L, WALKREGION_CLASS_NAME);
return 1;
}
// -----------------------------------------------------------------------------
-static const char * GEO_LIBRARY_NAME = "Geo";
+static const char *GEO_LIBRARY_NAME = "Geo";
-static const luaL_reg GEO_FUNCTIONS[] =
-{
+static const luaL_reg GEO_FUNCTIONS[] = {
"NewRegion", NewRegion,
"NewWalkRegion", NewWalkRegion,
0, 0,
@@ -335,28 +308,23 @@ static const luaL_reg GEO_FUNCTIONS[] =
// -----------------------------------------------------------------------------
-static BS_Region * CheckRegion(lua_State * L)
-{
- // Der erste Parameter muss vom Typ userdata sein und die Metatable der Klasse Geo.Region oder Geo.WalkRegion
- unsigned int * RegionHandlePtr;
+static BS_Region * CheckRegion(::lua_State *L) {
+ // The first parameter must be of type 'userdata', and the Metatable class Geo.Region or Geo.WalkRegion
+ unsigned int *RegionHandlePtr;
if ((RegionHandlePtr = reinterpret_cast<unsigned int *>(my_checkudata(L, 1, REGION_CLASS_NAME))) != 0 ||
- (RegionHandlePtr = reinterpret_cast<unsigned int *>(my_checkudata(L, 1, WALKREGION_CLASS_NAME))) != 0)
- {
+ (RegionHandlePtr = reinterpret_cast<unsigned int *>(my_checkudata(L, 1, WALKREGION_CLASS_NAME))) != 0) {
return BS_RegionRegistry::GetInstance().ResolveHandle(*RegionHandlePtr);
- }
- else
- {
+ } else {
luaL_argcheck(L, 0, 1, "'" REGION_CLASS_NAME "' expected");
}
- // Compiler ruhigstellen. Ausführung kommt nie an diesem Punkt an.
+ // Compilation fix. Execution never reaches this point
return 0;
}
// -----------------------------------------------------------------------------
-static int R_IsValid(lua_State * L)
-{
+static int R_IsValid(::lua_State *L) {
BS_Region * pR = CheckRegion(L);
BS_ASSERT(pR);
@@ -366,8 +334,7 @@ static int R_IsValid(lua_State * L)
// -----------------------------------------------------------------------------
-static int R_GetX(lua_State * L)
-{
+static int R_GetX(::lua_State *L) {
BS_Region * pR = CheckRegion(L);
BS_ASSERT(pR);
@@ -377,8 +344,7 @@ static int R_GetX(lua_State * L)
// -----------------------------------------------------------------------------
-static int R_GetY(lua_State * L)
-{
+static int R_GetY(::lua_State *L) {
BS_Region * pR = CheckRegion(L);
BS_ASSERT(pR);
@@ -388,8 +354,7 @@ static int R_GetY(lua_State * L)
// -----------------------------------------------------------------------------
-static int R_GetPos(lua_State * L)
-{
+static int R_GetPos(::lua_State *L) {
BS_Region * pR = CheckRegion(L);
BS_ASSERT(pR);
@@ -399,8 +364,7 @@ static int R_GetPos(lua_State * L)
// -----------------------------------------------------------------------------
-static int R_IsPointInRegion(lua_State * L)
-{
+static int R_IsPointInRegion(::lua_State *L) {
BS_Region * pR = CheckRegion(L);
BS_ASSERT(pR);
@@ -412,8 +376,7 @@ static int R_IsPointInRegion(lua_State * L)
// -----------------------------------------------------------------------------
-static int R_SetPos(lua_State * L)
-{
+static int R_SetPos(::lua_State *L) {
BS_Region * pR = CheckRegion(L);
BS_ASSERT(pR);
@@ -426,8 +389,7 @@ static int R_SetPos(lua_State * L)
// -----------------------------------------------------------------------------
-static int R_SetX(lua_State * L)
-{
+static int R_SetX(::lua_State *L) {
BS_Region * pR = CheckRegion(L);
BS_ASSERT(pR);
@@ -438,8 +400,7 @@ static int R_SetX(lua_State * L)
// -----------------------------------------------------------------------------
-static int R_SetY(lua_State * L)
-{
+static int R_SetY(::lua_State *L) {
BS_Region * pR = CheckRegion(L);
BS_ASSERT(pR);
@@ -450,9 +411,8 @@ static int R_SetY(lua_State * L)
// -----------------------------------------------------------------------------
-static void DrawPolygon(const BS_Polygon & Polygon, unsigned int Color, const BS_Vertex & Offset)
-{
- BS_GraphicEngine * pGE = static_cast<BS_GraphicEngine *>(BS_Kernel::GetInstance()->GetService("gfx"));
+static void DrawPolygon(const BS_Polygon &Polygon, unsigned int Color, const BS_Vertex &Offset) {
+ BS_GraphicEngine *pGE = static_cast<BS_GraphicEngine *>(BS_Kernel::GetInstance()->GetService("gfx"));
BS_ASSERT(pGE);
for (int i = 0; i < Polygon.VertexCount - 1; i++)
@@ -463,8 +423,7 @@ static void DrawPolygon(const BS_Polygon & Polygon, unsigned int Color, const BS
// -----------------------------------------------------------------------------
-static void DrawRegion(const BS_Region & Region, unsigned int Color, const BS_Vertex & Offset)
-{
+static void DrawRegion(const BS_Region &Region, unsigned int Color, const BS_Vertex &Offset) {
DrawPolygon(Region.GetContour(), Color, Offset);
for (int i = 0; i < Region.GetHoleCount(); i++)
DrawPolygon(Region.GetHole(i), Color, Offset);
@@ -472,15 +431,12 @@ static void DrawRegion(const BS_Region & Region, unsigned int Color, const BS_Ve
// -----------------------------------------------------------------------------
-static int R_Draw(lua_State * L)
-{
+static int R_Draw(::lua_State *L) {
BS_Region * pR = CheckRegion(L);
BS_ASSERT(pR);
- switch (lua_gettop(L))
- {
- case 3:
- {
+ switch (lua_gettop(L)) {
+ case 3: {
BS_Vertex Offset;
BS_Vertex::LuaVertexToVertex(L, 3, Offset);
DrawRegion(*pR, BS_GraphicEngine::LuaColorToARGBColor(L, 2), Offset);
@@ -500,8 +456,7 @@ static int R_Draw(lua_State * L)
// -----------------------------------------------------------------------------
-static int R_GetCentroid(lua_State * L)
-{
+static int R_GetCentroid(::lua_State *L) {
BS_Region * RPtr = CheckRegion(L);
BS_ASSERT(RPtr);
@@ -512,8 +467,7 @@ static int R_GetCentroid(lua_State * L)
// -----------------------------------------------------------------------------
-static int R_Delete(lua_State * L)
-{
+static int R_Delete(::lua_State *L) {
BS_Region * pR = CheckRegion(L);
BS_ASSERT(pR);
delete pR;
@@ -522,8 +476,7 @@ static int R_Delete(lua_State * L)
// -----------------------------------------------------------------------------
-static const luaL_reg REGION_METHODS[] =
-{
+static const luaL_reg REGION_METHODS[] = {
"SetPos", R_SetPos,
"SetX", R_SetX,
"SetY", R_SetY,
@@ -539,28 +492,23 @@ static const luaL_reg REGION_METHODS[] =
// -----------------------------------------------------------------------------
-static BS_WalkRegion * CheckWalkRegion(lua_State * L)
-{
- // Der erste Parameter muss vom Typ userdata sein und die Metatable der Klasse Geo.WalkRegion
+static BS_WalkRegion *CheckWalkRegion(::lua_State *L) {
+ // The first parameter must be of type 'userdate', and the Metatable class Geo.WalkRegion
unsigned int RegionHandle;
- if ((RegionHandle = *reinterpret_cast<unsigned int *>(my_checkudata(L, 1, WALKREGION_CLASS_NAME))) != 0)
- {
+ if ((RegionHandle = *reinterpret_cast<unsigned int *>(my_checkudata(L, 1, WALKREGION_CLASS_NAME))) != 0) {
return reinterpret_cast<BS_WalkRegion *>(BS_RegionRegistry::GetInstance().ResolveHandle(RegionHandle));
- }
- else
- {
+ } else {
luaL_argcheck(L, 0, 1, "'" WALKREGION_CLASS_NAME "' expected");
}
- // Compiler ruhigstellen. Ausführung kommt nie an diesem Punkt an.
+ // Compilation fix. Execution never reaches this point
return 0;
}
// -----------------------------------------------------------------------------
-static int WR_GetPath(lua_State * L)
-{
- BS_WalkRegion * pWR = CheckWalkRegion(L);
+static int WR_GetPath(::lua_State *L) {
+ BS_WalkRegion *pWR = CheckWalkRegion(L);
BS_ASSERT(pWR);
BS_Vertex Start;
@@ -568,18 +516,15 @@ static int WR_GetPath(lua_State * L)
BS_Vertex End;
BS_Vertex::LuaVertexToVertex(L, 3, End);
BS_Path Path;
- if (pWR->QueryPath(Start, End, Path))
- {
+ if (pWR->QueryPath(Start, End, Path)) {
lua_newtable(L);
BS_Path::const_iterator it = Path.begin();
- for (; it != Path.end(); it++)
- {
+ for (; it != Path.end(); it++) {
lua_pushnumber(L, (it - Path.begin()) + 1);
BS_Vertex::VertexToLuaVertex(L, *it);
lua_settable(L, -3);
}
- }
- else
+ } else
lua_pushnil(L);
return 1;
@@ -587,21 +532,19 @@ static int WR_GetPath(lua_State * L)
// -----------------------------------------------------------------------------
-static const luaL_reg WALKREGION_METHODS[] =
-{
+static const luaL_reg WALKREGION_METHODS[] = {
"GetPath", WR_GetPath,
0, 0,
};
// -----------------------------------------------------------------------------
-bool BS_Geometry::_RegisterScriptBindings()
-{
+bool BS_Geometry::_RegisterScriptBindings() {
BS_Kernel * pKernel = BS_Kernel::GetInstance();
BS_ASSERT(pKernel);
BS_ScriptEngine * pScript = static_cast<BS_ScriptEngine *>(pKernel->GetService("script"));
BS_ASSERT(pScript);
- lua_State * L = static_cast<lua_State *>(pScript->GetScriptObject());
+ ::lua_State *L = static_cast< ::lua_State *>(pScript->GetScriptObject());
BS_ASSERT(L);
if (!BS_LuaBindhelper::AddMethodsToClass(L, REGION_CLASS_NAME, REGION_METHODS)) return false;
@@ -615,3 +558,5 @@ bool BS_Geometry::_RegisterScriptBindings()
return true;
}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/math/line.h b/engines/sword25/math/line.h
index 3dd178adb5..86bcbd6537 100644
--- a/engines/sword25/math/line.h
+++ b/engines/sword25/math/line.h
@@ -35,11 +35,11 @@
/*
BS_Line
-------
- Diese Klasse enthält nur statische Methoden, die mit Geradensegmenten zu tun haben.
- Es gibt keine wirkliche Geradensegment-Klasse, da diese Klasse vor allem zu
- Berechnungen mit Polygonen herangezogen wird und es dabei wichtig ist, Start- und
- Endpunkte der Linien dynamisch wählen zu können. Dieses würde sich verbieten, wenn
- ein Polygon aus einer Menge von festen Geradensegmenten gebildet wäre.
+ This class contains only static methods, which have to do with straight line
+ segments. There is no real straight line segment class. Calculations will be
+ used with polygons, and it is important the process of starting and selecting
+ endpoints of lines is dynamic. This would prhobit a polygon from a set
+ being formed by fixed line segments
Autor: Malte Thiesen
*/
@@ -55,77 +55,69 @@
// -----------------------------------------------------------------------------
-class BS_Line
-{
+namespace Sword25 {
+
+class BS_Line {
public:
/**
- @brief Bestimmt ob sich ein Punkt links von einer Linie befindet.
- @param a der Startpunkt der Linie
- @param b der Endpunkt der Linie
- @param c der Testpunkt
- @return Gibt true zurück, wenn sich der Punkt links von der Linie befindet.<br>
- Falls sich der Punkt rechts von der Linie oder auf der Linie befindet wird false zurückgegeben.<br>
- @remark Ein Punkt liegt links von einer Linie, wenn er vom Startpunkt aus betrachtet links neben der Linie liegt.
- */
- static bool IsVertexLeft(const BS_Vertex & a, const BS_Vertex & b, const BS_Vertex & c)
- {
+ * Determines whether a piont is left of a line
+ * @param a The start point of a line
+ * @param b The end point of a line
+ * @param c The test point
+ * @return Returns true if the point is to the left of the line.
+ * If the point is to the right of the line or on the line, false is returned.
+ */
+ static bool IsVertexLeft(const BS_Vertex &a, const BS_Vertex &b, const BS_Vertex &c) {
return _TriangleArea2(a, b, c) > 0;
}
- static bool IsVertexLeftOn(const BS_Vertex & a, const BS_Vertex & b, const BS_Vertex & c)
- {
+ static bool IsVertexLeftOn(const BS_Vertex &a, const BS_Vertex &b, const BS_Vertex &c) {
return _TriangleArea2(a, b, c) >= 0;
}
/**
- @brief Bestimmt ob sich ein Punkt rechts von einer Linie befindet.
- @param a der Startpunkt der Linie
- @param b der Endpunkt der Linie
- @param c der Testpunkt
- @return Gibt true zurück, wenn sich der Punkt recht von der Linie befindet.<br>
- Falls sich der Punkt links von der Linie oder auf der Linie befindet wird false zurückgegeben.<br>
- @remark Ein Punkt liegt rechts von einer Linie, wenn er vom Startpunkt aus betrachtet rechts neben der Linie liegt.
- */
- static bool IsVertexRight(const BS_Vertex & a, const BS_Vertex & b, const BS_Vertex & c)
- {
+ * Determines whether a piont is right of a line
+ * @param a The start point of a line
+ * @param b The end point of a line
+ * @param c The test point
+ * @return Returns true if the point is to the right of the line.
+ * If the point is to the right of the line or on the line, false is returned.
+ */
+ static bool IsVertexRight(const BS_Vertex &a, const BS_Vertex &b, const BS_Vertex &c) {
return _TriangleArea2(a, b, c) < 0;
}
- static bool IsVertexRightOn(const BS_Vertex & a, const BS_Vertex & b, const BS_Vertex & c)
- {
+ static bool IsVertexRightOn(const BS_Vertex &a, const BS_Vertex &b, const BS_Vertex &c) {
return _TriangleArea2(a, b, c) <= 0;
}
/**
- @brief Bestimmt ob sich ein Punkt auf einer Linie befindet.
- @param a der Startpunkt der Linie
- @param b der Endpunkt der Linie
- @param c der Testpunkt
- @return Gibt true zurück, wenn sich der Punkt auf der Linie befindet.
- */
- static bool IsVertexOn(const BS_Vertex & a, const BS_Vertex & b, const BS_Vertex & c)
- {
+ * Determines whether a piont is on a line
+ * @param a The start point of a line
+ * @param b The end point of a line
+ * @param c The test point
+ * @return Returns true if the point is on the line, false otherwise.
+ */
+ static bool IsVertexOn(const BS_Vertex &a, const BS_Vertex &b, const BS_Vertex &c) {
return _TriangleArea2(a, b, c) == 0;
}
- enum VERTEX_CLASSIFICATION
- {
+ enum VERTEX_CLASSIFICATION {
LEFT,
RIGHT,
ON
};
/**
- @brief Bestimmt wo sich ein Punkt relativ zu einer Linie befindet.
- @param a der Startpunkt der Linie
- @param b der Endpunkt der Linie
- @param c der Testpunkt
- @return Gibt LEFT zurück, wenn sich der Punkt links von der Line befindet.<br>
- Gibt RIGHT zurück, wenn sich der Punkt links von der Line befindet.<br>
- Gibt ON zurück, wenn sich der Punkt auf der Linie befindet.
- */
- static VERTEX_CLASSIFICATION ClassifyVertexToLine(const BS_Vertex & a, const BS_Vertex & b, const BS_Vertex & c)
- {
+ * Determines where a point is relative to a line.
+ * @param a The start point of a line
+ * @param b The end point of a line
+ * @param c The test point
+ * @return LEFT is returned if the point is to the left of the line.
+ * RIGHT is returned if the point is to the right of the line.
+ * ON is returned if the point is on the line.
+ */
+ static VERTEX_CLASSIFICATION ClassifyVertexToLine(const BS_Vertex &a, const BS_Vertex &b, const BS_Vertex &c) {
int Area = _TriangleArea2(a, b, c);
if (Area > 0) return LEFT;
if (Area < 0) return RIGHT;
@@ -133,15 +125,14 @@ public:
}
/**
- @brief Bestimmt ob sich zwei Linien schneiden.
- @param a der Startpunkt der ersten Linie
- @param b der Endpunkt der ersten Linie
- @param c der Startpunkt der zweiten Linie
- @param d der Endpunkt der zweiten Linie
- @remark In den Fällen in denen eine Linie die andere nur berührt, wird false zurückgegeben (improper intersection).
- */
- static bool DoesIntersectProperly(const BS_Vertex & a, const BS_Vertex & b, const BS_Vertex & c, const BS_Vertex & d)
- {
+ * Determines whether two lines intersect
+ * @param a The start point of the first line
+ * @param b The end point of the first line
+ * @param c The start point of the second line
+ * @param d The end point of the second line
+ * @remark In cases where a line only touches the other, false is returned (improper intersection)
+ */
+ static bool DoesIntersectProperly(const BS_Vertex &a, const BS_Vertex &b, const BS_Vertex &c, const BS_Vertex &d) {
VERTEX_CLASSIFICATION Class1 = ClassifyVertexToLine(a, b, c);
VERTEX_CLASSIFICATION Class2 = ClassifyVertexToLine(a, b, d);
VERTEX_CLASSIFICATION Class3 = ClassifyVertexToLine(c, d, a);
@@ -153,26 +144,22 @@ public:
}
/**
- @brief Bestimmt ob sich ein Punkt auf einem Liniensegment befindet
- @param a der Startpunkt der Liniensegmentes
- @param b der Endpunkt der Liniensegmentes
- @param c der Testpunkt
- */
- static bool IsOnLine(const BS_Vertex & a, const BS_Vertex & b, const BS_Vertex & c)
- {
- // Die Punkte müssen alle Kollinear sein, sonst liegt der Testpunkt nicht auf dem Liniensegment
+ * Determines whether a point is on a line segment
+ * @param a The start point of a line
+ * @param b The end point of a line
+ * @param c The test point
+ */
+ static bool IsOnLine(const BS_Vertex &a, const BS_Vertex &b, const BS_Vertex &c) {
+ // The items must all be Collinear, otherwise don't bothering testing the point
if (_TriangleArea2(a, b, c) != 0) return false;
- // Falls das Liniensegment nicht vertikal ist prüfe auf der X-Achse, ansonsten auf der Y-Achse
- if (a.X != b.X)
- {
+ // If the line segment is not vertical, check on the x-axis, otherwise the y-axis
+ if (a.X != b.X) {
return ((a.X <= c.X) &&
(c.X <= b.X)) ||
((a.X >= c.X) &&
(c.X >= b.X));
- }
- else
- {
+ } else {
return ((a.Y <= c.Y) &&
(c.Y <= b.Y)) ||
((a.Y >= c.Y) &&
@@ -180,21 +167,17 @@ public:
}
}
- static bool IsOnLineStrict(const BS_Vertex & a, const BS_Vertex & b, const BS_Vertex & c)
- {
- // Die Punkte müssen alle Kollinear sein, sonst liegt der Testpunkt nicht auf dem Liniensegment
+ static bool IsOnLineStrict(const BS_Vertex &a, const BS_Vertex &b, const BS_Vertex &c) {
+ // The items must all be Collinear, otherwise don't bothering testing the point
if (_TriangleArea2(a, b, c) != 0) return false;
- // Falls das Liniensegment nicht vertikal ist prüfe auf der X-Achse, ansonsten auf der Y-Achse
- if (a.X != b.X)
- {
+ // If the line segment is not vertical, check on the x-axis, otherwise the y-axis
+ if (a.X != b.X) {
return ((a.X < c.X) &&
(c.X < b.X)) ||
((a.X > c.X) &&
(c.X > b.X));
- }
- else
- {
+ } else {
return ((a.Y < c.Y) &&
(c.Y < b.Y)) ||
((a.Y > c.Y) &&
@@ -203,19 +186,19 @@ public:
}
private:
-
/**
- @brief Gibt die doppelte Größe des durch a, b und c definierten Dreiecks zurück.
-
- Das Ergebnis ist positiv wenn die Punkte entgegen dem Uhrzeigersinn angeordnet sind und negativ wenn sie mit dem
- Uhrzeigersinn angeordnet sind.
- */
- static int _TriangleArea2(const BS_Vertex & a, const BS_Vertex & b, const BS_Vertex & c)
- {
+ * Return double the size of the triangle defined by the three passed points.
+ *
+ * The result is positive if the points are arrange counterclockwise,
+ * and negative if they are arranged counter-clockwise.
+ */
+ static int _TriangleArea2(const BS_Vertex &a, const BS_Vertex &b, const BS_Vertex &c) {
return a.X * b.Y - a.Y * b.X +
a.Y * c.X - a.X * c.Y +
b.X * c.Y - c.X * b.Y;
}
};
+} // End of namespace Sword25
+
#endif
diff --git a/engines/sword25/math/polygon.cpp b/engines/sword25/math/polygon.cpp
index ab5ce0d96d..6d416ea080 100644
--- a/engines/sword25/math/polygon.cpp
+++ b/engines/sword25/math/polygon.cpp
@@ -32,11 +32,6 @@
*
*/
-#include "sword25/kernel/memlog_off.h"
-#include <utility>
-#include <vector>
-#include "sword25/kernel/memlog_on.h"
-
#include <math.h>
#include "sword25/kernel/outputpersistenceblock.h"
@@ -45,58 +40,52 @@
#include "sword25/math/polygon.h"
#include "sword25/math/line.h"
+namespace Sword25 {
+
#define max(a,b) (((a) > (b)) ? (a) : (b))
-// Konstruktion / Destruktion
+// Constructor / Destructor
// --------------------------
-BS_Polygon::BS_Polygon() : VertexCount(0), Vertecies(NULL)
-{
+BS_Polygon::BS_Polygon() : VertexCount(0), Vertecies(NULL) {
}
-BS_Polygon::BS_Polygon(int VertexCount, const BS_Vertex* Vertecies) : VertexCount(0), Vertecies(NULL)
-{
+BS_Polygon::BS_Polygon(int VertexCount, const BS_Vertex *Vertecies) : VertexCount(0), Vertecies(NULL) {
Init(VertexCount, Vertecies);
}
-BS_Polygon::BS_Polygon(const BS_Polygon& Other) : VertexCount(0), Vertecies(NULL)
-{
+BS_Polygon::BS_Polygon(const BS_Polygon &Other) : VertexCount(0), Vertecies(NULL) {
Init(Other.VertexCount, Other.Vertecies);
}
-BS_Polygon::BS_Polygon(BS_InputPersistenceBlock & Reader) : VertexCount(0), Vertecies(NULL)
-{
+BS_Polygon::BS_Polygon(BS_InputPersistenceBlock &Reader) : VertexCount(0), Vertecies(NULL) {
Unpersist(Reader);
}
-BS_Polygon::~BS_Polygon()
-{
+BS_Polygon::~BS_Polygon() {
delete[] Vertecies;
}
-// Initialisierung
+// Initialisation
// ---------------
-bool BS_Polygon::Init(int VertexCount, const BS_Vertex* Vertecies)
-{
- // Alten Objektzustand merken um ihn wieder herstellen zu können, falls beim Initialisieren mit den neuen Daten ein Fehler auftreten
- // sollte.
+bool BS_Polygon::Init(int VertexCount, const BS_Vertex *Vertecies) {
+ // Rember the old obstate to restore it if an error occurs whilst initialising it with the new data
int OldVertexCount = this->VertexCount;
- BS_Vertex* OldVertecies = this->Vertecies;
+ BS_Vertex *OldVertecies = this->Vertecies;
this->VertexCount = VertexCount;
this->Vertecies = new BS_Vertex[VertexCount + 1];
memcpy(this->Vertecies, Vertecies, sizeof(BS_Vertex) * VertexCount);
// TODO:
- // Doppelte und überflüssige Vertecies entfernen (überflüssig = 3 Verts kollinear)
+ // Duplicate and remove redundant vertecies (Superflous = 3 co-linear verts)
// _WeedRepeatedVertecies();
- // Das erste Vertex wird am Ende des Vertex-Arrays wiederholt, dieses vereinfacht einige Algorithmen, die alle Edges durchgehen und
- // sich so die Überlaufkontrolle sparen können.
+ // The first vertex is repeated at the end of the vertex array; this simplifies
+ // some algorithms, running through the edges and thus can save the overflow control.
this->Vertecies[VertexCount] = this->Vertecies[0];
- // Falls das Polygon selbstüberschneidend ist, wird der alte Objektzustand wieder hergestellt und ein Fehler signalisiert.
- if (CheckForSelfIntersection())
- {
+ // If the polygon is self-intersecting, the object state is restore, and an error signalled
+ if (CheckForSelfIntersection()) {
delete[] this->Vertecies;
this->Vertecies = OldVertecies;
this->VertexCount = OldVertexCount;
@@ -105,10 +94,10 @@ bool BS_Polygon::Init(int VertexCount, const BS_Vertex* Vertecies)
return false;
}
- // Alte Vertexliste freigeben
+ // Release old vertex list
delete[] OldVertecies;
- // Eigenschaften des Polygons berechnen.
+ // Calculate properties of the polygon
m_IsCW = ComputeIsCW();
m_IsConvex = ComputeIsConvex();
m_Centroid = ComputeCentroid();
@@ -116,52 +105,44 @@ bool BS_Polygon::Init(int VertexCount, const BS_Vertex* Vertecies)
return true;
}
-// Überprüfung der Reihenfolge der Vertecies
-// -----------------------------------------
+// Review the order of the Vertecies
+// ---------------------------------
-bool BS_Polygon::IsCW() const
-{
+bool BS_Polygon::IsCW() const {
return m_IsCW;
}
-bool BS_Polygon::IsCCW() const
-{
+bool BS_Polygon::IsCCW() const {
return !IsCW();
}
-bool BS_Polygon::ComputeIsCW() const
-{
- if (VertexCount)
- {
- // Vertex finden, dass am weitesten rechts unten liegt.
+bool BS_Polygon::ComputeIsCW() const {
+ if (VertexCount) {
+ // Find the vertex on extreme bottom right
int V2Index = FindLRVertexIndex();
- // Vertex vorher und nachher finden.
+ // Find the vertex before and after it
int V1Index = (V2Index + (VertexCount - 1)) % VertexCount;
int V3Index = (V2Index + 1) % VertexCount;
- // Kreuzprodukt bilden.
- // Wenn das Kreuzprodukt des am weitesten unten links liegenden Vertex positiv ist, sind die Vertecies im Uhrzeigersinn angeordnet
- // ansonsten entgegen des Uhrzeigersinns.
+ // Cross product form
+ // If the cross product of the vertex lying fartherest bottom left is positive,
+ // the vertecies arrranged in a clockwise order. Otherwise counter-clockwise
if (CrossProduct(Vertecies[V1Index], Vertecies[V2Index], Vertecies[V3Index]) >= 0) return true;
}
return false;
}
-int BS_Polygon::FindLRVertexIndex() const
-{
- if (VertexCount)
- {
+int BS_Polygon::FindLRVertexIndex() const {
+ if (VertexCount) {
int CurIndex = 0;
int MaxX = Vertecies[0].X;
int MaxY = Vertecies[0].Y;
- for (int i = 1; i < VertexCount; i++)
- {
+ for (int i = 1; i < VertexCount; i++) {
if (Vertecies[i].Y > MaxY ||
- (Vertecies[i].Y == MaxY && Vertecies[i].X > MaxX))
- {
+ (Vertecies[i].Y == MaxY && Vertecies[i].X > MaxX)) {
MaxX = Vertecies[i].X;
MaxY = Vertecies[i].Y;
CurIndex = i;
@@ -174,109 +155,101 @@ int BS_Polygon::FindLRVertexIndex() const
return -1;
}
-// Testen auf Konvex/Konkav
+// Testing for Convex / Concave
// ------------------------
-bool BS_Polygon::IsConvex() const
-{
+bool BS_Polygon::IsConvex() const {
return m_IsConvex;
}
-bool BS_Polygon::IsConcave() const
-{
+bool BS_Polygon::IsConcave() const {
return !IsConvex();
}
-bool BS_Polygon::ComputeIsConvex() const
-{
- // Polygone mit 3 oder weniger Vertecies können nur Konvex sein.
+bool BS_Polygon::ComputeIsConvex() const {
+ // Polygons with three or less Vertecies can only be convex
if (VertexCount <= 3) return true;
- // Alle Winkel im Polygon berechnen, wenn das Polygon Konvex ist, müssen alle Winkel das selbe Vorzeichen haben.
+ // All angles in the polygon computed will have the same direction sign if the polygon is convex
int Flag = 0;
- for (int i = 0; i < VertexCount; i++)
- {
- // Die Indizies der beiden nächsten Vertecies nach i bestimmen.
+ for (int i = 0; i < VertexCount; i++) {
+ // Determine the next two vertecies to check
int j = (i + 1) % VertexCount;
int k = (i + 2) % VertexCount;
- // Kreuzprodukt der drei Vertecies berechnen.
+ // Calculate the cross product of the three vertecies
int Cross = CrossProduct(Vertecies[i], Vertecies[j], Vertecies[k]);
- // Die unteren beiden Bits von Flag haben folgende Bedeutung:
- // 0 : negativer Winkel ist aufgetreten
- // 1 : positiver Winkel ist aufgetreten
+ // The lower two bits of the flag represent the following:
+ // 0: negative angle occurred
+ // 1: positive angle occurred
- // Vorzeichen des aktuellen Winkels in Flag vermerken.
+ // The sign of the current angle is recorded in Flag
if (Cross < 0)
Flag |= 1;
else if (Cross > 0)
Flag |= 2;
- // Falls Flag 3 ist, sind sowohl positive als auch negative Winkel vorhanden -> Polygon ist Konkav.
+ // If flag is 3, there are both positive and negative angles; so the polygon is concave
if (Flag == 3) return false;
}
- // Polygon ist Konvex.
+ // Polygon is convex
return true;
}
-// Sicherstellen einer bestimmen Vertexordnung
-// -------------------------------------------
+// Make a determine vertex order
+// -----------------------------
-void BS_Polygon::EnsureCWOrder()
-{
+void BS_Polygon::EnsureCWOrder() {
if (!IsCW())
ReverseVertexOrder();
}
-void BS_Polygon::EnsureCCWOrder()
-{
+void BS_Polygon::EnsureCCWOrder() {
if (!IsCCW())
ReverseVertexOrder();
}
-// Umkehren der Reihenfolge der Vertecies
-// --------------------------------------
+// Reverse the order of vertecies
+// ------------------------------
-void BS_Polygon::ReverseVertexOrder()
-{
- // Vertecies paarweise vertauschen, bis die Liste komplett umgekehrt wurde.
- for (int i = 0; i < VertexCount / 2; i++)
- std::swap(Vertecies[i], Vertecies[VertexCount - i - 1]);
+void BS_Polygon::ReverseVertexOrder() {
+ // Vertecies are exchanged in pairs, until the list has been completely reversed
+ for (int i = 0; i < VertexCount / 2; i++) {
+ BS_Vertex tempVertex = Vertecies[i];
+ Vertecies[i] = Vertecies[VertexCount - i - 1];
+ Vertecies[VertexCount - i - 1] = tempVertex;
+ }
// Vertexordnung neu berechnen.
m_IsCW = ComputeIsCW();
}
-// Kreuzprodukt
-// ------------
+// Cross Product
+// -------------
-int BS_Polygon::CrossProduct(const BS_Vertex& V1, const BS_Vertex& V2, const BS_Vertex& V3) const
-{
+int BS_Polygon::CrossProduct(const BS_Vertex &V1, const BS_Vertex &V2, const BS_Vertex &V3) const {
return (V2.X - V1.X) * (V3.Y - V2.Y) -
(V2.Y - V1.Y) * (V3.X - V2.X);
}
-// Skalarproduct
-// -------------
+// Scalar Product
+// --------------
-int BS_Polygon::DotProduct(const BS_Vertex& V1, const BS_Vertex& V2, const BS_Vertex& V3) const
-{
+int BS_Polygon::DotProduct(const BS_Vertex &V1, const BS_Vertex &V2, const BS_Vertex &V3) const {
return (V1.X - V2.X) * (V3.X - V2.X) +
(V1.Y - V2.Y) * (V3.X - V2.Y);
}
-// Überprüfen auf Selbstüberschneidung
-// -----------------------------------
+// Check for self-intersections
+// ----------------------------
-bool BS_Polygon::CheckForSelfIntersection() const
-{
- // TODO: Fertigstellen
+bool BS_Polygon::CheckForSelfIntersection() const {
+ // TODO: Finish this
/*
float AngleSum = 0.0f;
- for (int i = 0; i < VertexCount; i++)
- {
+ for (int i = 0; i < VertexCount; i++) {
int j = (i + 1) % VertexCount;
int k = (i + 2) % VertexCount;
@@ -289,8 +262,7 @@ bool BS_Polygon::CheckForSelfIntersection() const
(Vertecies[k].Y - Vertecies[j].Y) * (Vertecies[k].Y - Vertecies[j].Y));
float Norm = Length1 * Length2;
- if (Norm > 0.0f)
- {
+ if (Norm > 0.0f) {
Dot /= Norm;
AngleSum += acos(Dot);
}
@@ -300,46 +272,43 @@ bool BS_Polygon::CheckForSelfIntersection() const
return false;
}
-// Verschieben
-// -----------
+// Move
+// ----
-void BS_Polygon::operator+=(const BS_Vertex& Delta)
-{
- // Alle Vetecies verschieben
+void BS_Polygon::operator+=(const BS_Vertex &Delta) {
+ // Move all vertecies
for (int i = 0; i < VertexCount; i++)
Vertecies[i] += Delta;
- // Den Schwerpunkt verschieben.
+ // Shift the focus
m_Centroid += Delta;
}
-// Sichtlinie
-// ----------
+// Line of Sight
+// -------------
-bool BS_Polygon::IsLineInterior(const BS_Vertex & a, const BS_Vertex & b) const
-{
- // Beide Punkte müssen im Polygon sein
+bool BS_Polygon::IsLineInterior(const BS_Vertex &a, const BS_Vertex &b) const {
+ // Both points have to be in the polygon
if (!IsPointInPolygon(a, true) || !IsPointInPolygon(b, true)) return false;
- // Falls die Punkte identisch sind, ist die Linie trivialerweise innerhalb des Polygons
+ // If the points are identical, the line is trivially within the polygon
if (a == b) return true;
- // Testen, ob die Linie ein Liniensegment strikt schneidet (proper intersection)
- for (int i = 0; i < VertexCount; i++)
- {
+ // Test whether the line intersects a line segment strictly (proper intersection)
+ for (int i = 0; i < VertexCount; i++) {
int j = (i + 1) % VertexCount;
- const BS_Vertex & VS = Vertecies[i];
- const BS_Vertex & VE = Vertecies[j];
+ const BS_Vertex &VS = Vertecies[i];
+ const BS_Vertex &VE = Vertecies[j];
- // Falls die Linie ein Liniensegment strikt schneidet (proper intersection) ist die Linie nicht innerhalb des Polygons
+ // If the line intersects a line segment strictly (proper cross section) the line is not in the polygon
if (BS_Line::DoesIntersectProperly(a, b, VS, VE)) return false;
- // Falls einer der beiden Linienpunkte auf der Kante liegt und der andere rechts der Kante liegt, befindet sich die Linie nicht
- // vollständig innerhalb des Polygons.
+ // If one of the two line items is on the edge and the other is to the right of the edge,
+ // then the line is not completely within the polygon
if (BS_Line::IsOnLineStrict(VS, VE, a) && BS_Line::IsVertexRight(VS, VE, b)) return false;
if (BS_Line::IsOnLineStrict(VS, VE, b) && BS_Line::IsVertexRight(VS, VE, a)) return false;
- // Falls einer der beiden Linienpunkte auf einem Vertex liegt muss die Linie in das Polygon hinein verlaufen
+ // If one of the two line items is on a vertex, the line traces into the polygon
if ((a == VS) && !IsLineInCone(i, b, true)) return false;
if ((b == VS) && !IsLineInCone(i, a, true)) return false;
}
@@ -347,37 +316,34 @@ bool BS_Polygon::IsLineInterior(const BS_Vertex & a, const BS_Vertex & b) const
return true;
}
-bool BS_Polygon::IsLineExterior(const BS_Vertex & a, const BS_Vertex & b) const
-{
- // Keiner der beiden Punkte darf strikt im Polygon sein (auf der Kante ist erlaubt)
+bool BS_Polygon::IsLineExterior(const BS_Vertex &a, const BS_Vertex &b) const {
+ // Neither of the two points must be strictly in the polygon (on the edge is allowed)
if (IsPointInPolygon(a, false) || IsPointInPolygon(b, false)) return false;
- // Falls die Punkte identisch sind, ist die Linie trivialerweise ausserhalb des Polygons
+ // If the points are identical, the line is trivially outside of the polygon
if (a == b) return true;
- // Testen, ob die Linie ein Liniensegment strikt schneidet (proper intersection)
- for (int i = 0; i < VertexCount; i++)
- {
+ // Test whether the line intersects a line segment strictly (proper intersection)
+ for (int i = 0; i < VertexCount; i++) {
int j = (i + 1) % VertexCount;
- const BS_Vertex & VS = Vertecies[i];
- const BS_Vertex & VE = Vertecies[j];
+ const BS_Vertex &VS = Vertecies[i];
+ const BS_Vertex &VE = Vertecies[j];
- // Falls die Linie ein Liniensegment strikt schneidet (proper intersection) ist die Linie teilweise innerhalb des Polygons
+ // If the line intersects a line segment strictly (proper intersection), then
+ // the line is partially inside the polygon
if (BS_Line::DoesIntersectProperly(a, b, VS, VE)) return false;
- // Falls einer der beiden Linienpunkte auf der Kante liegt und der andere rechts der Kante liegt, befindet sich die Linie nicht vollständig
- // ausserhalb des Polygons.
+ // If one of the two line items is on the edge and the other is to the right of the edge,
+ // the line is not completely outside the polygon
if (BS_Line::IsOnLineStrict(VS, VE, a) && BS_Line::IsVertexLeft(VS, VE, b)) return false;
if (BS_Line::IsOnLineStrict(VS, VE, b) && BS_Line::IsVertexLeft(VS, VE, a)) return false;
- // Falls einer der beiden Linienpunkte auf einem Vertex liegt, darf die Linie nicht in das Polygon hinein verlaufen
+ // If one of the lwo line items is on a vertex, the line must not run into the polygon
if ((a == VS) && IsLineInCone(i, b, false)) return false;
if ((b == VS) && IsLineInCone(i, a, false)) return false;
- // Falls das Vertex mit Start- und Zielpunkt kollinear ist, dürfen die beiden Liniensegmente (a, VS) und (b, VS) nicht in das Polygon hinein
- // verlaufen
- if (BS_Line::IsOnLine(a, b, VS))
- {
+ // If the vertex with start and end point is collinear, (a VS) and (b, VS) is not in the polygon
+ if (BS_Line::IsOnLine(a, b, VS)) {
if (IsLineInCone(i, a, false)) return false;
if (IsLineInCone(i, b, false)) return false;
}
@@ -386,23 +352,19 @@ bool BS_Polygon::IsLineExterior(const BS_Vertex & a, const BS_Vertex & b) const
return true;
}
-bool BS_Polygon::IsLineInCone(int StartVertexIndex, const BS_Vertex & EndVertex, bool IncludeEdges) const
-{
- const BS_Vertex & StartVertex = Vertecies[StartVertexIndex];
- const BS_Vertex & NextVertex = Vertecies[(StartVertexIndex + 1) % VertexCount];
- const BS_Vertex & PrevVertex = Vertecies[(StartVertexIndex + VertexCount - 1) % VertexCount];
+bool BS_Polygon::IsLineInCone(int StartVertexIndex, const BS_Vertex &EndVertex, bool IncludeEdges) const {
+ const BS_Vertex &StartVertex = Vertecies[StartVertexIndex];
+ const BS_Vertex &NextVertex = Vertecies[(StartVertexIndex + 1) % VertexCount];
+ const BS_Vertex &PrevVertex = Vertecies[(StartVertexIndex + VertexCount - 1) % VertexCount];
- if (BS_Line::IsVertexLeftOn(PrevVertex, StartVertex, NextVertex))
- {
+ if (BS_Line::IsVertexLeftOn(PrevVertex, StartVertex, NextVertex)) {
if (IncludeEdges)
return BS_Line::IsVertexLeftOn(EndVertex, StartVertex, NextVertex) &&
BS_Line::IsVertexLeftOn(StartVertex, EndVertex, PrevVertex);
else
return BS_Line::IsVertexLeft(EndVertex, StartVertex, NextVertex) &&
BS_Line::IsVertexLeft(StartVertex, EndVertex, PrevVertex);
- }
- else
- {
+ } else {
if (IncludeEdges)
return !(BS_Line::IsVertexLeft(EndVertex, StartVertex, PrevVertex) &&
BS_Line::IsVertexLeft(StartVertex, EndVertex, NextVertex));
@@ -412,56 +374,49 @@ bool BS_Polygon::IsLineInCone(int StartVertexIndex, const BS_Vertex & EndVertex,
}
}
-// Punkt-Polygon Tests
+// Point-Polygon Tests
// -------------------
-bool BS_Polygon::IsPointInPolygon(int X, int Y, bool BorderBelongsToPolygon) const
-{
+bool BS_Polygon::IsPointInPolygon(int X, int Y, bool BorderBelongsToPolygon) const {
return IsPointInPolygon(BS_Vertex(X, Y), BorderBelongsToPolygon);
}
-bool BS_Polygon::IsPointInPolygon(const BS_Vertex & Point, bool EdgesBelongToPolygon) const
-{
- int Rcross = 0; // Anzahl der rechtsseitigen Überschneidungen
- int Lcross = 0; // Anzahl der linksseitigen Überschneidungen
+bool BS_Polygon::IsPointInPolygon(const BS_Vertex &Point, bool EdgesBelongToPolygon) const {
+ int Rcross = 0; // Number of right-side overlaps
+ int Lcross = 0; // Number of left-side overlaps
- // Jede Kante wird überprüft ob sie den vom Punkt ausgehenden Strahl schneidet
- for (int i = 0; i < VertexCount; i++)
- {
- const BS_Vertex & EdgeStart = Vertecies[i];
- const BS_Vertex & EdgeEnd = Vertecies[(i + 1) % VertexCount];
+ // Each edge is checked whether it cuts the outgoing stream from the point
+ for (int i = 0; i < VertexCount; i++) {
+ const BS_Vertex &EdgeStart = Vertecies[i];
+ const BS_Vertex &EdgeEnd = Vertecies[(i + 1) % VertexCount];
- // Ist der Punkt ein Vertex? Dann liegt er auf einer Kante des Polygons
+ // A vertex is a point? Then it lies on one edge of the polygon
if (Point == EdgeStart) return EdgesBelongToPolygon;
- if ((EdgeStart.Y > Point.Y) != (EdgeEnd.Y > Point.Y))
- {
+ if ((EdgeStart.Y > Point.Y) != (EdgeEnd.Y > Point.Y)) {
int Term1 = (EdgeStart.X - Point.X) * (EdgeEnd.Y - Point.Y) - (EdgeEnd.X - Point.X) * (EdgeStart.Y - Point.Y);
int Term2 = (EdgeEnd.Y - Point.Y) - (EdgeStart.Y - EdgeEnd.Y);
if ((Term1 > 0) == (Term2 >= 0)) Rcross++;
}
- if ((EdgeStart.Y < Point.Y) != (EdgeEnd.Y < Point.Y))
- {
+ if ((EdgeStart.Y < Point.Y) != (EdgeEnd.Y < Point.Y)) {
int Term1 = (EdgeStart.X - Point.X) * (EdgeEnd.Y - Point.Y) - (EdgeEnd.X - Point.X) * (EdgeStart.Y - Point.Y);
int Term2 = (EdgeEnd.Y - Point.Y) - (EdgeStart.Y - EdgeEnd.Y);
if ((Term1 < 0) == (Term2 <= 0)) Lcross++;
}
}
- // Der Punkt befindet sich auf einer Kante, wenn die Anzahl der linken und rechten Überschneidungen nicht die gleiche Geradzahligkeit haben
+ // The point is on an adge, if the number of left and right intersections have the same even numbers
if ((Rcross % 2 ) != (Lcross % 2 )) return EdgesBelongToPolygon;
- // Der Punkt befindet sich genau dann strikt innerhalb des Polygons, wenn die Anzahl der Überschneidungen ungerade ist
+ // The point is strictly inside the polygon if and only if the number of overlaps is odd
if ((Rcross % 2) == 1) return true;
else return false;
}
-bool BS_Polygon::Persist(BS_OutputPersistenceBlock & Writer)
-{
+bool BS_Polygon::Persist(BS_OutputPersistenceBlock &Writer) {
Writer.Write(VertexCount);
- for (int i = 0; i < VertexCount; ++i)
- {
+ for (int i = 0; i < VertexCount; ++i) {
Writer.Write(Vertecies[i].X);
Writer.Write(Vertecies[i].Y);
}
@@ -469,16 +424,16 @@ bool BS_Polygon::Persist(BS_OutputPersistenceBlock & Writer)
return true;
}
-bool BS_Polygon::Unpersist(BS_InputPersistenceBlock & Reader)
-{
+bool BS_Polygon::Unpersist(BS_InputPersistenceBlock &Reader) {
int StoredVertexCount;
Reader.Read(StoredVertexCount);
- std::vector<BS_Vertex> StoredVertecies(StoredVertexCount);
- for (int i = 0; i < StoredVertexCount; ++i)
- {
- Reader.Read(StoredVertecies[i].X);
- Reader.Read(StoredVertecies[i].Y);
+ Common::Array<BS_Vertex> StoredVertecies;
+ for (int i = 0; i < StoredVertexCount; ++i) {
+ int x, y;
+ Reader.Read(x);
+ Reader.Read(y);
+ StoredVertecies.push_back(BS_Vertex(x, y));
}
Init(StoredVertexCount, &StoredVertecies[0]);
@@ -486,30 +441,26 @@ bool BS_Polygon::Unpersist(BS_InputPersistenceBlock & Reader)
return Reader.IsGood();
}
-// Schwerpunkt
-// -----------
+// Main Focus
+// ----------
-BS_Vertex BS_Polygon::GetCentroid() const
-{
+BS_Vertex BS_Polygon::GetCentroid() const {
return m_Centroid;
}
-BS_Vertex BS_Polygon::ComputeCentroid() const
-{
- // Flächeninhalt des Polygons berechnen.
+BS_Vertex BS_Polygon::ComputeCentroid() const {
+ // Area of the polygon is calculated
int DoubleArea = 0;
- for (int i = 0; i < VertexCount; ++i)
- {
+ for (int i = 0; i < VertexCount; ++i) {
DoubleArea += Vertecies[i].X * Vertecies[i + 1].Y - Vertecies[i + 1].X * Vertecies[i].Y;
}
- // Division durch 0 beim nächsten Schritt vermeiden.
+ // Avoid division by zero in the next step
if (DoubleArea == 0) return BS_Vertex();
- // Schwerpunkt berechnen.
+ // Calculate centroid
BS_Vertex Centroid;
- for (int i = 0; i < VertexCount; ++i)
- {
+ for (int i = 0; i < VertexCount; ++i) {
int Area = Vertecies[i].X * Vertecies[i + 1].Y - Vertecies[i + 1].X * Vertecies[i].Y;
Centroid.X += (Vertecies[i].X + Vertecies[i + 1].X) * Area;
Centroid.Y += (Vertecies[i].Y + Vertecies[i + 1].Y) * Area;
@@ -519,3 +470,5 @@ BS_Vertex BS_Polygon::ComputeCentroid() const
return Centroid;
}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/math/polygon.h b/engines/sword25/math/polygon.h
index 73de386917..d435c9746b 100644
--- a/engines/sword25/math/polygon.h
+++ b/engines/sword25/math/polygon.h
@@ -40,6 +40,8 @@
#include "sword25/kernel/persistable.h"
#include "sword25/math/vertex.h"
+namespace Sword25 {
+
// -----------------------------------------------------------------------------
// Forward Declarations
// -----------------------------------------------------------------------------
@@ -49,158 +51,151 @@ class BS_Vertex;
/**
@brief Eine Polygonklasse.
*/
-class BS_Polygon : public BS_Persistable
-{
+class BS_Polygon : public BS_Persistable {
public:
/**
- @brief Erzeugt ein Objekt vom Typ #BS_Polygon, das 0 Vertecies enthält.
-
- Mit der Methode Init() können dem Polygon später Vertecies hinzugefügt werden.
- */
+ * Creates an object of type #BS_Polygon, containing 0 Vertecies.
+ *
+ * With the method Init(), Vertices can be added in later
+ */
BS_Polygon();
/**
- @brief Copy-Constructor
- */
- BS_Polygon(const BS_Polygon& Other);
+ * Copy constructor
+ */
+ BS_Polygon(const BS_Polygon &Other);
/**
- @brief Erstellt ein Polygon anhand persistierter Daten.
- */
- BS_Polygon(BS_InputPersistenceBlock & Reader);
+ * Creates a polygon using persisted data
+ */
+ BS_Polygon(BS_InputPersistenceBlock &Reader);
/**
- @brief Erzeugt ein Objekt vom Typ #BS_Polygon und ordnet ihm Vertecies zu.
- @param VertexCount die Anzahl der Vertecies im Vertex Array.
- @param Vertecies ein Array, das Objekte vom Typ BS_Vertex enthält, die die Vertecies des Polygons darstellen.
- @remark Die Vertecies müssen ein nicht selbstüberschneidendes Polygon definieren.
- Falls das Polygon selbstüberschneidend sein sollte wird ein leeres BS_Polygon Objekt erzeugt.
- */
- BS_Polygon(int VertexCount, const BS_Vertex* Vertecies);
+ * Creaes an object of type #BS_Polygon, and assigns Vertices to it
+ * @param VertexCount The number of vertices being passed
+ * @param Vertecies An array of BS_Vertex objects representing the vertices in the polygon.
+ * @remark The Vertecies that define a polygon must not have any self-intersections.
+ * If the polygon does have self-intersections, then an empty polygon object is created.
+ */
+ BS_Polygon(int VertexCount, const BS_Vertex *Vertecies);
/**
- @brief Löscht das BS_Polygon Objekt.
- */
+ * Deletes the BS_Polygon object
+ */
virtual ~BS_Polygon();
/**
- @brief Initialisiert das BS_Polygon mit einer Liste von Vertecies.
-
- Die Vertecies müssen ein nicht selbstüberschneidendes Polygon definieren.
- Es kann auch einem Polygon, welches bereits Vertecies enthält, mit einer neue Vertexliste initialisiert werden, dabei gehen die
- alten Vertecies verloren.
-
- @param VertexCount die Anzahl der Vertecies im Vertecies Array.
- @param Vertecies ein Array, das Objekte vom Typ BS_Vertex enthält, die die Vertecies des Polygons darstellen.
- @return Gibt false zurück, falls die Vertecies ein selbstüberschneidendes Polygon definiert haben.
- In diesem Fall wird das Objekt nicht initialisiert.
- */
- bool Init(int VertexCount, const BS_Vertex* Vertecies);
-
- //@{
- /** @name Sondierende Methoden */
+ * Initialises the BS_Polygon with a list of Vertecies.
+ *
+ * The Vertices need to define a polygon must not have self-intersections.
+ * If a polygon already has verticies, this will re-initialise it with the new list.
+ *
+ * @param VertexCount The number of vertices being passed
+ * @param Vertecies An array of BS_Vertex objects representing the vertices in the polygon.
+ * @return Returns false if the Vertecies have self-intersections. In this case,
+ * the object is not initialised.
+ */
+ bool Init(int VertexCount, const BS_Vertex *Vertecies);
+
+ //
+ // ** Exploratory methods **
+ //
/**
- @brief Überprüft, ob die Vertecies des Polygons im Uhrzeigersinn angeordnet sind.
- @return Gibt true zurück, wenn die Vertecies des Polygons im Uhrzeigersinn angeordnet sind oder Koplanar sind.<br>
- Gibt false zurück, wenn die Vertecies des Polygons entgegen dem Uhrzeigersinn angeordnet sind.
- @remark Diese Methode gibt nur ein sinnvolles Ergebnis zurück, wenn das Polygon mindestens 3 Vertecies hat.
- */
+ * Checks whether the Vertecies of the polygon are arranged in a clockwise direction.
+ * @return Returns true if the Vertecies of the polygon are arranged clockwise or co-planar.
+ * Returns false if the Vertecies of the polygon are arrange counter-clockwise.
+ * @remark This method only returns a meaningful result if the polygon has at least three Vertecies.
+ */
bool IsCW() const;
/**
- @brief Überprüft, ob die Vertecies des Polygons entgegen dem Uhrzeigersinn angeordnet sind.
- @return Gibt true zurück, wenn die Vertecies des Polygons entgegen dem Uhrzeigersinn angeordnet sind.<br>
- Gibt false zurück, wenn die Vertecies des Polygons im Uhrzeigersinn angeordnet sind oder Koplanar sind.
- @remark Diese Methode gibt nur ein sinnvolles Ergebnis zurück, wenn das Polygon mindestens 3 Vertecies hat.
-
- */
+ * Checks whether the Vertices of the polygon are arranged in a counter-clockwise direction.
+ * @return Returns true if the Vertecies of the polygon are arranged counter-clockwise.
+ * Returns false if the Vertecies of the polygon are arranged clockwise or co-planar.
+ * @remark This method only returns a meaningful result if the polygon has at least three Vertecies.
+ */
bool IsCCW() const;
/**
- @brief Überprüft, ob das Polygon konvex ist.
- @return Gibt true zurück, wenn das Polygon konvex ist.<br>
- Gibt false zurück, wenn das Polygon konkav ist.
- @remark Diese Methode gibt nur ein sinnvolles Ergebnis zurück, wenn das Polygon mindestens 3 Vertecies hat.
- */
+ * Checks whether the polygon is convex.
+ * @return Returns true if the polygon is convex. Returns false if the polygon is concave.
+ * @remark This method only returns a meaningful result if the polygon has at least three Vertecies.
+ */
bool IsConvex() const;
/**
- @brief Überprüft, ob das Polygon konkav ist.
- @return Gibt true zurück, wenn das Polygon konkav ist.<br>
- Gibt false zurück, wenn das Polygon konvex ist.
- @remark Diese Methode gibt nur ein sinnvolles Ergebnis zurück, wenn das Polygon mindestens 3 Vertecies hat.
- */
+ * Checks whether the polygon is concave.
+ * @return Returns true if the polygon is concave. Returns false if the polygon is convex.
+ * @remark This method only returns a meaningful result if the polygon has at least three Vertecies.
+ */
bool IsConcave() const;
/**
- @brief Überprüft, ob sich ein Punkt innerhalb des Polygons befindet.
- @param Vertex ein Vertex, mit den Koordinaten des zu testenden Punktes.
- @param BorderBelongsToPolygon gibt an, ob der Rand des Polygons als Teil des Polygons betrachtet werden soll.<br>
- Der Standardwert ist true.
- @return Gibt true zurück, wenn sich der Punkt innerhalb des Polygons befindet.<br>
- Gibt false zurück, wenn sich der Punkt außerhalb des Polygons befindet.
- */
- bool IsPointInPolygon(const BS_Vertex& Vertex, bool BorderBelongsToPolygon = true) const;
+ * Checks whether a point is inside the polygon
+ * @param Vertex A Vertex with the co-ordinates of the point to be tested.
+ * @param BorderBelongsToPolygon Specifies whether the edge of the polygon should be considered
+ * @return Returns true if the point is inside the polygon, false if it is outside.
+ */
+ bool IsPointInPolygon(const BS_Vertex &Vertex, bool BorderBelongsToPolygon = true) const;
/**
- @brief Überprüft, ob sich ein Punkt innerhalb des Polygons befindet.
- @param X die Position des Punktes auf der X-Achse.
- @param Y die Position des Punktes auf der Y-Achse.
- @param BorderBelongsToPolygon gibt an, ob der Rand des Polygons als Teil des Polygons betrachtet werden soll.<br>
- Der Standardwert ist true.
- @return Gibt true zurück, wenn sich der Punkt innerhalb des Polygons befindet.<br>
- Gibt false zurück, wenn sich der Punkt außerhalb des Polygons befindet.
- */
+ * Checks whether a point is inside the polygon
+ * @param X The X position of the point
+ * @param Y The Y position of the point
+ * @param BorderBelongsToPolygon Specifies whether the edge of the polygon should be considered
+ * @return Returns true if the point is inside the polygon, false if it is outside.
+ */
bool IsPointInPolygon(int X, int Y, bool BorderBelongsToPolygon = true) const;
/**
- @brief Gibt den Schwerpunkt des Polygons zurück.
- */
+ * Returns the focus/centroid of the polygon
+ */
BS_Vertex GetCentroid() const;
- // Rand gehört zum Polygon
- // Polygon muss CW sein
- bool IsLineInterior(const BS_Vertex & a, const BS_Vertex & b) const;
- // Rand gehört nicht zum Polygon
- // Polygon muss CW sein
- bool IsLineExterior(const BS_Vertex & a, const BS_Vertex & b) const;
-
- //@}
+ // Edge belongs to the polygon
+ // Polygon must be CW
+ bool IsLineInterior(const BS_Vertex &a, const BS_Vertex &b) const;
+ // Edge does not belong to the polygon
+ // Polygon must be CW
+ bool IsLineExterior(const BS_Vertex &a, const BS_Vertex &b) const;
- //@{
- /** @name Manipulierende Methoden */
+ //
+ // Manipulation methods
+ //
/**
- @brief Stellt sicher, dass die Vertecies des Polygons im Uhrzeigersinn angeordnet sind.
- */
+ * Ensures that the Vertecies of the polygon are arranged in a clockwise direction
+ */
void EnsureCWOrder();
/**
- @brief Stellt sicher, dass die Vertecies des Polygons entgegen dem Uhrzeigersinn angeordnet sind.
- */
+ * Ensures that the Vertecies of the polygon are arranged in a counter-clockwise direction
+ */
void EnsureCCWOrder();
/**
- @brief Kehrt die Reihenfolge der Vertecies um.
- */
+ * Reverses the Vertecies order.
+ */
void ReverseVertexOrder();
/**
- @brief Verschiebt das Polygon.
- @param Delta das Vertex um das das Polygon verschoben werden soll.
- */
- void operator+=(const BS_Vertex& Delta);
+ * Moves the polygon.
+ * @param Delta The vertex around the polygon to be moved.
+ */
+ void operator+=(const BS_Vertex &Delta);
- //@}
+ //
+ //------------------
+ //
- /// Gibt die Anzahl an Vertecies im Vertecies-Array an.
+ /// Specifies the number of Vertecies in the Vertecies array.
int VertexCount;
- /// Enthält die Vertecies des Polygons.
- BS_Vertex* Vertecies;
+ /// COntains the Vertecies of the polygon
+ BS_Vertex *Vertecies;
- virtual bool Persist(BS_OutputPersistenceBlock & Writer);
- virtual bool Unpersist(BS_InputPersistenceBlock & Reader);
+ virtual bool Persist(BS_OutputPersistenceBlock &Writer);
+ virtual bool Unpersist(BS_InputPersistenceBlock &Reader);
private:
bool m_IsCW;
@@ -208,60 +203,64 @@ private:
BS_Vertex m_Centroid;
/**
- @brief Berechnet den Schwerpunkt des Polygons.
- */
+ * Computes the centroid of the polygon.
+ */
BS_Vertex ComputeCentroid() const;
/**
- @brief Bestimmt wie die Vertecies des Polygon angeordnet sind.
- @return Gibt true zurück, wenn die Vertecies im Uhrzeigersinn angeordnet sind, ansonsten false.
- */
+ * Determines how the Vertecies of the polygon are arranged.
+ * @return Returns true if the Vertecies are arranged in a clockwise
+ * direction, otherwise false.
+ */
bool ComputeIsCW() const;
/**
- @brief Bestimmt ob das Polygon Konvex oder Konkav ist.
- @return Gibt true zurück, wenn das Polygon Konvex ist, ansonsten false.
- */
+ * Determines whether the polygon is convex or concave.
+ * @return Returns true if the polygon is convex, otherwise false.
+ */
bool ComputeIsConvex() const;
/**
- @brief Berechnet das Kreuzprodukt dreier Vertecies.
- @param V1 das erste Vertex
- @param V2 des zweite Vertex
- @param V3 das dritte Vertex
- @return Gibt das Kreuzprodukt der drei Vertecies zurück.
- @todo Diese Methode sollte an geeigneter Stelle in die BS_Vertex Klasse integriert werden.
- */
- int CrossProduct(const BS_Vertex& V1, const BS_Vertex& V2, const BS_Vertex& V3) const;
+ * Calculates the cross product of three Vertecies
+ * @param V1 The first Vertex
+ * @param V2 The second Vertex
+ * @param V3 The third Vertex
+ * @return Returns the cross-product of the three vertecies
+ * @todo This method would be better as a method of the BS_Vertex class
+ */
+ int CrossProduct(const BS_Vertex &V1, const BS_Vertex &V2, const BS_Vertex &V3) const;
/**
- @brief Berechnet des Skalarprodukt der beiden von drei Vertecies aufgespannten Vektoren.
-
- Die Vektoren werden von V2 -> V1 und V2 -> V3 aufgespannt.
-
- @param V1 das erste Vertex
- @param V2 des zweite Vertex
- @param V3 das dritte Vertex
- @return Gibt das Skalarprodukt der drei Vertecies zurück.
- @todo Diese Methode sollte an geeigneter Stelle in die BS_Vertex Klasse integriert werden.
- */
- int DotProduct(const BS_Vertex& V1, const BS_Vertex& V2, const BS_Vertex& V3) const;
+ * Computes the scalar product of two vectors spanning three vertecies
+ *
+ * The vectors are spanned by V2->V1 and V2->V3
+ *
+ * @param V1 The first Vertex
+ * @param V2 The second Vertex
+ * @param V3 The third Vertex
+ * @return Returns the dot product of the three Vertecies.
+ * @todo This method would be better as a method of the BS_Vertex class
+ */
+ int DotProduct(const BS_Vertex &V1, const BS_Vertex &V2, const BS_Vertex &V3) const;
/**
- @brief Überprüft ob das Polygon selbstüberschneidend ist.
- @return Gibt true zurück, wenn das Polygon selbstüberschneidend ist.<br>
- Gibt false zurück, wenn das Polygon nicht selbstüberschneidend ist.
- */
+ * Checks whether the polygon is self-intersecting
+ * @return Returns true if the polygon is self-intersecting.
+ * Returns false if the polygon is not self-intersecting.
+ */
bool CheckForSelfIntersection() const;
/**
- @brief Findet das Vertex des Polygons das am weitesten rechts unten liegt und gibt dessen Index im Vertex-Array zurück.
- @return Gibt den Index des Vertex zurück das am weiteesten rechts unten liegt.<br>
- Gibt -1 zurück, wenn die Vertexliste leer ist.
- */
+ * Find the vertex of the polygon that is located below the right-most point,
+ * and returns it's index in the vertex array.
+ * @return Returns the index of the vertex at the bottom-right of the polygon.
+ * Returns -1 if the vertex list is empty.
+ */
int FindLRVertexIndex() const;
- bool IsLineInCone(int StartVertexIndex, const BS_Vertex & EndVertex, bool IncludeEdges) const;
+ bool IsLineInCone(int StartVertexIndex, const BS_Vertex &EndVertex, bool IncludeEdges) const;
};
+} // End of namespace Sword25
+
#endif
diff --git a/engines/sword25/math/rect.h b/engines/sword25/math/rect.h
index a39c4de25f..849839aeec 100644
--- a/engines/sword25/math/rect.h
+++ b/engines/sword25/math/rect.h
@@ -36,278 +36,57 @@
#define SWORD25_RECT_H
// Includes
+#include "common/rect.h"
#include "sword25/kernel/common.h"
#include "sword25/math/vertex.h"
-// Klassendefinition
+namespace Sword25 {
+
+// Class definitions
+
/**
- @brief Diese Klasse beschreibt ein Rechteck und einige nützliche Operationen auf Rechtecken.
+ * Rect class. Currently this encapsultes the ScummVM Rect class. Eventually all usage of this
+ * class should be replaced with Common::Rect directly.
*/
-class BS_Rect
-{
+class BS_Rect: public Common::Rect {
public:
- /// Das linke Extrem des Rechteckes.
- int left;
- /// Das obere Extrem des Rechteckes.
- int top;
- /// Das rechte Extrem des Rechteckes + 1.
- int right;
- /// Das untere Extrem des Rechteckes + 1.
- int bottom;
+ BS_Rect() : Common::Rect() {}
+ BS_Rect(int16 w, int16 h) : Common::Rect(w, h) {}
+ BS_Rect(int16 x1, int16 y1, int16 x2, int16 y2) : Common::Rect(x1, y1, x2, y2) {}
- /**
- @brief Konstruktor, der alle Werte des Rechteckes mit 0 initialisiert.
- */
- BS_Rect()
- {
- left = 0;
- top = 0;
- right = 0;
- bottom = 0;
- }
- /**
- @brief Konstruktor, der das Rechteck mit den übergebenen Werten initialisiert.
- @param left das linke Extrem des Rechteckes
- @param top das obere Extrem des Rechteckes
- @param right das rechte Extrem des Rechteckes + 1
- @param bottom des untere Extrem des Rechteckes + 1
- */
- BS_Rect(int left_, int top_, int right_, int bottom_)
- {
- this->left = left_;
- this->top = top_;
- this->right = right_;
- this->bottom = bottom_;
- }
- /**
- @brief Verschiebt das Rechteck.
- @param DeltaX der Wert um den das Rechteck auf der X-Achse verschoben werden soll.
- @param DeltaY der Wert um den das Rechteck auf der Y-Achse verschoben werden soll.
- */
- void Move(int DeltaX, int DeltaY)
- {
- left += DeltaX;
- right += DeltaX;
- top += DeltaY;
- bottom += DeltaY;
- }
- /**
- @brief Testet ob sich zwei Rechtecke schneiden.
- @return Gibt true zurück, wenn sich die Rechtecke schneiden.
- */
- bool DoesIntersect(const BS_Rect& Rect) const
- {
- int Dist;
-
- // Intersektion auf der X-Achse
- Dist = left - Rect.left;
- if (Dist < 0)
- {
- Dist = abs(Dist);
-
- // Schneiden sich die Rechtecke nicht auf der X-Achse, so schneiden sie sich gar nicht
- if (Dist >= GetWidth())
- return false;
- }
- else
- {
- // Schneiden sich die Rechtecke nicht auf der X-Achse, so schneiden sie sich gar nicht
- if (Dist >= Rect.right - Rect.left)
- return false;
- }
-
- // Intersektion auf der Y-Achse
- Dist = top - Rect.top;
- if (Dist < 0)
- {
- Dist = abs(Dist);
-
- // Schneiden sich die Rechtecke nicht auf der Y-Achse, so schneiden sie sich gar nicht
- if (Dist >= GetHeight())
- return false;
- }
- else
- {
- // Schneiden sich die Rechtecke nicht auf der Y-Achse, so schneiden sie sich gar nicht
- if (Dist >= Rect.bottom - Rect.top)
- return false;
- }
-
- return true;
- }
+ void Move(int DeltaX, int DeltaY) { translate(DeltaX, DeltaY); }
- /**
- @brief Bildet den Durchschnitt zweier Rechtecke
- @param Rect das Rechteck, dass mit dem Objekt geschnitter werden soll.
- @param Result das Rechteck, dass das Ergebnisrechteck enthalten soll.
- @return Gibt false zurück, falls Result undefiniert ist.<br>
- Dies ist der Fall, wenn sich die Rechtecke nicht schneiden.
- */
- bool Intersect(const BS_Rect& Rect, BS_Rect& Result) const
- {
- int Dist;
-
- // Intersektion auf der X-Achse
- Dist = left - Rect.left;
- if (Dist < 0)
- {
- Dist = abs(Dist);
-
- // Schneiden sich die Rechtecke nicht auf der X-Achse, so schneiden sie sich gar nicht
- if (Dist >= GetWidth())
- {
- Result = BS_Rect(0, 0, 0, 0);
- return false;
- }
-
- // Die Abmessungen des Rect auf der X-Achse berechnen
- Result.left = Rect.left;
- }
- else
- {
- // Schneiden sich die Rechtecke nicht auf der X-Achse, so schneiden sie sich gar nicht
- if (Dist >= Rect.right - Rect.left)
- {
- Result = BS_Rect(0, 0, 0, 0);
- return false;
- }
-
- // Die Abmessungen des Rect auf der X-Achse berechnen
- Result.left = left;
- }
- Result.right = right < Rect.right ? right : Rect.right;
-
- // Intersektion auf der Y-Achse
- Dist = top - Rect.top;
- if (Dist < 0)
- {
- Dist = abs(Dist);
-
- // Schneiden sich die Rechtecke nicht auf der Y-Achse, so schneiden sie sich gar nicht
- if (Dist >= GetHeight())
- {
- Result = BS_Rect(0, 0, 0, 0);
- return false;
- }
-
- // Die Abmessungen des Rect auf der Y-Achse berechnen
- Result.top = Rect.top;
- }
- else
- {
- // Schneiden sich die Rechtecke nicht auf der Y-Achse, so schneiden sie sich gar nicht
- if (Dist >= Rect.bottom - Rect.top)
- {
- Result = BS_Rect(0, 0, 0, 0);
- return false;
- }
-
- // Die Abmessungen des Rect auf der Y-Achse berechnen
- Result.top = top;
- }
- Result.bottom = bottom < Rect.bottom ? bottom : Rect.bottom;
-
- return true;
- }
- /**
- @brief Bildet die Bounding-Box zweier Rechtecke.
- @param Rect das Rechteck, dass mit dem Objekt verbunden werden soll.
- @remark Das Ergebnis ist nicht ein Join in eigentlichen Sinne, sondern vielmehr die Bounding-Box um die Beiden
- Rechtecke.
- */
- void Join(const BS_Rect& Rect, BS_Rect& Result) const
- {
- Result.left = left < Rect.left ? left : Rect.left;
- Result.top = top < Rect.top ? top : Rect.top;
- Result.right = right > Rect.right ? right : Rect.right;
- Result.bottom = bottom > Rect.bottom ? bottom : Rect.bottom;
- return;
- }
- /**
- @brief Gibt die Breite des Rechteckes zurück.
- @return Die Breite des Rechteckes.
- */
- int GetWidth() const
- {
- return right - left;
- }
- /**
- @brief Gibt die Höhe des Rechteckes zurück.
- @return Die Höhe des Rechteckes.
- */
- int GetHeight() const
- {
- return bottom - top;
- }
- /** @brief Gibt den Flächeninhalt des Rechteckes zurück.
- @return Der Flächeninhalt des Rechteckes.
- */
- int GetArea() const
- {
- return GetWidth() * GetHeight();
- }
- /**
- @brief Vergleichsoperator zum Überprüfen der Gleichheit zweier BS_Rect Objekte.
- @return Gibt true zurück, wenn die Objekte die gleichen Werte haben, ansonsten false.
- */
- bool operator== (const BS_Rect& rhs)
- {
- return (left == rhs.left) &&
- (top == rhs.top) &&
- (right == rhs.right) &&
- (bottom == rhs.bottom);
- }
- /**
- @brief Vergleichsoperator zum Überprüfen der Ungleichheit zweier BS_Rect Objekte.
- @return Gibt true zurück, wenn die Objekte ungleiche Werte haben, ansonsten false.
- */
- bool operator!= (const BS_Rect& rhs)
- {
- return !(*this == rhs);
- }
- /**
- @brief Überprüft, ob das Objekt einen gültigen Zustand hat.
- @return Gibt false zurück, wenn das Objekt einen ungültigen Zustand hat.
- */
- bool IsValid() const
- {
- if (left < right && top < bottom) return true;
- return false;
- }
- /**
- @brief Testet, ob sich ein Vertex innerhalb des Rechteckes befindet.
- @param Vertex das Vertex, dass mit dem Rechteckes getestet werden soll
- @return Gibt true zurück, wenn sich das Vertex innerhalb des Rechteckes befindet.<br>
- Gibt false zurück, wenn sich das Vertex außerhalb des Rechteckes befindet.
- */
- bool IsPointInRect(const BS_Vertex& Vertex) const
- {
- if (Vertex.X >= left && Vertex.X < right &&
- Vertex.Y >= top && Vertex.Y < bottom)
- return true;
- return false;
- }
- /**
- @brief Testet, ob sich ein Punkt innerhalb des Rechteckes befindet.
- @param X die Position des Punktes auf der X-Achse.
- @param Y die Position des Punktes auf der Y-Achse.
- @return Gibt true zurück, wenn sich der Punkt innerhalb des Rechteckes befindet.<br>
- Gibt false zurück, wenn sich der Punkt außerhalb des Rechteckes befindet.
- */
- bool IsPointInRect(int X, int Y) const
- {
- return IsPointInRect(BS_Vertex(X, Y));
+ bool DoesIntersect(const BS_Rect &Rect) const { return intersects(Rect); }
+
+ bool Intersect(const BS_Rect &Rect, BS_Rect &Result) const {
+ Result = Rect;
+ Result.clip(*this);
}
- /**
- @brief Testet, ob ein andere Rechteck komplett in den Rechteck enthalten ist.
- @param OtherRect das zu testende Rechteck
- @brief Gibt true zurück, wenn sich das andere Rechteck komplett im Rechteck enthalten ist, ansonsten false.
- */
- bool ContainsRect(const BS_Rect & OtherRect) const
- {
- return IsPointInRect(OtherRect.left, OtherRect.top) &&
- IsPointInRect(OtherRect.right - 1, OtherRect.bottom - 1);
+
+ void Join(const BS_Rect &Rect, BS_Rect &Result) const {
+ Result = Rect;
+ Result.extend(*this);
}
+
+ int GetWidth() const { return width(); }
+
+ int GetHeight() const { return height(); }
+
+ int GetArea() const { return width() * height(); }
+
+ bool operator==(const BS_Rect &rhs) const { return equals(rhs); }
+
+ bool operator!= (const BS_Rect &rhs) const { return !equals(rhs); }
+
+ bool IsValid() const { return isValidRect(); }
+
+ bool IsPointInRect(const BS_Vertex &Vertex) const { return contains(Vertex.X, Vertex.Y); }
+
+ bool IsPointInRect(int X, int Y) const { return contains(X, Y); }
+
+ bool ContainsRect(const BS_Rect &OtherRect) const { return contains(OtherRect); }
};
+} // End of namespace Sword25
+
#endif
diff --git a/engines/sword25/math/region.cpp b/engines/sword25/math/region.cpp
index 323164435f..4999a4340e 100644
--- a/engines/sword25/math/region.cpp
+++ b/engines/sword25/math/region.cpp
@@ -41,29 +41,27 @@
#define BS_LOG_PREFIX "REGION"
-// Konstruktion/Destruktion
+namespace Sword25 {
+
+// Constructor / Destructor
// ------------------------
-BS_Region::BS_Region() : m_Valid(false), m_Type(RT_REGION)
-{
+BS_Region::BS_Region() : m_Valid(false), m_Type(RT_REGION) {
BS_RegionRegistry::GetInstance().RegisterObject(this);
}
// -----------------------------------------------------------------------------
-BS_Region::BS_Region(BS_InputPersistenceBlock & Reader, unsigned int Handle) : m_Valid(false), m_Type(RT_REGION)
-{
+BS_Region::BS_Region(BS_InputPersistenceBlock &Reader, unsigned int Handle) : m_Valid(false), m_Type(RT_REGION) {
BS_RegionRegistry::GetInstance().RegisterObject(this, Handle);
Unpersist(Reader);
}
// -----------------------------------------------------------------------------
-unsigned int BS_Region::Create(REGION_TYPE Type)
-{
+unsigned int BS_Region::Create(REGION_TYPE Type) {
BS_Region * RegionPtr;
- switch (Type)
- {
+ switch (Type) {
case RT_REGION:
RegionPtr = new BS_Region();
break;
@@ -81,24 +79,18 @@ unsigned int BS_Region::Create(REGION_TYPE Type)
// -----------------------------------------------------------------------------
-unsigned int BS_Region::Create(BS_InputPersistenceBlock & Reader, unsigned int Handle)
-{
- // Typ einlesen.
+unsigned int BS_Region::Create(BS_InputPersistenceBlock & Reader, unsigned int Handle) {
+ // Read type
unsigned int Type;
Reader.Read(Type);
- // Je nach Typ ein neues BS_Region oder BS_WalkRegion Objekt erstellen.
+ // Depending on the type, create a new BS_Region or BS_WalkRegion object
BS_Region * RegionPtr;
- if (Type == RT_REGION)
- {
+ if (Type == RT_REGION) {
RegionPtr = new BS_Region(Reader, Handle);
- }
- else if (Type == RT_WALKREGION)
- {
+ } else if (Type == RT_WALKREGION) {
RegionPtr = new BS_WalkRegion(Reader, Handle);
- }
- else
- {
+ } else {
BS_ASSERT(false);
}
@@ -107,37 +99,33 @@ unsigned int BS_Region::Create(BS_InputPersistenceBlock & Reader, unsigned int H
// -----------------------------------------------------------------------------
-BS_Region::~BS_Region()
-{
+BS_Region::~BS_Region() {
BS_RegionRegistry::GetInstance().DeregisterObject(this);
}
// -----------------------------------------------------------------------------
-bool BS_Region::Init(const BS_Polygon& Contour, const std::vector<BS_Polygon>* pHoles)
-{
- // Objektzustand zurücksetzen.
+bool BS_Region::Init(const BS_Polygon& Contour, const Common::Array<BS_Polygon> *pHoles) {
+ // Reset object state
m_Valid = false;
m_Position = BS_Vertex(0, 0);
m_Polygons.clear();
- // Genügend Platz für Kontur und Löcher im Polygon-Vektor reservieren
+ // Reserve sufficient space for countour and holes in the polygon list
if (pHoles)
m_Polygons.reserve(1 + pHoles->size());
else
m_Polygons.reserve(1);
- // Kontur an die erste Position im Polygon-Vektor kopieren
+ // The first polygon will be the contour
m_Polygons.push_back(BS_Polygon());
m_Polygons[0].Init(Contour.VertexCount, Contour.Vertecies);
- // Sicherstellen, dass die Vertecies der Contour im Uhrzeigersinn angeordnet sind.
+ // Make sure that the Vertecies in the Contour are arranged in a clockwise direction
m_Polygons[0].EnsureCWOrder();
- // Übergebene Lochpolygone an die folgenden Positionen im Polygon-Vektor kopieren
- if (pHoles)
- {
- for (unsigned int i = 0; i< pHoles->size(); ++i)
- {
+ // Place the hole polygons in the following positions
+ if (pHoles) {
+ for (unsigned int i = 0; i< pHoles->size(); ++i) {
m_Polygons.push_back(BS_Polygon());
m_Polygons[i + 1].Init((*pHoles)[i].VertexCount, (*pHoles)[i].Vertecies);
m_Polygons[i + 1].EnsureCWOrder();
@@ -145,7 +133,7 @@ bool BS_Region::Init(const BS_Polygon& Contour, const std::vector<BS_Polygon>* p
}
- // Bounding-Box initialisieren.
+ // Initialise bounding box
UpdateBoundingBox();
m_Valid = true;
@@ -154,17 +142,14 @@ bool BS_Region::Init(const BS_Polygon& Contour, const std::vector<BS_Polygon>* p
// -----------------------------------------------------------------------------
-void BS_Region::UpdateBoundingBox()
-{
- if (m_Polygons[0].VertexCount)
- {
+void BS_Region::UpdateBoundingBox() {
+ if (m_Polygons[0].VertexCount) {
int MinX = m_Polygons[0].Vertecies[0].X;
int MaxX = m_Polygons[0].Vertecies[0].X;
int MinY = m_Polygons[0].Vertecies[0].Y;
int MaxY = m_Polygons[0].Vertecies[0].Y;
- for (int i = 1; i < m_Polygons[0].VertexCount; i++)
- {
+ for (int i = 1; i < m_Polygons[0].VertexCount; i++) {
if (m_Polygons[0].Vertecies[i].X < MinX) MinX = m_Polygons[0].Vertecies[i].X;
else if (m_Polygons[0].Vertecies[i].X > MaxX) MaxX = m_Polygons[0].Vertecies[i].X;
if (m_Polygons[0].Vertecies[i].Y < MinY) MinY = m_Polygons[0].Vertecies[i].Y;
@@ -175,55 +160,47 @@ void BS_Region::UpdateBoundingBox()
}
}
-// Positionsänderungen
-// -------------------
+// Position Changes
+// ----------------
-void BS_Region::SetPos(int X, int Y)
-{
- // Unterschied zwischen alter und neuer Position berechnen.
+void BS_Region::SetPos(int X, int Y) {
+ // Calculate the difference between the old and new position
BS_Vertex Delta(X - m_Position.X, Y - m_Position.Y);
- // Neue Position im internen Zustand merken.
+ // Save the new position
m_Position = BS_Vertex(X, Y);
- // Alle Vertecies verschieben.
- for (unsigned int i = 0; i < m_Polygons.size(); ++i)
- {
+ // Move all the vertecies
+ for (unsigned int i = 0; i < m_Polygons.size(); ++i) {
m_Polygons[i] += Delta;
}
- // Bounding-Box aktualisieren
+ // Update the bounding box
UpdateBoundingBox();
}
// -----------------------------------------------------------------------------
-void BS_Region::SetPosX(int X)
-{
+void BS_Region::SetPosX(int X) {
SetPos(X, m_Position.Y);
}
// -----------------------------------------------------------------------------
-void BS_Region::SetPosY(int Y)
-{
+void BS_Region::SetPosY(int Y) {
SetPos(m_Position.X, Y);
}
-// Punkt-Region Tests
+// Point-Region Tests
// ------------------
-bool BS_Region::IsPointInRegion(int X, int Y) const
-{
- // Testen, ob der Punkt in der Bounding-Box ist.
- if (m_BoundingBox.IsPointInRect(X, Y))
- {
- // Testen, ob der Punkt in der Contour ist.
- if (m_Polygons[0].IsPointInPolygon(X, Y, true))
- {
- // Testen, ob der Punkt in einem Loch ist.
- for (unsigned int i = 1; i < m_Polygons.size(); i++)
- {
+bool BS_Region::IsPointInRegion(int X, int Y) const {
+ // Test whether the point is in the bounding box
+ if (m_BoundingBox.IsPointInRect(X, Y)) {
+ // Test whether the point is in the contour
+ if (m_Polygons[0].IsPointInPolygon(X, Y, true)) {
+ // Test whether the point is in a hole
+ for (unsigned int i = 1; i < m_Polygons.size(); i++) {
if (m_Polygons[i].IsPointInPolygon(X,Y, false))
return false;
}
@@ -237,22 +214,19 @@ bool BS_Region::IsPointInRegion(int X, int Y) const
// -----------------------------------------------------------------------------
-bool BS_Region::IsPointInRegion(const BS_Vertex& Vertex) const
-{
+bool BS_Region::IsPointInRegion(const BS_Vertex &Vertex) const {
return IsPointInRegion(Vertex.X, Vertex.Y);
}
// -----------------------------------------------------------------------------
-BS_Vertex BS_Region::FindClosestRegionPoint(const BS_Vertex& Point) const
-{
- // Feststellen, ob sich der Punkt innerhalb eines Loches befindet, falls dies der Fall ist wird der dichteste Punkt am Rand des Loches gesucht
+BS_Vertex BS_Region::FindClosestRegionPoint(const BS_Vertex &Point) const {
+ // Determine whether the point is inside a hole. If that is the case, the closest
+ // point on the edge of the hole is determined
int PolygonIdx = 0;
{
- for (unsigned int i = 1; i < m_Polygons.size(); ++i)
- {
- if (m_Polygons[i].IsPointInPolygon(Point))
- {
+ for (unsigned int i = 1; i < m_Polygons.size(); ++i) {
+ if (m_Polygons[i].IsPointInPolygon(Point)) {
PolygonIdx = i;
break;
}
@@ -263,30 +237,27 @@ BS_Vertex BS_Region::FindClosestRegionPoint(const BS_Vertex& Point) const
BS_ASSERT(Polygon.VertexCount > 1);
- // Für jede Linie des Polygons wird der Punkt berechnet, der dem übergebenen am nächsten ist.
- // Der Punkt dieser Menge mit dem gerigsten Abstand zum übergebenen Punkt ist das Ergebnis.
+ // For each line of the polygon, calculate the point that is cloest to the given point
+ // The point of this set with the smallest distance to the given point is the result.
BS_Vertex ClosestVertex = FindClosestPointOnLine(Polygon.Vertecies[0], Polygon.Vertecies[1], Point);
int ClosestVertexDistance2 = ClosestVertex.Distance(Point);
- for (int i = 1; i < Polygon.VertexCount; ++i)
- {
+ for (int i = 1; i < Polygon.VertexCount; ++i) {
int j = (i + 1) % Polygon.VertexCount;
BS_Vertex CurVertex = FindClosestPointOnLine(Polygon.Vertecies[i], Polygon.Vertecies[j], Point);
- if (CurVertex.Distance(Point) < ClosestVertexDistance2)
- {
+ if (CurVertex.Distance(Point) < ClosestVertexDistance2) {
ClosestVertex = CurVertex;
ClosestVertexDistance2 = CurVertex.Distance(Point);
}
}
- // Feststellen, ob der konstruierte Punkt wirklich von der Methode IsPointInRegion als innerhalb der Region liegend erkannt wird.
- // Dies muss nicht so sein, da aufgrund von Rundungsfehlern am Rand der Polygone Ungenauigkeiten auftreten.
+ // Determine whether the point is really within the region. This must not be so, as a result of rounding
+ // errors can occur at the edge of polygons
if (IsPointInRegion(ClosestVertex))
return ClosestVertex;
- else
- {
- // Es wird versucht einen Punkt innerhalb der Region zu konstruieren indem 8 Punkte getestet werden, die in unmittelbarer Umgebung des
- // berechneten Punktes liegen
+ else {
+ // Try to construct a point within the region - 8 points are tested in the immediate vacinity
+ // of the point
if (IsPointInRegion(ClosestVertex + BS_Vertex(-2, -2)))
return ClosestVertex + BS_Vertex(-2, -2);
else if (IsPointInRegion(ClosestVertex + BS_Vertex(0, -2)))
@@ -304,30 +275,27 @@ BS_Vertex BS_Region::FindClosestRegionPoint(const BS_Vertex& Point) const
else if (IsPointInRegion(ClosestVertex + BS_Vertex(2, 2)))
return ClosestVertex + BS_Vertex(2, 2);
- // Falls auch auf diese Weise kein Punkt gefunden werden konnte, der innerhalb der Region liegt wird das Vertex genommen, welches am
- // nächst an dem Punkt liegt.
+ // If no point could be found that way that lies within the region, find the next point
ClosestVertex = Polygon.Vertecies[0];
int ShortestVertexDistance2 = Polygon.Vertecies[0].Distance2(Point);
{
- for (int i = 1; i < Polygon.VertexCount; i++)
- {
+ for (int i = 1; i < Polygon.VertexCount; i++) {
int CurDistance2 = Polygon.Vertecies[i].Distance2(Point);
- if (CurDistance2 < ShortestVertexDistance2)
- {
+ if (CurDistance2 < ShortestVertexDistance2) {
ClosestVertex = Polygon.Vertecies[i];
ShortestVertexDistance2 = CurDistance2;
}
}
}
- BS_LOG_WARNINGLN("Clostest vertex forced because edgepoint was outside region.");
- return ClosestVertex;
+
+ BS_LOG_WARNINGLN("Clostest vertex forced because edgepoint was outside region.");
+ return ClosestVertex;
}
}
// -----------------------------------------------------------------------------
-BS_Vertex BS_Region::FindClosestPointOnLine(const BS_Vertex & LineStart, const BS_Vertex & LineEnd, const BS_Vertex Point) const
-{
+BS_Vertex BS_Region::FindClosestPointOnLine(const BS_Vertex &LineStart, const BS_Vertex &LineEnd, const BS_Vertex Point) const {
float Vector1X = static_cast<float>(Point.X - LineStart.X);
float Vector1Y = static_cast<float>(Point.Y - LineStart.Y);
float Vector2X = static_cast<float>(LineEnd.X - LineStart.X);
@@ -347,15 +315,14 @@ BS_Vertex BS_Region::FindClosestPointOnLine(const BS_Vertex & LineStart, const B
}
// -----------------------------------------------------------------------------
-// Sichtlinie
+// Line of Sight
// -----------------------------------------------------------------------------
-bool BS_Region::IsLineOfSight(const BS_Vertex & a, const BS_Vertex & b) const
-{
+bool BS_Region::IsLineOfSight(const BS_Vertex &a, const BS_Vertex &b) const {
BS_ASSERT(m_Polygons.size());
- // Die Linie muss innerhalb des Kontur-Polygons und ausserhalb aller Loch-Polygone sein
- std::vector<BS_Polygon>::const_iterator iter = m_Polygons.begin();
+ // The line must be within the contour polygon, and outside of any hole polygons
+ Common::Array<BS_Polygon>::const_iterator iter = m_Polygons.begin();
if (!(*iter).IsLineInterior(a, b)) return false;
for (iter++; iter != m_Polygons.end(); iter++)
if (!(*iter).IsLineExterior(a, b)) return false;
@@ -364,11 +331,10 @@ bool BS_Region::IsLineOfSight(const BS_Vertex & a, const BS_Vertex & b) const
}
// -----------------------------------------------------------------------------
-// Persistenz
+// Persistence
// -----------------------------------------------------------------------------
-bool BS_Region::Persist(BS_OutputPersistenceBlock & Writer)
-{
+bool BS_Region::Persist(BS_OutputPersistenceBlock &Writer) {
bool Result = true;
Writer.Write(static_cast<unsigned int>(m_Type));
@@ -377,9 +343,8 @@ bool BS_Region::Persist(BS_OutputPersistenceBlock & Writer)
Writer.Write(m_Position.Y);
Writer.Write(m_Polygons.size());
- std::vector<BS_Polygon>::iterator It = m_Polygons.begin();
- while (It != m_Polygons.end())
- {
+ Common::Array<BS_Polygon>::iterator It = m_Polygons.begin();
+ while (It != m_Polygons.end()) {
Result &= It->Persist(Writer);
++It;
}
@@ -394,8 +359,7 @@ bool BS_Region::Persist(BS_OutputPersistenceBlock & Writer)
// -----------------------------------------------------------------------------
-bool BS_Region::Unpersist(BS_InputPersistenceBlock & Reader)
-{
+bool BS_Region::Unpersist(BS_InputPersistenceBlock &Reader) {
Reader.Read(m_Valid);
Reader.Read(m_Position.X);
Reader.Read(m_Position.Y);
@@ -403,8 +367,7 @@ bool BS_Region::Unpersist(BS_InputPersistenceBlock & Reader)
m_Polygons.clear();
unsigned int PolygonCount;
Reader.Read(PolygonCount);
- for (unsigned int i = 0; i < PolygonCount; ++i)
- {
+ for (unsigned int i = 0; i < PolygonCount; ++i) {
m_Polygons.push_back(BS_Polygon(Reader));
}
@@ -418,10 +381,11 @@ bool BS_Region::Unpersist(BS_InputPersistenceBlock & Reader)
// -----------------------------------------------------------------------------
-BS_Vertex BS_Region::GetCentroid() const
-{
+BS_Vertex BS_Region::GetCentroid() const {
if (m_Polygons.size() > 0)
return m_Polygons[0].GetCentroid();
return
BS_Vertex();
}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/math/region.h b/engines/sword25/math/region.h
index 90d6613aca..577da94fac 100644
--- a/engines/sword25/math/region.h
+++ b/engines/sword25/math/region.h
@@ -35,192 +35,188 @@
#ifndef SWORD25_REGION_H
#define SWORD25_REGION_H
-#include "sword25/kernel/memlog_off.h"
-#include <vector>
-#include "sword25/kernel/memlog_on.h"
-
#include "sword25/kernel/common.h"
#include "sword25/kernel/persistable.h"
#include "sword25/math/vertex.h"
#include "sword25/math/polygon.h"
#include "sword25/math/rect.h"
+namespace Sword25 {
+
/**
- @brief Diese Klasse ist die Basisklasse aller Regionen.
-
- Mit der Methode IsValid() lässt sich abfragen, ob sich das Objekt in einem gültigen Zustand befindet.<br>
- Sollte dies nicht der Fall sein, ist die Methode Init() die einzige Methode die aufgerufen werden darf.
- Diese Klasse garantiert, dass die Vertecies der die Umriss- und die Lochpolygone im Uhrzeigersinn angeordnet sind, so dass auf den Polygonen
- arbeitende Algorithmen nur für diese Anordnung implementiert werden müssen.
-*/
-class BS_Region : public BS_Persistable
-{
+ * This class is the base class of all regions.
+ *
+ * The IsValid() method can be queried to see whether the object is in a valid state.
+ * If this is not the case, the method Init() is the only method that may be invoked.
+ * This class guarantees that the Vertecies outline of the hole, and the polygons are
+ * arranged in a clockwise direction, so that the polygon working algorithms will
+ * work properly.
+ */
+class BS_Region : public BS_Persistable {
protected:
/**
- @brief Erzeugt ein uninitialisiertes #BS_Region Objekt.
-
- Nach dem Erzeugen ist das Objekt noch ungültig (IsValid() gibt false zurück), allerdings kann das Objekt nachträglich über
- einen Aufruf von Init() in einen gültigen Zustand versetzt werden.
- */
+ * Creates a new BS_Region object
+ *
+ * After creation the object is invaild (IsValid() return false), but a call can
+ * be made later on to Init() to set up the region into a valid state.
+ */
BS_Region();
- BS_Region(BS_InputPersistenceBlock & Reader, unsigned int Handle);
+ BS_Region(BS_InputPersistenceBlock &Reader, unsigned int Handle);
public:
- enum REGION_TYPE
- {
+ enum REGION_TYPE {
RT_REGION,
RT_WALKREGION
};
static unsigned int Create(REGION_TYPE Type);
- static unsigned int Create(BS_InputPersistenceBlock & Reader, unsigned int Handle = 0);
+ static unsigned int Create(BS_InputPersistenceBlock &Reader, unsigned int Handle = 0);
virtual ~BS_Region();
/**
- @brief Initialisiert ein BS_Region Objekt.
- @param Contour ein Polygon das den Umriss der Region angibt.
- @param pHoles ein Pointer auf einen Vector von Polygonen, die Löcher in der Region angeben.<br>
- Falls die Region keine Löcher hat, muss NULL übergeben werden.<br>
- Der Standardwert ist NULL.
- @return Gibt true zurück, wenn die Initialisierung erfolgreich war.<br>
- Gibt false zurück, wenn die Intialisierung fehlgeschlagen ist.
- @remark Falls die Region bereits initialisiert war, wird der alte Zustand gelöscht.
- */
- virtual bool Init(const BS_Polygon& Contour, const std::vector<BS_Polygon>* pHoles = NULL);
-
- //@{
- /** @name Sondierende Methoden */
-
- /**
- @brief Gibt an, ob das Objekt in einem gültigen Zustand ist.
- @return Gibt true zurück, wenn sich das Objekt in einem gültigen Zustand befindet.
- Gibt false zurück, wenn sich das Objekt in einem ungültigen Zustand befindet.
- @remark Ungültige Objekte können durch einen Aufruf von Init() in einen gültigen Zustand versetzt werden.
- */
+ * Initialises a BS_Region object
+ * @param Contour A polygon indicating the outline of the region
+ * @param pHoles A pointer to an array of polygons representing the hole state in the region.
+ * If the region has no holes, it must be passed as NULL. The default value is NULL.
+ * @return Returns true if the initialisation was successful, otherwise false.
+ * @remark If the region was already initialised, the old state will be deleted.
+ */
+ virtual bool Init(const BS_Polygon &Contour, const Common::Array<BS_Polygon> *pHoles = NULL);
+
+ //
+ // Exploratory Methods
+ //
+
+ /**
+ * Specifies whether the object is in a valid state
+ * @return Returns true if the object is in a valid state, otherwise false.
+ * @remark Invalid objects can be made valid by calling Init with a valid state.
+ */
bool IsValid() const { return m_Valid; }
/**
- @brief Gibt die Position der Region zurück.
- */
- const BS_Vertex& GetPosition() const { return m_Position; }
+ * Returns the position of the region
+ */
+ const BS_Vertex &GetPosition() const { return m_Position; }
/**
- @brief Gibt die Position des Region auf der X-Achse zurück.
- */
+ * Returns the X position of the region
+ */
int GetPosX() const { return m_Position.X; }
/**
- @brief Gibt die Position des Region auf der Y-Achse zurück.
- */
+ * Returns the Y position of the region
+ */
int GetPosY() const { return m_Position.Y; }
/**
- @brief Gibt an, ob sich ein Punkt innerhalb der Region befindet.
- @param Vertex ein Vertex, mit den Koordinaten des zu testenden Punktes.
- @return Gibt true zurück, wenn sich der Punkt innerhalb der Region befindet.<br>
- Gibt false zurück, wenn sich der Punkt außerhalb der Region befindet.
- */
- bool IsPointInRegion(const BS_Vertex& Vertex) const;
+ * Indicates whether a point is inside the region
+ * @param Vertex A verex with the co-ordinates of the test point
+ * @return Returns true if the point is within the region, otherwise false.
+ */
+ bool IsPointInRegion(const BS_Vertex &Vertex) const;
/**
- @brief Gibt an, ob sich ein Punkt innerhalb der Region befindet.
- @param X die Position des Punktes auf der X-Achse.
- @param Y die Position des Punktes auf der Y-Achse.
- @return Gibt true zurück, wenn sich der Punkt innerhalb der Region befindet.<br>
- Gibt false zurück, wenn sich der Punkt außerhalb der Region befindet.
- */
+ * Indicates whether a point is inside the region
+ * @param X The X position
+ * @param Y The Y position
+ * @return Returns true if the point is within the region, otherwise false.
+ */
bool IsPointInRegion(int X, int Y) const;
/**
- @brief Gibt das Umrisspolygon der Region zurück.
- */
- const BS_Polygon& GetContour() const { return m_Polygons[0]; }
+ * Returns the countour of the region
+ */
+ const BS_Polygon &GetContour() const { return m_Polygons[0]; }
/**
- @brief Gibt die Anzahl der Lochpolygone in der Region zurück.
- */
+ * Returns the number of polygons in the hole region
+ */
int GetHoleCount() const { return static_cast<int>(m_Polygons.size() - 1); }
/**
- @brief Gibt ein bestimmtes Lochpolygon in der Region zurück.
- @param i die Nummer des zurückzugebenen Loches.<br>
- Dieser Wert muss zwischen 0 und GetHoleCount() - 1 liegen.
- @return Gibt das gewünschte Lochpolygon zurück.
- */
- inline const BS_Polygon& GetHole(unsigned int i) const;
+ * Returns a specific hole polygon in the region
+ * @param i The number of the hole to return.
+ * The index must be between 0 and GetHoleCount() - 1.
+ * @return Returns the desired hole polygon
+ */
+ inline const BS_Polygon &GetHole(unsigned int i) const;
/**
- @brief Findet für einen Punkt ausserhalb der Region den nächsten Punkt, der sich innerhalb der Region befindet.
- @param Point der Punkt, der sich ausserhalb der Region befindet
- @return Gibt den Punkt innerhalb der Region zurück, der den geringsten Abstand zum übergebenen Punkt hat.
- @remark Diese Methode arbeitet nicht immer Pixelgenau. Man sollte sich also nicht darauf verlassen, dass es wirklich keine Punkt innerhalb der
- Region gibt, der dichter am übergebenen Punkt liegt.
- */
- BS_Vertex FindClosestRegionPoint(const BS_Vertex& Point) const;
+ * For a point outside the region, finds the closest point inside the region
+ * @param Point The point that is outside the region
+ * @return Returns the point within the region which is closest
+ * @remark This method does not always work with pixel accuracy.
+ * One should not therefore rely on the fact that there is really no point in
+ * the region which is closer to the given point.
+ */
+ BS_Vertex FindClosestRegionPoint(const BS_Vertex &Point) const;
/**
- @brief Gibt den Schwerpunkt des Umrisspolygons zurück.
- */
+ * Returns the centroid for the region
+ */
BS_Vertex GetCentroid() const;
- bool IsLineOfSight(const BS_Vertex & a, const BS_Vertex & b) const;
+ bool IsLineOfSight(const BS_Vertex &a, const BS_Vertex &b) const;
- //@}
-
- //@{
- /** @name Manipulierende Methoden */
+ //
+ // Manipulation Methods
+ //
/**
- @brief Setzt die Position der Region.
- @param X die neue Position der Region auf der X-Achse.
- @param Y die neue Position der Region auf der Y-Achse.
- */
+ * Sets the position of the region
+ * @param X The new X psoition of the region
+ * @param Y The new Y psoition of the region
+ */
virtual void SetPos(int X, int Y);
/**
- @brief Setzt die Position der Region auf der X-Achse.
- @param X die neue Position der Region auf der X-Achse.
- */
+ * Sets the X position of the region
+ * @param X The new X position of the region
+ */
void SetPosX(int X);
/**
- @brief Setzt die Position der Region auf der Y-Achse.
- @param Y die neue Position der Region auf der Y-Achse.
- */
+ * Sets the Y position of the region
+ * @param Y The new Y position of the region
+ */
void SetPosY(int Y);
- //@}
+ //
+ // Manipulation Methods
+ //
- virtual bool Persist(BS_OutputPersistenceBlock & Writer);
- virtual bool Unpersist(BS_InputPersistenceBlock & Reader);
+ virtual bool Persist(BS_OutputPersistenceBlock &Writer);
+ virtual bool Unpersist(BS_InputPersistenceBlock &Reader);
protected:
- /// Diese Variable gibt den Typ des Objektes an.
+ /// This specifies the type of object
REGION_TYPE m_Type;
- /// Diese Variable gibt an, ob der aktuelle Objektzustand gültig ist.
+ /// This variable indicates whether the current object state is valid
bool m_Valid;
- /// Dieses Vertex gibt die Position der Region an.
+ /// This vertex is the position of the region
BS_Vertex m_Position;
- /// Dieser Vector enthält alle Polygone die die Region definieren. Das erste Element des Vectors ist die Kontur, alle weiteren sind die Löcher.
- std::vector<BS_Polygon> m_Polygons;
- /// Die Bounding-Box der Region.
+ /// This array contains all the polygons that define the region. The first element of
+ // the array is the contour, all others are the holes
+ Common::Array<BS_Polygon> m_Polygons;
+ /// The bounding box for the region
BS_Rect m_BoundingBox;
/**
- @brief Aktualisiert die Bounding-Box der Region.
- */
+ * Updates the bounding box of the region.
+ */
void UpdateBoundingBox();
/**
- @brief Findet den Punkt auf einer Linie, der einem anderen Punkt am nächsten ist.
- @param LineStart der Startpunkt der Linie
- @param LineEnd der Endpunkt der Linie
- @param Point der Punkt, zu dem der nächste Punkt auf der Linie konstruiert werden soll.
- @return Gibt den Punkt auf der Linie zurück, der dem übergebenen Punkt am nächsten ist.
- */
- BS_Vertex FindClosestPointOnLine(const BS_Vertex & LineStart, const BS_Vertex & LineEnd, const BS_Vertex Point) const;
+ * Find the point on a line which is closest to another point
+ * @param LineStart The start of the line
+ * @param LineEnd The end of the line
+ * @param Point The point to be compared against
+ * @return Returns the point on the line which is cloest to the passed point.
+ */
+ BS_Vertex FindClosestPointOnLine(const BS_Vertex &LineStart, const BS_Vertex &LineEnd, const BS_Vertex Point) const;
};
@@ -228,10 +224,11 @@ protected:
// Inlines
// -----------------------------------------------------------------------------
-inline const BS_Polygon& BS_Region::GetHole(unsigned int i) const
-{
+inline const BS_Polygon &BS_Region::GetHole(unsigned int i) const {
BS_ASSERT(i < m_Polygons.size() - 1);
return m_Polygons[i + 1];
}
+} // End of namespace Sword25
+
#endif
diff --git a/engines/sword25/math/regionregistry.cpp b/engines/sword25/math/regionregistry.cpp
index 3af871b1e7..1611f228ea 100644
--- a/engines/sword25/math/regionregistry.cpp
+++ b/engines/sword25/math/regionregistry.cpp
@@ -47,46 +47,44 @@
#include "sword25/math/regionregistry.h"
#include "sword25/math/region.h"
+namespace Sword25 {
+
// -----------------------------------------------------------------------------
// Implementation
// -----------------------------------------------------------------------------
-std::auto_ptr<BS_RegionRegistry> BS_RegionRegistry::m_InstancePtr;
+Common::SharedPtr<BS_RegionRegistry> BS_RegionRegistry::m_InstancePtr;
// -----------------------------------------------------------------------------
-void BS_RegionRegistry::LogErrorLn(const char * Message) const
-{
+void BS_RegionRegistry::LogErrorLn(const char *Message) const {
BS_LOG_ERRORLN(Message);
}
// -----------------------------------------------------------------------------
-void BS_RegionRegistry::LogWarningLn(const char * Message) const
-{
+void BS_RegionRegistry::LogWarningLn(const char *Message) const {
BS_LOG_WARNINGLN(Message);
}
// -----------------------------------------------------------------------------
-bool BS_RegionRegistry::Persist(BS_OutputPersistenceBlock & Writer)
-{
+bool BS_RegionRegistry::Persist(BS_OutputPersistenceBlock &Writer) {
bool Result = true;
- // Das nächste zu vergebene Handle schreiben.
+ // Write out the next handle
Writer.Write(m_NextHandle);
- // Anzahl an BS_Regions schreiben.
+ // Number of regions to write
Writer.Write(m_Handle2PtrMap.size());
- // Alle BS_Regions persistieren.
+ // Persist all the BS_Regions
HANDLE2PTR_MAP::const_iterator Iter = m_Handle2PtrMap.begin();
- while (Iter != m_Handle2PtrMap.end())
- {
- // Handle persistieren.
+ while (Iter != m_Handle2PtrMap.end()) {
+ // Handle persistence
Writer.Write(Iter->first);
- // Objekt persistieren.
+ // Persist object
Result &= Iter->second->Persist(Writer);
++Iter;
@@ -97,30 +95,30 @@ bool BS_RegionRegistry::Persist(BS_OutputPersistenceBlock & Writer)
// -----------------------------------------------------------------------------
-bool BS_RegionRegistry::Unpersist(BS_InputPersistenceBlock & Reader)
-{
+bool BS_RegionRegistry::Unpersist(BS_InputPersistenceBlock &Reader) {
bool Result = true;
- // Das nächste zu vergebene Handle wieder herstellen.
+ // Read in the next handle
Reader.Read(m_NextHandle);
- // Alle vorhandenen BS_Regions zerstören.
+ // Destroy all existing BS_Regions
while (!m_Handle2PtrMap.empty()) delete m_Handle2PtrMap.begin()->second;
- // Anzahl an BS_Regions einlesen.
+ // Read in the number of BS_Regions
unsigned int RegionCount;
Reader.Read(RegionCount);
- // Alle gespeicherten BS_Regions wieder herstellen.
- for (unsigned int i = 0; i < RegionCount; ++i)
- {
- // Handle lesen.
+ // Restore all the BS_Regions objects
+ for (unsigned int i = 0; i < RegionCount; ++i) {
+ // Handle read
unsigned int Handle;
Reader.Read(Handle);
- // BS_Region wieder herstellen.
+ // BS_Region restore
Result &= BS_Region::Create(Reader, Handle) != 0;
}
return Reader.IsGood() && Result;
}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/math/regionregistry.h b/engines/sword25/math/regionregistry.h
index f1af5dc1b7..3c4771df5f 100644
--- a/engines/sword25/math/regionregistry.h
+++ b/engines/sword25/math/regionregistry.h
@@ -39,41 +39,40 @@
// Includes
// -----------------------------------------------------------------------------
+#include "common/ptr.h"
#include "sword25/kernel/common.h"
#include "sword25/kernel/persistable.h"
#include "sword25/kernel/objectregistry.h"
-#include "sword25/kernel/memlog_off.h"
-#include <memory>
-#include "sword25/kernel/memlog_on.h"
+namespace Sword25 {
// -----------------------------------------------------------------------------
-// Forward Deklarationen
+// Forward Declarations
// -----------------------------------------------------------------------------
class BS_Region;
// -----------------------------------------------------------------------------
-// Klassendeklaration
+// Class definitions
// -----------------------------------------------------------------------------
-class BS_RegionRegistry : public BS_ObjectRegistry<BS_Region>, public BS_Persistable
-{
+class BS_RegionRegistry : public BS_ObjectRegistry<BS_Region>, public BS_Persistable {
public:
- static BS_RegionRegistry & GetInstance()
- {
- if (!m_InstancePtr.get()) m_InstancePtr.reset(new BS_RegionRegistry);
+ static BS_RegionRegistry & GetInstance() {
+ if (!m_InstancePtr.get()) m_InstancePtr = Common::SharedPtr<BS_RegionRegistry>(new BS_RegionRegistry());
return *m_InstancePtr.get();
}
- virtual bool Persist(BS_OutputPersistenceBlock & Writer);
- virtual bool Unpersist(BS_InputPersistenceBlock & Reader);
+ virtual bool Persist(BS_OutputPersistenceBlock &Writer);
+ virtual bool Unpersist(BS_InputPersistenceBlock &Reader);
private:
- virtual void LogErrorLn(const char * Message) const;
- virtual void LogWarningLn(const char * Message) const;
+ virtual void LogErrorLn(const char *Message) const;
+ virtual void LogWarningLn(const char *Message) const;
- static std::auto_ptr<BS_RegionRegistry> m_InstancePtr;
+ static Common::SharedPtr<BS_RegionRegistry> m_InstancePtr;
};
+} // End of namespace Sword25
+
#endif
diff --git a/engines/sword25/math/vertex.cpp b/engines/sword25/math/vertex.cpp
index 5dbf99402e..61d21b58d8 100644
--- a/engines/sword25/math/vertex.cpp
+++ b/engines/sword25/math/vertex.cpp
@@ -34,31 +34,36 @@
#include "sword25/math/vertex.h"
+namespace {
+
extern "C"
{
#include "sword25/util/lua/lua.h"
#include "sword25/util/lua/lauxlib.h"
}
+}
+
// -----------------------------------------------------------------------------
-BS_Vertex & BS_Vertex::LuaVertexToVertex(lua_State * L, int StackIndex, BS_Vertex & Vertex)
-{
+namespace Sword25 {
+
+BS_Vertex &BS_Vertex::LuaVertexToVertex(lua_State *L, int StackIndex, BS_Vertex &Vertex) {
#ifdef DEBUG
int __startStackDepth = lua_gettop(L);
#endif
- // Sicherstellen, dass wir wirklich eine Tabelle betrachten
+ // Ensure that we actually consider a table
luaL_checktype(L, StackIndex, LUA_TTABLE);
- // X Komponente auslesen
+ // Read X Component
lua_pushstring(L, "X");
lua_gettable(L, StackIndex);
if (!lua_isnumber(L, -1)) luaL_argcheck(L, 0, StackIndex, "the X component has to be a number");
Vertex.X = static_cast<int>(lua_tonumber(L, -1));
lua_pop(L, 1);
- // Y Komponente auslesen
+ // Read Y Component
lua_pushstring(L, "Y");
lua_gettable(L, StackIndex);
if (!lua_isnumber(L, -1)) luaL_argcheck(L, 0, StackIndex, "the Y component has to be a number");
@@ -74,18 +79,19 @@ BS_Vertex & BS_Vertex::LuaVertexToVertex(lua_State * L, int StackIndex, BS_Verte
// -----------------------------------------------------------------------------
-void BS_Vertex::VertexToLuaVertex(lua_State * L, const BS_Vertex & Vertex)
-{
- // Neue Tabelle erstellen
+void BS_Vertex::VertexToLuaVertex(lua_State * L, const BS_Vertex &Vertex) {
+ // Create New Table
lua_newtable(L);
- // X-Wert in die Tabelle schreiben
+ // X value is written to table
lua_pushstring(L, "X");
lua_pushnumber(L, Vertex.X);
lua_settable(L, -3);
- // Y-Wert in die Tabelle schreiben
+ // Y value is written to table
lua_pushstring(L, "Y");
lua_pushnumber(L, Vertex.Y);
lua_settable(L, -3);
}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/math/vertex.h b/engines/sword25/math/vertex.h
index bb7a84abb9..5b4e6da0f8 100644
--- a/engines/sword25/math/vertex.h
+++ b/engines/sword25/math/vertex.h
@@ -46,14 +46,19 @@
#include <math.h>
#include "sword25/kernel/common.h"
-// Forward-Declarations
+namespace {
+
+// Forward declarations
struct lua_State;
+}
+
+namespace Sword25 {
+
/**
- @brief Ein 2D-Vertex.
-*/
-class BS_Vertex
-{
+ * Defines a 2-D Vertex
+ */
+class BS_Vertex {
public:
BS_Vertex() : X(0), Y(0) {};
BS_Vertex(int X_, int Y_) { this->X = X_; this->Y = Y_; }
@@ -62,91 +67,87 @@ public:
int Y;
/**
- @brief Vergleicht zwei Vertecies.
- */
+ * Compares two Vertecies.
+ */
inline bool operator==(const BS_Vertex& rhs) const { if (X == rhs.X && Y == rhs.Y) return true; return false; }
/**
- @brief Vergleicht zwei Vertecies.
- */
+ * Compares two Vertecies.
+ */
inline bool operator!=(const BS_Vertex& rhs) const { if (X != rhs.X || Y != rhs.Y) return true; return false; }
/**
- @brief Addiert ein Vertex zum Vertex.
- */
+ * Adds a vertex to vertex
+ */
inline void operator+=(const BS_Vertex& Delta) { X += Delta.X; Y += Delta.Y; }
/**
- @brief Subtrahiert ein Vertex vom Vertex.
- */
+ * Subtracts a vertex from a vertex
+ */
inline void operator-=(const BS_Vertex& Delta) { X -= Delta.X; Y -= Delta.Y; }
/**
- @brief Addiert zwei Vertecies
- */
+ * Adds two vertecies
+ */
inline BS_Vertex operator+(const BS_Vertex& Delta) const { return BS_Vertex(X + Delta.X, Y + Delta.Y); }
/**
- @brief Subtrahiert zwei Vertecies
- */
+ * Subtracts two vertecies
+ */
inline BS_Vertex operator-(const BS_Vertex& Delta) const { return BS_Vertex(X - Delta.X, Y - Delta.Y); }
/**
- @brief Berechnet das Quadrat des Abstandes zweier Vertecies.
- @param Vertex das Vertex zu dem der Abstand berechnet werden soll.
- @return Gibt das Quadrat des Abstandes zwischen diesem Objekt und Vertex zurück.
- @remark Falls nur Abstände verglichen werden sollen, sollte diese Methode benutzt werden, da sie schneller ist, als Distance().
- */
- inline int Distance2(const BS_Vertex& Vertex) const
- {
+ * Calculates the square of the distance between two Vertecies.
+ * @param Vertex The vertex for which the distance is to be calculated
+ * @return Returns the square of the distance between itself and the passed vertex
+ * @remark If only distances should be compared, this method should be used because
+ * it is faster than Distance()
+ */
+ inline int Distance2(const BS_Vertex& Vertex) const {
return (X - Vertex.X) * (X - Vertex.X) + (Y - Vertex.Y) * (Y - Vertex.Y);
}
/**
- @brief Berechnet den Abstand zweier Vertecies.
- @param Vertex das Vertex zu dem der Abstand berechnet werden soll.
- @return Gibt den Abstand zwischen diesem Objekt und Vertex zurück.
- @remark Falls nur Abstände verglichen werden sollen, sollte diese Methode Distance2(), die das Quadrat des Abstandes berechnet.
- Sie ist schneller.
- */
- inline int Distance(const BS_Vertex& Vertex) const
- {
+ * Calculates the square of the distance between two Vertecies.
+ * @param Vertex The vertex for which the distance is to be calculated
+ * @return Returns the square of the distance between itself and the passed vertex
+ * @remark If only distances should be compared, Distance2() should be used, since it is faster.
+ */
+ inline int Distance(const BS_Vertex& Vertex) const {
return (int)(sqrtf(static_cast<float>(Distance2(Vertex))) + 0.5);
}
/**
- @brief Berechnet das Kreuzprodukt dieses Vertex mit einem weiteren Vertex. Hierbei werden die Vertecies als Vektoren aufgefasst.
- @param Vertex das zweite Vertex
- @return Gibt das Kreuzprodukt von diesem Vertex und dem Parameter Vertex zurück.
- */
- inline int ComputeCrossProduct(const BS_Vertex& Vertex) const
- {
+ * Calculates the cross product of the vertex with another vertex. Here the Vertecies will be
+ * interpreted as vectors.
+ * @param Vertex The second vertex
+ * @return Returns the cross product of this vertex and the passed vertex.
+ */
+ inline int ComputeCrossProduct(const BS_Vertex& Vertex) const {
return X * Vertex.Y - Vertex.X * Y;
}
/**
- @brief Berechnet das Skalarprodukt dieses Vertex mit einem weiteren Vertex. Hierbei werden die Vertecies als Vektoren aufgefasst.
- @param Vertex das zweite Vertex
- @return Gibt das Skalarprodukt von diesem Vertex und dem Parameter Vertex zurück.
- */
+ * Returns the dot product of this vertex with another vertex. Here the Vertecies are interpreted as vectors.
+ * @param Vertex The second vertex
+ * @return Returns the dot product of this vertex and the passed vertex.
+ */
inline int ComputeDotProduct(const BS_Vertex& Vertex) const
{
return X * Vertex.X + Y * Vertex.Y;
}
/**
- @brief Berechnet den Winkel zwischen diesem Vertex und einem weiteren Vertex. Hierbei werden die Vertecies als Vektoren aufgefasst.
- @param Vertex das zweite Vertex
- @return Gibt den Winkel zwischen diesem Vertex und dem Parameter Vertex im Bogenmaß zurück.
- */
- inline float ComputeAngle(const BS_Vertex& Vertex) const
- {
+ * Calculates the angle between this vertex and another vertex. Here the Vertecies are interpreted as vectors.
+ * @param Vertex The second vertex
+ * @return Returns the angle between this vertex and the passed vertex in radians.
+ */
+ inline float ComputeAngle(const BS_Vertex& Vertex) const {
return atan2f(static_cast<float>(ComputeCrossProduct(Vertex)), static_cast<float>(ComputeDotProduct(Vertex)));
}
/**
- @brief Berechnet die Länge des Vektors
- */
- inline float ComputeLength() const
- {
+ * Calculates the length of the vector
+ */
+ inline float ComputeLength() const {
return sqrtf(static_cast<float>(X * X + Y * Y));
}
@@ -154,4 +155,6 @@ public:
static void VertexToLuaVertex(lua_State * L, const BS_Vertex & Vertex);
};
+} // End of namespace Sword25
+
#endif
diff --git a/engines/sword25/math/walkregion.cpp b/engines/sword25/math/walkregion.cpp
index 58d5bc45ba..70b84da3b9 100644
--- a/engines/sword25/math/walkregion.cpp
+++ b/engines/sword25/math/walkregion.cpp
@@ -32,8 +32,7 @@
*
*/
-#include <list>
-#include <algorithm>
+#include "sword25/kernel/kernel.h"
#include "sword25/kernel/inputpersistenceblock.h"
#include "sword25/kernel/outputpersistenceblock.h"
#include "sword25/math/walkregion.h"
@@ -41,65 +40,62 @@
#define BS_LOG_PREFIX "WALKREGION"
+namespace Sword25 {
+
// -----------------------------------------------------------------------------
-// Konstanten
+// Constants
// -----------------------------------------------------------------------------
static const int infinity = INT_MAX;
// -----------------------------------------------------------------------------
-// Konstruktion / Destruktion
+// Constructor / Destructor
// -----------------------------------------------------------------------------
-BS_WalkRegion::BS_WalkRegion()
-{
+BS_WalkRegion::BS_WalkRegion() {
m_Type = RT_WALKREGION;
}
// -----------------------------------------------------------------------------
BS_WalkRegion::BS_WalkRegion(BS_InputPersistenceBlock &Reader, unsigned int Handle) :
- BS_Region(Reader, Handle)
-{
+ BS_Region(Reader, Handle) {
m_Type = RT_WALKREGION;
Unpersist(Reader);
}
// -----------------------------------------------------------------------------
-BS_WalkRegion::~BS_WalkRegion()
-{
+BS_WalkRegion::~BS_WalkRegion() {
}
// -----------------------------------------------------------------------------
-bool BS_WalkRegion::Init(const BS_Polygon & Contour, const std::vector<BS_Polygon> * pHoles)
-{
- // Standard-Initialisierungen der Region vornehmen.
+bool BS_WalkRegion::Init(const BS_Polygon &Contour, const Common::Array<BS_Polygon> *pHoles) {
+ // Default initialisation of the region
if (!BS_Region::Init(Contour, pHoles)) return false;
- // Datenstrukturen fürs Pathfinding vorbereiten
+ // Prepare structures for pathfinding
InitNodeVector();
ComputeVisibilityMatrix();
- // Erfolg signalisieren.
+ // Signal success
return true;
}
// -----------------------------------------------------------------------------
-bool BS_WalkRegion::QueryPath(BS_Vertex StartPoint, BS_Vertex EndPoint, BS_Path & Path)
-{
+bool BS_WalkRegion::QueryPath(BS_Vertex StartPoint, BS_Vertex EndPoint, BS_Path &Path) {
BS_ASSERT(Path.empty());
- // Falls Start und Ziel identisch sind, muss trivialerweise kein Pfad gefunden werden.
+ // If the start and finish are identical, no path can be found trivially
if (StartPoint == EndPoint) return true;
- // Sicherstellen, dass Start und Ziel gültig sind und neuen Start- und Zielpunkt finden, falls sie ausserhalb des Polygons liegen.
+ // Ensure that the start and finish are valid and find new start points if either
+ // are outside the polygon
if (!CheckAndPrepareStartAndEnd(StartPoint, EndPoint)) return false;
- // Wenn zwischen Start- und Endpunkt eine Sichtlinie besteht, muss kein Pathfindung durchgeführt werden und als Ergebnis wird die
- // direkte Verbindungslinie zwischen Start- und Endpunkt zurückgegeben.
+ // If between the start and point a line of sight exists, then it can be returned.
if (IsLineOfSight(StartPoint, EndPoint))
{
Path.push_back(StartPoint);
@@ -112,9 +108,8 @@ bool BS_WalkRegion::QueryPath(BS_Vertex StartPoint, BS_Vertex EndPoint, BS_Path
// -----------------------------------------------------------------------------
-struct DijkstraNode
-{
- typedef std::vector<DijkstraNode> Container;
+struct DijkstraNode {
+ typedef Common::Array<DijkstraNode> Container;
typedef Container::iterator Iter;
typedef Container::const_iterator ConstIter;
@@ -124,30 +119,27 @@ struct DijkstraNode
bool Chosen;
};
-static void InitDijkstraNodes(DijkstraNode::Container & DijkstraNodes, const BS_Region & Region, const BS_Vertex & Start, const std::vector<BS_Vertex> & Nodes)
-{
- // Ausreichend Platz im Vector reservieren
+static void InitDijkstraNodes(DijkstraNode::Container &DijkstraNodes, const BS_Region &Region,
+ const BS_Vertex &Start, const Common::Array<BS_Vertex> &Nodes) {
+ // Allocate sufficient space in the array
DijkstraNodes.resize(Nodes.size());
- // Alle Randknoten initialisieren, die vom Startknoten sichtbar sind
+ // Initialise all the nodes which are visible from the starting node
DijkstraNode::Iter DijkstraIter = DijkstraNodes.begin();
- for (std::vector<BS_Vertex>::const_iterator NodesIter = Nodes.begin(); NodesIter != Nodes.end(); NodesIter++, DijkstraIter++)
- {
+ for (Common::Array<BS_Vertex>::const_iterator NodesIter = Nodes.begin();
+ NodesIter != Nodes.end(); NodesIter++, DijkstraIter++) {
(*DijkstraIter).ParentIter = DijkstraNodes.end();
if (Region.IsLineOfSight(*NodesIter, Start)) (*DijkstraIter).Cost = (*NodesIter).Distance(Start);
}
BS_ASSERT(DijkstraIter == DijkstraNodes.end());
}
-static DijkstraNode::Iter ChooseClosestNode(DijkstraNode::Container & Nodes)
-{
+static DijkstraNode::Iter ChooseClosestNode(DijkstraNode::Container & Nodes) {
DijkstraNode::Iter ClosestNodeInter = Nodes.end();
int MinCost = infinity;
- for (DijkstraNode::Iter iter = Nodes.begin(); iter != Nodes.end(); iter++)
- {
- if (!(*iter).Chosen && (*iter).Cost < MinCost)
- {
+ for (DijkstraNode::Iter iter = Nodes.begin(); iter != Nodes.end(); iter++) {
+ if (!(*iter).Chosen && (*iter).Cost < MinCost) {
MinCost = (*iter).Cost;
ClosestNodeInter = iter;
}
@@ -156,22 +148,19 @@ static DijkstraNode::Iter ChooseClosestNode(DijkstraNode::Container & Nodes)
return ClosestNodeInter;
}
-static void RelaxNodes(DijkstraNode::Container & Nodes,
- const std::vector< std::vector<int> > & VisibilityMatrix,
- const DijkstraNode::ConstIter & CurNodeIter)
-{
- // Alle Nachfolger vom aktuellen Knoten, die noch nicht gewählt wurden, werden in die Randknotenliste eingefügt und die Kosten werden
- // aktualisiert, wenn ein kürzerer Pfad zu ihnen gefunden wurde.
+static void RelaxNodes(DijkstraNode::Container &Nodes,
+ const Common::Array< Common::Array<int> > &VisibilityMatrix,
+ const DijkstraNode::ConstIter &CurNodeIter) {
+ // All the successors of the current node that have not been chosen will be
+ // inserted into the boundary node list, and the cost will be updated if
+ // a shorter path has been found to them.
int CurNodeIndex = CurNodeIter - Nodes.begin();
- for (unsigned int i = 0; i < Nodes.size(); i++)
- {
+ for (unsigned int i = 0; i < Nodes.size(); i++) {
int Cost = VisibilityMatrix[CurNodeIndex][i];
- if (!Nodes[i].Chosen && Cost != infinity)
- {
+ if (!Nodes[i].Chosen && Cost != infinity) {
int TotalCost = (*CurNodeIter).Cost + Cost;
- if (TotalCost < Nodes[i].Cost)
- {
+ if (TotalCost < Nodes[i].Cost) {
Nodes[i].ParentIter = CurNodeIter;
Nodes[i].Cost = TotalCost;
}
@@ -179,90 +168,82 @@ static void RelaxNodes(DijkstraNode::Container & Nodes,
}
}
-static void RelaxEndPoint(const BS_Vertex & CurNodePos,
- const DijkstraNode::ConstIter & CurNodeIter,
- const BS_Vertex & EndPointPos,
- DijkstraNode & EndPoint,
- const BS_Region & Region)
-{
- if (Region.IsLineOfSight(CurNodePos, EndPointPos))
- {
+static void RelaxEndPoint(const BS_Vertex &CurNodePos,
+ const DijkstraNode::ConstIter &CurNodeIter,
+ const BS_Vertex &EndPointPos,
+ DijkstraNode &EndPoint,
+ const BS_Region &Region) {
+ if (Region.IsLineOfSight(CurNodePos, EndPointPos)) {
int TotalCost = (*CurNodeIter).Cost + CurNodePos.Distance(EndPointPos);
- if (TotalCost < EndPoint.Cost)
- {
+ if (TotalCost < EndPoint.Cost) {
EndPoint.ParentIter = CurNodeIter;
EndPoint.Cost = TotalCost;
}
}
}
-bool BS_WalkRegion::FindPath(const BS_Vertex & Start, const BS_Vertex & End, BS_Path & Path) const
-{
- // Dies ist eine Implementation des Dijkstra-Algorithmus
+bool BS_WalkRegion::FindPath(const BS_Vertex &Start, const BS_Vertex &End, BS_Path &Path) const {
+ // This is an implementation of Dijkstra's algorithm
- // Randknotenliste initialisieren
+ // Initialise edge node list
DijkstraNode::Container DijkstraNodes;
InitDijkstraNodes(DijkstraNodes, *this, Start, m_Nodes);
- // Der Endpunkt wird gesondert behandelt, da er im Sichtbarkeitsgraphen nicht vorhanden ist
+ // The end point is treated separately, since it does not exist in the visibility graph
DijkstraNode EndPoint;
- // Da in jedem Durchgang ein Knoten aus der Knotenliste gewählt wird, und danach nie wieder gewählt werden kann, ist die maximale Anzahl der
- // Schleifendurchläufe durch die Anzahl der Knoten begrenzt.
- for (unsigned int i = 0; i < m_Nodes.size(); i++)
- {
- // Bestimme nächstgelegenen Knoten in der Randknotenliste
+ // Since a node is selected each round from the node list, and can never be selected again
+ // after that, the maximum number of loop iterations is limited by the number of nodes
+ for (unsigned int i = 0; i < m_Nodes.size(); i++) {
+ // Determine the nearest edge node in the node list
DijkstraNode::Iter NodeInter = ChooseClosestNode(DijkstraNodes);
(*NodeInter).Chosen = true;
- // Falls kein freier Knoten mehr in der Randknotenliste vorhanden ist, gibt es keinen Weg vom Start- zum Endknoten.
- // Dieser Fall sollte nie auftreten, da die Anzahl der Schleifendurchgänge begrenzt ist, aber sicher ist sicher.
+ // If no free nodes are absent from the edge node list, there is no path from start
+ // to end node. This case should never occur, since the number of loop passes is
+ // limited, but etter safe than sorry
if (NodeInter == DijkstraNodes.end()) return false;
- // Wenn der Zielpunkt noch näher liegt als der nächte Punkt, ist die Suche beendet
- if (EndPoint.Cost <= (*NodeInter).Cost)
- {
- // Ergebnispfad extrahieren
-
- // Den Endpunkt in den Ergebnispfad einfügen
+ // If the destination point is closer than the point cost, scan can stop
+ if (EndPoint.Cost <= (*NodeInter).Cost) {
+ // Insert the end point in the list
Path.push_back(End);
- // Die Wegknoten in umgekehrter Reihenfolge ablaufen und in den Ergebnispfad einfügen
+ // The list is done in reverse order and inserted into the path
DijkstraNode::ConstIter CurNode = EndPoint.ParentIter;
- while (CurNode != DijkstraNodes.end())
- {
+ while (CurNode != DijkstraNodes.end()) {
BS_ASSERT((*CurNode).Chosen);
Path.push_back(m_Nodes[CurNode - DijkstraNodes.begin()]);
CurNode = (*CurNode).ParentIter;
}
- // Den Startpunkt in den Ergebnispfad einfügen
+ // The starting point is inserted into the path
Path.push_back(Start);
- // Die Knoten des Pfades müssen ungedreht werden, da sie in umgekehrter Reihenfolge extrahiert wurden.
- // Diesen Schritt könnte man sich sparen, wenn man den Pfad vom Ende zum Anfang sucht.
- std::reverse(Path.begin(), Path.end());
+ // The nodes of the path must be untwisted, as they were extracted in reverse order.
+ // This step could be saved if the path from end to the beginning was desired
+ ReverseArray<BS_Vertex>(Path);
return true;
}
- // Relaxation-Schritt für die Knoten des Graphen und für den Endknoten durchführen
+ // Relaxation step for nodes of the graph, and perform the end nodes
RelaxNodes(DijkstraNodes, m_VisibilityMatrix, NodeInter);
RelaxEndPoint(m_Nodes[NodeInter - DijkstraNodes.begin()], NodeInter, End, EndPoint, *this);
}
- // Falls die Schleife komplett durchlaufen wurde, wurden alle Knoten gewählt und es wurde trotzdem kein Pfad gefunden. Es existiert also keiner.
+ // If the loop has been completely run through, all the nodes have been chosen, and still
+ // no path was found. There is therefore no path available
return false;
}
// -----------------------------------------------------------------------------
-void BS_WalkRegion::InitNodeVector()
-{
- // Knoten-Vector leeren.
+void BS_WalkRegion::InitNodeVector() {
+ // Empty the Node list
m_Nodes.clear();
- // Anzahl der Knoten bestimmen.
+ // Determine the number of nodes
int NodeCount = 0;
{
for (unsigned int i = 0; i < m_Polygons.size(); i++)
@@ -280,26 +261,27 @@ void BS_WalkRegion::InitNodeVector()
// -----------------------------------------------------------------------------
-void BS_WalkRegion::ComputeVisibilityMatrix()
-{
- // Sichtbarkeitsmatrix initialisieren
- m_VisibilityMatrix = std::vector< std::vector <int> >(m_Nodes.size(), std::vector<int>(m_Nodes.size(), infinity));
+void BS_WalkRegion::ComputeVisibilityMatrix() {
+ // Initialise visibility matrix
+ m_VisibilityMatrix = Common::Array< Common::Array <int> >();
+ for (uint idx = 0; idx < m_Nodes.size(); ++idx) {
+ Common::Array<int> arr;
+ for (uint idx2 = 0; idx2 < m_Nodes.size(); ++idx2)
+ arr.push_back(infinity);
- // Sichtbarkeiten zwischen Vertecies berechnen und in die Sichbarkeitsmatrix eintragen.
- for (unsigned int j = 0; j < m_Nodes.size(); ++j)
- {
- for (unsigned int i = j; i < m_Nodes.size(); ++i)
- {
- if (IsLineOfSight(m_Nodes[i], m_Nodes[j]))
- {
- // Wenn eine Sichtlinie besteht wird die Entfernung der Knoten eingetragen
+ m_VisibilityMatrix.push_back(arr);
+ }
+
+ // Calculate visibility been vertecies
+ for (unsigned int j = 0; j < m_Nodes.size(); ++j) {
+ for (unsigned int i = j; i < m_Nodes.size(); ++i) {
+ if (IsLineOfSight(m_Nodes[i], m_Nodes[j])) {
+ // There is a line of sight, so save the distance between the two
int Distance = m_Nodes[i].Distance(m_Nodes[j]);
m_VisibilityMatrix[i][j] = Distance;
m_VisibilityMatrix[j][i] = Distance;
- }
- else
- {
- // Wenn keine Sichtlinie besteht wird die Entfernung "unendlich" eingetragen
+ } else {
+ // There is no line of sight, so save infinity as the distance
m_VisibilityMatrix[i][j] = infinity;
m_VisibilityMatrix[j][i] = infinity;
}
@@ -309,15 +291,12 @@ void BS_WalkRegion::ComputeVisibilityMatrix()
// -----------------------------------------------------------------------------
-bool BS_WalkRegion::CheckAndPrepareStartAndEnd(BS_Vertex & Start, BS_Vertex & End) const
-{
- if (!IsPointInRegion(Start))
- {
+bool BS_WalkRegion::CheckAndPrepareStartAndEnd(BS_Vertex &Start, BS_Vertex &End) const {
+ if (!IsPointInRegion(Start)) {
BS_Vertex NewStart = FindClosestRegionPoint(Start);
- // Sicherstellen, dass der ermittelte Punkt wirklich innerhalb der Region liegt und Notfalls abbrechen.
- if (!IsPointInRegion(NewStart))
- {
+ // Check to make sure the point is really in the region. If not, stop with an error
+ if (!IsPointInRegion(NewStart)) {
BS_LOG_ERRORLN("Constructed startpoint ((%d,%d) from (%d,%d)) is not inside the region.",
NewStart.X, NewStart.Y,
Start.X, Start.Y);
@@ -327,14 +306,13 @@ bool BS_WalkRegion::CheckAndPrepareStartAndEnd(BS_Vertex & Start, BS_Vertex & En
Start = NewStart;
}
- // Falls der Zielpunkt außerhalb der Region liegt, wird der nächste Punkt innerhalb der Region bestimmt und als Endpunkt benutzt.
- if (!IsPointInRegion(End))
- {
+ // If the destination is outside the region, a point is determined that is within the region,
+ // and that is used as an endpoint instead
+ if (!IsPointInRegion(End)) {
BS_Vertex NewEnd = FindClosestRegionPoint(End);
- // Sicherstellen, dass der ermittelte Punkt wirklich innerhalb der Region liegt und Notfalls abbrechen.
- if (!IsPointInRegion(NewEnd))
- {
+ // Make sure that the determined point is really within the region
+ if (!IsPointInRegion(NewEnd)) {
BS_LOG_ERRORLN("Constructed endpoint ((%d,%d) from (%d,%d)) is not inside the region.",
NewEnd.X, NewEnd.Y,
End.X, End.Y);
@@ -344,52 +322,47 @@ bool BS_WalkRegion::CheckAndPrepareStartAndEnd(BS_Vertex & Start, BS_Vertex & En
End = NewEnd;
}
- // Erfolg signalisieren
+ // Signal success
return true;
}
// -----------------------------------------------------------------------------
-void BS_WalkRegion::SetPos(int X, int Y)
-{
- // Unterschied zwischen alter und neuer Position berechnen.
+void BS_WalkRegion::SetPos(int X, int Y) {
+ // Calculate the difference between old and new position
BS_Vertex Delta(X - m_Position.X, Y - m_Position.Y);
- // Alle Nodes verschieben.
+ // Move all the nodes
for (unsigned int i = 0; i < m_Nodes.size(); i++) m_Nodes[i] += Delta;
- // Region verschieben
+ // Move regions
BS_Region::SetPos(X, Y);
}
// -----------------------------------------------------------------------------
-bool BS_WalkRegion::Persist(BS_OutputPersistenceBlock & Writer)
-{
+bool BS_WalkRegion::Persist(BS_OutputPersistenceBlock &Writer) {
bool Result = true;
- // Elternobjekt persistieren.
+ // Persist the parent region
Result &= BS_Region::Persist(Writer);
- // Knoten persistieren.
+ // Persist the nodes
Writer.Write(m_Nodes.size());
- std::vector<BS_Vertex>::const_iterator It = m_Nodes.begin();
- while (It != m_Nodes.end())
- {
+ Common::Array<BS_Vertex>::const_iterator It = m_Nodes.begin();
+ while (It != m_Nodes.end()) {
Writer.Write(It->X);
Writer.Write(It->Y);
++It;
}
- // Sichtbarkeitsmatrix persistieren.
+ // Persist the visibility matrix
Writer.Write(m_VisibilityMatrix.size());
- std::vector< std::vector<int> >::const_iterator RowIter = m_VisibilityMatrix.begin();
- while (RowIter != m_VisibilityMatrix.end())
- {
+ Common::Array< Common::Array<int> >::const_iterator RowIter = m_VisibilityMatrix.begin();
+ while (RowIter != m_VisibilityMatrix.end()) {
Writer.Write(RowIter->size());
- std::vector<int>::const_iterator ColIter = RowIter->begin();
- while (ColIter != RowIter->end())
- {
+ Common::Array<int>::const_iterator ColIter = RowIter->begin();
+ while (ColIter != RowIter->end()) {
Writer.Write(*ColIter);
++ColIter;
}
@@ -402,40 +375,36 @@ bool BS_WalkRegion::Persist(BS_OutputPersistenceBlock & Writer)
// -----------------------------------------------------------------------------
-bool BS_WalkRegion::Unpersist(BS_InputPersistenceBlock & Reader)
-{
+bool BS_WalkRegion::Unpersist(BS_InputPersistenceBlock &Reader) {
bool Result = true;
- // Das Elternobjekt wurde schon über den Konstruktor von BS_Region geladen, daher müssen an dieser Stelle nur noch die zusätzlichen Daten von
- // BS_WalkRegion geladen werden.
+ // The parent object was already loaded in the constructor of BS_Region, so at
+ // this point only the additional data from BS_WalkRegion needs to be loaded
- // Knoten laden.
+ // Node load
unsigned int NodeCount;
Reader.Read(NodeCount);
m_Nodes.clear();
m_Nodes.resize(NodeCount);
- std::vector<BS_Vertex>::iterator It = m_Nodes.begin();
- while (It != m_Nodes.end())
- {
+ Common::Array<BS_Vertex>::iterator It = m_Nodes.begin();
+ while (It != m_Nodes.end()) {
Reader.Read(It->X);
Reader.Read(It->Y);
++It;
}
- // Sichtbarkeitsmatrix laden.
+ // Visibility matrix load
unsigned int RowCount;
Reader.Read(RowCount);
m_VisibilityMatrix.clear();
m_VisibilityMatrix.resize(RowCount);
- std::vector< std::vector<int> >::iterator RowIter = m_VisibilityMatrix.begin();
- while (RowIter != m_VisibilityMatrix.end())
- {
+ Common::Array< Common::Array<int> >::iterator RowIter = m_VisibilityMatrix.begin();
+ while (RowIter != m_VisibilityMatrix.end()) {
unsigned int ColCount;
Reader.Read(ColCount);
RowIter->resize(ColCount);
- std::vector<int>::iterator ColIter = RowIter->begin();
- while (ColIter != RowIter->end())
- {
+ Common::Array<int>::iterator ColIter = RowIter->begin();
+ while (ColIter != RowIter->end()) {
Reader.Read(*ColIter);
++ColIter;
}
@@ -445,3 +414,5 @@ bool BS_WalkRegion::Unpersist(BS_InputPersistenceBlock & Reader)
return Result && Reader.IsGood();
}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/math/walkregion.h b/engines/sword25/math/walkregion.h
index 8c61720a12..6b06c8ed30 100644
--- a/engines/sword25/math/walkregion.h
+++ b/engines/sword25/math/walkregion.h
@@ -35,83 +35,83 @@
#ifndef SWORD25_WALKREGION_H
#define SWORD25_WALKREGION_H
-#include "sword25/kernel/memlog_off.h"
-#include <vector>
-#include "sword25/kernel/memlog_on.h"
-
+#include "common/array.h"
#include "sword25/kernel/common.h"
#include "sword25/math/region.h"
+namespace Sword25 {
+
// -----------------------------------------------------------------------------
-// Typdefinitionen
+// Type definitions
// -----------------------------------------------------------------------------
-typedef std::vector<BS_Vertex> BS_Path;
+typedef Common::Array<BS_Vertex> BS_Path;
// -----------------------------------------------------------------------------
-// Klassendefinition
+// Class definitions
// -----------------------------------------------------------------------------
/**
- @brief Diese Klasse stellt die Region dar, in der sich der Hauptcharakter bewegen kann.
-*/
-class BS_WalkRegion : public BS_Region
-{
+ * This class represents the region in which the main character can move
+ */
+class BS_WalkRegion : public BS_Region {
friend class BS_Region;
protected:
BS_WalkRegion();
- BS_WalkRegion(BS_InputPersistenceBlock & Reader, unsigned int Handle);
+ BS_WalkRegion(BS_InputPersistenceBlock &Reader, unsigned int Handle);
public:
virtual ~BS_WalkRegion();
- virtual bool Init(const BS_Polygon & Contour, const std::vector<BS_Polygon> * pHoles = 0);
+ virtual bool Init(const BS_Polygon &Contour, const Common::Array<BS_Polygon> *pHoles = 0);
/**
- @brief Ermittelt den kürzesten Weg zwischen zwei Punkten in der Region.
-
- Diese Methode verlangt, dass der Startpunkt innerhalb der Region liegt. Der Endpunkt darf außerhalb der Region liegen. In diesem
- Fall wählt die Methode als Endpunkt den Punkt innerhalb der Region, der am dichtesten am Endpunkt liegt.
-
- @param X1 X-Koordinate des Startpunktes
- @param Y1 Y-Koordinate des Startpunktes
- @param X2 X-Koordinate des Zielpunktes
- @param Y2 Y-Koordinate des Zielpunktes
- @param Path ein leerer BS_Path, der den Ergebnispfad aufnehmen soll
- @return Gibt false zurück, fall die Eingaben ungültig waren, ansonsten wird true zurückgegeben.
+ * Get the shortest path between two points in the region
+ *
+ * This method requires that the starting point lies within the region. The end point
+ * may lie outside the region. Int his case, the end is chosen as the cloest point to it
+ * that lies within the region.
+ *
+ * @param X1 X Co-ordinate of the start point
+ * @param Y1 Y Co-ordinate of the start point
+ * @param X2 X Co-ordinate of the end point
+ * @param Y2 Y Co-ordinate of the end point
+ * @param Path An empty BS_Path that will be set to the resulting path
+ * @return Returns false if the result is invalid, otherwise returns true.
*/
- bool QueryPath(int X1, int Y1, int X2, int Y2, BS_Path & Path) { return QueryPath(BS_Vertex(X1, Y1), BS_Vertex(X2, Y2), Path); }
+ bool QueryPath(int X1, int Y1, int X2, int Y2, BS_Path &Path) {
+ return QueryPath(BS_Vertex(X1, Y1), BS_Vertex(X2, Y2), Path);
+ }
/**
- @brief Ermittelt den kürzesten Weg zwischen zwei Punkten in der Region.
-
- Diese Methode verlangt, dass der Startpunkt innerhalb der Region liegt. Der Endpunkt darf außerhalb der Region liegen. In diesem
- Fall wählt die Methode als Endpunkt den Punkt innerhalb der Region, der am dichtesten am Endpunkt liegt.
-
- @param StartPoint der Startpunkt
- @param EndPoint der Endpunkt
- @param Path ein leerer BS_Path, der den Ergebnispfad aufnehmen soll
- @return Gibt false zurück, fall die Eingaben ungültig waren, ansonsten wird true zurückgegeben.
+ * Get the shortest path between two points in the region.
+ *
+ * @param StartPoint The start point
+ * @param EndPoint The end point
+ * @param Path An empty BS_Path that will be set to the resulting path
+ * @return Returns false if the result is invalid, otherwise returns true.
*/
bool QueryPath(BS_Vertex StartPoint, BS_Vertex EndPoint, BS_Path & Path);
virtual void SetPos(int X, int Y);
- const std::vector<BS_Vertex> & GetNodes() const { return m_Nodes; }
- const std::vector< std::vector<int> > & GetVisibilityMatrix() const { return m_VisibilityMatrix; }
+ const Common::Array<BS_Vertex> &GetNodes() const { return m_Nodes; }
+ const Common::Array< Common::Array<int> > &GetVisibilityMatrix() const { return m_VisibilityMatrix; }
- virtual bool Persist(BS_OutputPersistenceBlock & Writer);
- virtual bool Unpersist(BS_InputPersistenceBlock & Reader);
+ virtual bool Persist(BS_OutputPersistenceBlock &Writer);
+ virtual bool Unpersist(BS_InputPersistenceBlock &Reader);
private:
- std::vector<BS_Vertex> m_Nodes;
- std::vector< std::vector<int> > m_VisibilityMatrix;
+ Common::Array<BS_Vertex> m_Nodes;
+ Common::Array< Common::Array<int> > m_VisibilityMatrix;
void InitNodeVector();
void ComputeVisibilityMatrix();
- bool CheckAndPrepareStartAndEnd(BS_Vertex & Start, BS_Vertex & End) const;
- bool FindPath(const BS_Vertex & Start, const BS_Vertex & End, BS_Path & Path) const;
+ bool CheckAndPrepareStartAndEnd(BS_Vertex &Start, BS_Vertex &End) const;
+ bool FindPath(const BS_Vertex &Start, const BS_Vertex &End, BS_Path &Path) const;
};
+} // End of namespace Sword25
+
#endif
diff --git a/engines/sword25/script/luascript.cpp b/engines/sword25/script/luascript.cpp
index 22d2a28072..8af0128c72 100644
--- a/engines/sword25/script/luascript.cpp
+++ b/engines/sword25/script/luascript.cpp
@@ -540,7 +540,7 @@ bool BS_LuaScriptEngine::Unpersist(BS_InputPersistenceBlock &Reader) {
ClearGlobalTable(m_State, ClearExceptionsSecondPass);
// Persisted Lua data
- vector<unsigned char> chunkData;
+ Common::Array<unsigned char> chunkData;
Reader.Read(chunkData);
// Chunk-Reader initialisation. It is used with pluto_unpersist to restore read data